Le droit chemin
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
le fichier .desktop doit être installé (c'est-à-dire situé dans /usr/share/applications
ou ~/.local/share/applications
).
Donc, pour contourner ce problème, nous pouvons utiliser une petite fonction haletante de 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 également transmettre des arguments supplémentaires ou des URI si vous le souhaitez):
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 awk
commande suivante :
awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop
Si vous souhaitez traiter la awk
commande 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 est introuvable:
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 \047%s\047\n", FILENAME > "/dev/stderr"} close("/dev/stderr"); exit 1}}'
Les commandes susmentionnées vont:
- Trouver la ligne commençant par Exec =
- Supprimer Exec =
- Retirez 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. Voir la dernière spécification du poste de travail .
- Exécuter la commande
- Quitter immédiatement avec le code de sortie approprié (afin de ne pas exécuter plusieurs lignes Exec )
Notez que ce script AWK aborde quelques cas marginaux qui peuvent ou ne peuvent pas ê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 égal (par exemple script.py --profile=name
).
Juste quelques autres avertissements ... Selon la spécification, TryExec est:
Chemin d'accès à un fichier exécutable sur le disque utilisé pour déterminer si le programme est réellement installé. Si le chemin n'est pas un chemin absolu, le fichier est recherché dans la variable d'environnement $ PATH. Si le fichier n'est pas présent ou s'il n'est pas exécutable, l'entrée peut être ignorée (ne pas être utilisée dans les menus, par exemple).
Dans cet esprit, il n’a aucun sens d’exécuter sa valeur.
Path et Terminal sont quelques autres problèmes . Path est constitué du répertoire de travail dans lequel exécuter le programme. Terminal est un booléen indiquant si le programme est exécuté dans une fenêtre de terminal. Tous ces problèmes peuvent être résolus, 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, vous ne pouvez donc pas modifier le répertoire de travail en procédant de la manière suivante system("cd \047" working_directory "\047"); system(command)
. Cependant, vous pourriez probablement faire quelque chose comme system("cd \047" working_directory "\047 && " 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 module 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 E / S.
launch(){
# Usage: launch PATH [URI...]
python - "$@" <<EOF
import sys
from gi.repository import Gio
Gio.DesktopAppInfo.new_from_filename(sys.argv[1]).launch_uris(sys.argv[2:])
EOF
}
Puis exécutez la fonction lanceur comme suit:
launch ./path/to/shortcut.desktop
Notez que l'utilisation des URI est facultative. En outre, 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 souhaitez que votre script soit durable.
exec
échec est parce qu'exec remplace votre processus en cours d'exécution par le processus que vous spécifiez. Vous avez donc essayé de remplacer votre shell par l'exécution du poste de travail sous forme de fichier binaire compilé. La raison pour laquelle vous ne pouviez pas le fairesudo exec
est qu'il s'agit d'un shell intégré et non d'une commande binaire.