2024-11-03 16:49:29 +01:00
|
|
|
#!/bin/bash
|
|
|
|
# Summary: Search for .desktop files with directives that match certain search strings.
|
|
|
|
# License: MIT <https://opensource.org/license/mit>
|
|
|
|
# Author: Tilman Kranz <t.kranz@tk-sls.de>
|
|
|
|
|
|
|
|
##
|
|
|
|
# Configuration
|
|
|
|
|
|
|
|
name=$(basename "$(readlink -f "$0")")
|
|
|
|
IFS=":"
|
|
|
|
xdg_data_dirs=${XDG_DATA_DIRS:-/usr/share/gnome:$HOME/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share}
|
|
|
|
search_regex=.*
|
|
|
|
help=false
|
|
|
|
verbose=false
|
|
|
|
show_directives_regex=.*
|
|
|
|
search_directives_regex="(Name|Exec)"
|
|
|
|
|
|
|
|
##
|
|
|
|
# Functions
|
|
|
|
|
|
|
|
usage() {
|
2024-11-03 19:08:55 +01:00
|
|
|
cat << 'EOF'
|
|
|
|
# XDG-DESKTOP-SEARCH(1) - Search for .desktop files
|
|
|
|
|
|
|
|
## SYNOPSIS
|
|
|
|
|
|
|
|
```
|
|
|
|
xdg-desktop-search [ OPTIONS ] SEARCH ...
|
|
|
|
```
|
|
|
|
|
|
|
|
## DESCRIPTION
|
|
|
|
|
|
|
|
xdg-desktop-search locates files with names that end in `.desktop` in
|
|
|
|
sub-directories of name "applications" of a collection of directories
|
|
|
|
refered to as "XDG data directories". It the searches the lines of such
|
|
|
|
desktop files for "directives", meaning key-value-assignments such as
|
|
|
|
`Exec=/some/program` where the assigned value matches one of the search
|
|
|
|
string given as commandline arguments SEARCH.
|
|
|
|
|
|
|
|
xdg-desktop-search prints a list of files that match the given search
|
|
|
|
criteria, it optionally prints selected directives from the file.
|
|
|
|
|
|
|
|
xdg-desktop-search returns successfully if the search rendered one or
|
|
|
|
more results and unsuccessfully otherwise.
|
|
|
|
|
|
|
|
The path of XDG directories searched can be modified by altering the
|
|
|
|
environment variable `XDG_DATA_DIRS`.
|
|
|
|
|
|
|
|
## ARGUMENTS
|
|
|
|
|
|
|
|
- `SEARCH`: Search .desktop files with search directives containing this
|
|
|
|
string. The searched directives are "Name" and "Exec" by default but can be
|
|
|
|
overridden using the `-s` option (see below).
|
|
|
|
|
|
|
|
## OPTIONS
|
|
|
|
|
|
|
|
- `-h`, `--help`: Print this message and exit.
|
|
|
|
|
|
|
|
- `-v`, `--verbose`: Print directives in found .desktop files.
|
|
|
|
|
|
|
|
- `-d STRING`, `--show-directive STRING`: Instead of printing all directives
|
|
|
|
when searching in verbose mode, print only the directive given by `STRING`
|
|
|
|
(e.g. "Name"). Option can be repeated to print multiple directives.
|
|
|
|
|
|
|
|
- `-s STRING`, `--search-directive STRING`: Instead of searching directives
|
|
|
|
"Name" and "Exec" for strings containing `SEARCH`, search the given directive
|
|
|
|
instead (e.g. "Comment"). Option can be repeated to search in multiple directives.
|
|
|
|
|
|
|
|
## RETURN VALUES
|
|
|
|
|
|
|
|
The command returns 0 if .desktop files were found that match the specified
|
|
|
|
criteria, 1 on usage error and 2 if no matching .desktop files were found.
|
|
|
|
|
|
|
|
## EXAMPLE
|
|
|
|
|
|
|
|
Search for the string "firefox" in all .desktop files found in the path
|
|
|
|
specified by `XDG_DATA_DIRS`. To match, the string "firefox" must be contained
|
|
|
|
in either the "Exec" or the "Comment" directive. List the matching files, also
|
|
|
|
show the "Exec" and "TryExec" directives in each found file.
|
|
|
|
|
|
|
|
```shell
|
|
|
|
xdg-desktop-search -s Exec -s Comment -v -d Exec -d TryExec firefox
|
|
|
|
```
|
|
|
|
|
|
|
|
## AUTHOR AND COPYRIGHT
|
|
|
|
|
|
|
|
Copyright © 2024 Tilman Kranz <t.kranz@tk-sls.de>
|
|
|
|
|
|
|
|
## LICENSE
|
|
|
|
|
|
|
|
xdg-desktop-search is distributed under the terms and conditions of the MIT
|
|
|
|
license <https://opensource.org/license/mit>.
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
this software and associated documentation files (the “Software”), to deal in
|
|
|
|
the Software without restriction, including without limitation the rights to
|
|
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
|
|
so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
2024-11-03 16:49:29 +01:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
join() {
|
|
|
|
local IFS="$1"
|
|
|
|
shift
|
|
|
|
echo "$*"
|
|
|
|
}
|
|
|
|
|
|
|
|
parse_options() {
|
|
|
|
local search=()
|
|
|
|
local search_directives=()
|
|
|
|
local show_directives=()
|
|
|
|
local argc=$#
|
|
|
|
local counter=1
|
|
|
|
|
|
|
|
while true ; do
|
|
|
|
[[ $counter -gt $argc ]] && break
|
|
|
|
argument=$1
|
|
|
|
shift
|
|
|
|
(( counter++ ))
|
|
|
|
|
|
|
|
case "$argument" in
|
|
|
|
-h|--help)
|
|
|
|
help=true
|
|
|
|
;;
|
|
|
|
-v|--verbose)
|
|
|
|
verbose=true
|
|
|
|
;;
|
|
|
|
-d|--show-directive)
|
|
|
|
[[ $counter -gt $argc ]] && {
|
|
|
|
echo "ERROR: Missing argument for option -d; aborted." >&2 ;
|
|
|
|
exit 1 ;
|
|
|
|
}
|
|
|
|
show_directives+=( "$1" )
|
|
|
|
shift
|
|
|
|
(( counter++ ))
|
|
|
|
;;
|
|
|
|
-s|--search-directive)
|
|
|
|
[[ $counter -gt $argc ]] && {
|
|
|
|
echo "ERROR: Missing argument for option -s; aborted." >&2 ;
|
|
|
|
exit 1 ;
|
|
|
|
}
|
|
|
|
search_directives+=( "$1" )
|
|
|
|
shift
|
|
|
|
(( counter++ ))
|
|
|
|
;;
|
|
|
|
|
|
|
|
*)
|
|
|
|
search+=( "$argument" )
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
[[ "${#search_directives[@]}" -gt 0 ]] && search_directives_regex="($(join "|" ${search_directives[@]}))"
|
|
|
|
[[ "${#show_directives[@]}" -gt 0 ]] && show_directives_regex="^($(join "|" ${show_directives[@]}))="
|
|
|
|
[[ "${#search[@]}" -gt 0 ]] && search_regex="^$search_directives_regex=.*($(join "|" ${search[@]}))"
|
|
|
|
}
|
|
|
|
|
|
|
|
##
|
|
|
|
# Main Program
|
|
|
|
|
|
|
|
parse_options $@
|
|
|
|
|
|
|
|
"$help" && { usage ; exit 0 ; }
|
|
|
|
|
|
|
|
found=0
|
|
|
|
|
2024-11-03 19:08:55 +01:00
|
|
|
for _data_dir in $xdg_data_dirs ; do
|
|
|
|
data_dir=$(realpath --canonicalize-missing --no-symlinks "$_data_dir")
|
2024-11-03 16:49:29 +01:00
|
|
|
applications="$data_dir/applications"
|
|
|
|
|
|
|
|
[[ -d $applications ]] && for desktop in "$applications"/*.desktop ; do
|
|
|
|
grep -Eiq "$search_regex" "$desktop" && {
|
|
|
|
(( found++ ))
|
|
|
|
if "$verbose" ; then
|
|
|
|
echo "# $desktop"
|
|
|
|
grep -Ei "$show_directives_regex" "$desktop"
|
|
|
|
else
|
|
|
|
echo "$desktop"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
if [[ $found -gt 0 ]] ; then
|
|
|
|
exit 0
|
|
|
|
else
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
# vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
|