J'ai besoin de trouver le chemin d'un programme donné sur l' PATH
utilisation d'un script shell. Le chemin doit être le chemin complet réel du programme, qui peut être transmis plus tard à l'une des exec*
fonctions, qui ne recherche pas PATH
lui - même, par exemple execv
.
Il existe des programmes comme kill
, qui sont disponibles en tant que programme réel et un shell intégré en même temps. Si tel est le cas, j'ai besoin du chemin complet vers le programme réel.
Il existe plusieurs utilitaires qui peuvent trouver un programme sur le PATH
comme spécifié dans la Section 2.9.1.1, Recherche et exécution de commandes du standard POSIX .
Il y en a which
, qui ne fait partie d'aucune norme. Il peut s'agir d'un programme régulier sur certains systèmes, tandis que certains shells fournissent qu'il s'agit d'un programme intégré. Il semble être disponible sur la plupart des systèmes et des shells, mais les shells avec une version intégrée retournent également le nom de la fonction intégrée au lieu du chemin d'accès à l'exécutable. De plus, il n'est en aucune façon standardisé et peut renvoyer n'importe quelle sortie et prendre différentes options.
bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command
Il y whence
en a un qui est intégré à quelques obus. Mais non disponible sur de nombreux obus. Il renverra également le nom de la fonction intégrée au lieu du chemin d'accès au programme. Un -p
peut être transmis à d'où changer ce comportement.
bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill
Il y a le command
builtin spécifié par POSIX: 2008 . Malheureusement, il recherche également des commandes régulières et intégrées et renverra le nom du intégré au lieu du chemin d'accès au programme masqué par un intégré du même nom. Certains vieux obus ne l'ont pas encore implémenté.
bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill
enable
est spécifié dans POSIX ou non, mais si c'est le cas, vous pouvez utiliserenable -n which
pour désactiver le shell intégré pourwhich
.realpath
enable
est uniquement fourni parbash
etzsh
type -p
. Bash et dash vous permettent de direcommand
commande pour exécuter un exécutable réel même s'il existe une fonction ou une fonction intégrée portant le même nom.command
ignore les fonctions (et les alias) mais PAS les commandes internes, comme le Q le dit correctement. Et vous ne pouvez pas toujours utiliser un shebang car il n'y a aucun chemin qui obtient un shell donné, ou même un shell POSIX, sur tous les systèmes.Réponses:
Recherchez-le vous-même.
Testé
bash
,dash
,ksh
,mksh
,zsh
Mise à jour
Ce qui précède est bien pour un script autonome, mais si vous prévoyez d'incorporer cela dans un script plus grand, vous voudrez peut-être utiliser quelque chose de plus semblable au suivant.
Il en est ainsi que
IFS
est restaurée après avoir trouvé le match, aussi permutéexit
« s avecreturn
» sla source
IFS
variable? N'est-ce pas suffisant d'avoir cet ensemble dans le shell local? En parlant de local, serait-local IFS
il portable? Ce qui précède peut mal interagir si quelque chose d'autre enregistre IFS de la même manière. En regardant cette question sur SE , celalocal
peut fonctionner pour la plupart des shells bien qu'il ne soit pas POSIX. Mettre la version originale dans un(…)
sous-shell peut également fonctionner.