L'utilitaire qui
trouvera un programme sur le chemin mais qu'en est-il d'un fichier de données arbitraire?
Je dois chercher le mauvais truc mais je peux ' Je ne trouve aucun moyen de le faire avec un utilitaire standard alors j'ai pensé à écrire un petit script Bash pour le faire.
La variable d'environnement $ PATH
est séparée par des deux-points, mais en essayant définir IFS = ':'
puis parcourir les résultats ne fonctionne pas pour moi. Voici ce que j'ai jusqu'à présent:
IFS=':' DIRS=($PATH) for d in $DIRS; do echo $d; done
À ce stade, il ne renvoie que la première entrée de mon chemin plutôt que toutes.
Réflexions ? S'il existe déjà une commande standard qui fait cela, il n'y a aucune raison d'écrire un script ...
4 Réponses :
En utilisant ceci, en utilisant les extensions de paramètres bash et find
:
find ${PATH//:/\/ } -name 'file'
Supposons qu'il y ait un répertoire dans le PATH qui contient un espace. Ou un fichier dans un répertoire dans le PATH avec un espace dans le nom de fichier.
Vous ne développez pas non plus les fichiers dans la dernière entrée PATH.
Cette solution serait géniale si je pouvais utiliser find
d'une manière qui recherche le $ PATH
mais le remplacement des deux-points par des espaces ne fonctionnera pas
@GillesQuenot J'ai voté pour votre solution find
parce que je l'aime mais cela ne fonctionnera pas quand il y a des espaces dans les répertoires qui sont dans $ PATH
Je n'utilise jamais d'espaces spécialement pour un répertoire PATH, et j'aime aussi ma solution ^^
Pour trouver un fichier nommé $ name
sur votre PATH
en utilisant une boucle bash:
oldIFS=$IFS IFS=: for d in $PATH do [ -f "$d/$name" ] && echo "Found $d/$name" done IFS=$oldIFS
Sur de nombreux systèmes, tels que debian , qui
est juste un script shell et utilise une boucle très similaire. Jetez un œil à less / usr / bin / which
.
Quelques choses se passent ici:
IFS = ':' DIRS = ($ PATH)
bash développera la variable avant de définir IFS et DIRS, il est donc trop tard d'ici là. Vous aurez besoin de quelque chose de fou comme
for d in "${dirs[@]}" ...
- non, c'était faux. Tout d'abord, la variable $ PATH est développée, puis IFS est défini, puis l'élément DIRS est divisé en utilisant IFS car il n'est pas entre guillemets.
pour d dans $ DIRS; faire echo $ d; terminé
Pour parcourir tous les éléments d'un tableau, vous devez
dirs=() while IFS= read -r -d: dir || [ "$dir" ]; do dirs+=("$dir"); done <<<"$PATH"
Avec un tableau, $ DIRS
est égal à $ {DIRS [0]}
, c'est-à-dire la première entrée.
N'utilisez pas de noms de variables ALLCAPS. Il est trop facile d'écraser une variable système cruciale.
Citez vos variables à moins que vous ne sachiez exactement ce qui se passera si vous ne le faites pas.
L'erreur n'est pas avec l'affectation, mais avec le fait de ne pas boucler sur le tableau.
find "${dirs[@]}" -name "$desired_file_name"
fonctionne pour moi; ou plus succinctement
desired_file_name=$1 # or whatever for dir in "${dirs[@]}"; do test -e "$dir/$desired_file_name" || continue echo "$0: found $dir/$desired_file_name" >&2 done
Comme vous l'avez découvert, $ dirs
ne renvoie que le premier élément du tableau.
En fait parcourir ces répertoires à la recherche d'un fichier particulier, peut-être essayer
printf '%s\n' "${dirs[@]}"
Une autre approche est
IFS=: dirs=($PATH) for dir in "${dirs[@]}"; do echo "$dir" done
(vous devriez préférer les minuscules pour vos variables privées, j'ai donc changé DIRS
en dirs
. Moins de cris est bon aussi pour les yeux.)
Huh, je suppose que je n'ai pas testé ce que j'ai écrit.
Les fichiers de données arbitraires ne devraient probablement pas être dans les listes de répertoires dans
PATH
.