La bonne façon
Vous devriez vraiment utiliser gtk-launch
s'il est disponible. Cela fait généralement partie du paquet libgtk-3-bin (cela peut varier en fonction de la distribution).
gtk-launch
est utilisé comme suit:
gtk-launch APPLICATION [URI...]
gtk-launch app-name.desktop
gtk-launch app-name
Veuillez noter que gtk-launch
requiert l'installation du fichier .desktop (c'est-à-dire situé dans /usr/share/applications
ou ~/.local/share/applications
).
Donc, pour contourner ce problème, nous pouvons utiliser une petite fonction hacheuse Bash qui installe temporairement le fichier .desktop souhaité avant de le lancer. La méthode "correcte" pour installer un fichier .desktop est via desktop-file-install
mais je vais l'ignorer.
launch(){
# Usage: launch PATH [URI...]
# NOTE: The bulk of this function is executed in a subshell, i.e. '(..)'
# This isn't strictly necessary, but it keeps everything
# out of the global namespace and lessens the likelihood
# of side effects.
(
# where you want to install the launcher to
appdir=$HOME/.local/share/applications
# the template used to install the launcher
template=launcher-XXXXXX.desktop
# ensure $1 has a .desktop extension, exists, is a normal file, is readable, has nonzero size
# optionally use desktop-file-validate for stricter checking
# desktop-file-validate "$1" 2>/dev/null || {
[[ $1 = *.desktop && -f $1 && -r $1 && -s $1 ]] || {
echo "ERROR: you have not supplied valid .desktop file" >&2
return 1
}
# ensure the temporary launcher is deleted upon exit
trap 'rm "$launcherfile" &>/dev/null' EXIT
# create a temp file to overwrite later
launcherfile=$(mktemp -p "$appdir" "$template")
launchername=${launcherfile##*/}
# overwrite temp file with the launcher file
if cp "$1" "$launcherfile" &>/dev/null; then
gtk-launch "$launchername" "${@:2}"
else
echo "ERROR: failed to copy launcher to applications directory" >&2
return 1
fi
)
}
Vous pouvez l'utiliser comme ça (et transmettre si vous le souhaitez des arguments supplémentaires ou des URI):
launch PATH [URI...]
launch ./path/to/shortcut.desktop
L'alternative manuelle
Si vous souhaitez analyser et exécuter manuellement un fichier .desktop , vous pouvez le faire avec la commande awk
suivante:
awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop
Si vous souhaitez traiter la commande awk
comme un script tout-en-un; nous pouvons même afficher un message d'erreur et quitter avec un code de retour de 1 dans le cas où une commande Exec n'est pas trouvée:
awk 'BEGIN {command=""} /^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); command=$0; exit} END {if (command!="") {exit system(command)} else {if (FILENAME == "-") {printf "ERROR: Failed to identify Exec line\n" > "/dev/stderr"} else {printf "ERROR: Failed to identify Exec line in 7%s7\n", FILENAME > "/dev/stderr"} close("/dev/stderr"); exit 1}}'
Les commandes susmentionnées vont:
- Recherchez la ligne commençant par Exec =
- Supprimer Exec =
- Supprimez toutes les variables Exec (par exemple,
%f
, %u
, %U
). Il est possible de remplacer ceux-ci par des arguments de position comme le prévoit la spécification, mais cela compliquerait considérablement le problème. Consultez la dernière spécification d'entrée de bureau .
- Exécuter la commande
- Quittez immédiatement avec le code de sortie approprié (pour ne pas exécuter plusieurs lignes Exec )
Remarque: ce script AWK traite quelques cas marginaux qui peuvent ou non être traités correctement par certaines des autres réponses. Plus précisément, cette commande supprime plusieurs variables Exec (en prenant soin de ne pas supprimer le symbole%), n'exécutera qu'une seule commande de ligne Exec et se comportera comme prévu, même si la commande de ligne Exec contient un ou plusieurs signes d’égal (par exemple, script.py --profile=name
).
Juste quelques autres réserves ... Selon la spécification, TryExec est:
Path to an executable file on disk used to determine if the program is actually installed. If the path is not an absolute path, the file is looked up in the $PATH environment variable. If the file is not present or if it is not executable, the entry may be ignored (not be used in menus, for example).
Dans cet esprit, il n’a aucun sens d’exécuter sa valeur.
Path et Terminal sont quelques autres problèmes. Chemin comprend le répertoire de travail dans lequel le programme est exécuté. Terminal est un booléen indiquant si le programme est exécuté dans une fenêtre de terminal. Tout cela peut être résolu, mais il est inutile de réinventer la roue car il existe déjà des implémentations de la spécification. Si vous souhaitez implémenter Path , gardez à l'esprit que system()
génère un sous-processus. Par conséquent, vous ne pouvez pas modifier le répertoire de travail en effectuant une opération telle que system("cd 7" working_directory "7"); system(command)
. Cependant, vous pourriez probablement faire quelque chose comme system("cd 7" working_directory "7 && " command)
. Note \ 047 sont des guillemets simples (pour que la commande ne soit pas interrompue sur les chemins contenant des espaces).
L'alternative Python
Je vole une page de Carlo, ici , qui a suggéré de créer un script Python pour utiliser le gi . Voici un moyen minimal d’exécuter le même code à partir du shell sans avoir à créer un fichier et à vous soucier des entrées / sorties.
launch(){
# Usage: launch PATH [URI...]
python - "[email protected]" <<EOF
import sys
from gi.repository import Gio
Gio.DesktopAppInfo.new_from_filename(sys.argv[1]).launch_uris(sys.argv[2:])
EOF
}
Exécutez ensuite la fonction de lancement comme suit:
launch ./path/to/shortcut.desktop
Notez que l'utilisation des URI est facultative. De plus, aucune vérification d’erreur n’est effectuée, vous devez donc vous assurer que le programme de lancement existe et qu'il est lisible (avant de l’utiliser) si vous voulez que votre script soit durable.