Je n'arrive pas à trouver comment lister les différents chemins d'accès dans $PATH
séparément pour qu'ils ressemblent à ceci :
/bin
/usr/bin
/usr/local/bin
Comment cela peut-il être fait ?
Je n'arrive pas à trouver comment lister les différents chemins d'accès dans $PATH
séparément pour qu'ils ressemblent à ceci :
/bin
/usr/bin
/usr/local/bin
Comment cela peut-il être fait ?
J'utilise les "Bash Path Functions" de Stephen Collyer (cf. son article dans le Linux Journal ). Il me permet d'utiliser la "liste séparée par deux points" comme type de données dans la programmation Shell. Par exemple, je peux produire une liste de tous les répertoires du répertoire courant par :
dirs="";for i in * ; do if [ -d $i ] ; then addpath -p dirs $i; fi; done
Ensuite, listpath -p dirs
produit une liste.
Explication de la réponse de @Cyrus
echo "${PATH//:/$'\n'}"
Notes :
Cotation ANSI-C - il explique $'some \ntext '
ShellExpansion de paramètre - il explique ${paramètre/pattern/string}, Si le pattern commence par '/', toutes les correspondances du pattern sont remplacées par la string.
Donc nous avons :
Un autre moyen pour AWK est de traiter chaque répertoire comme un élément distinct record plutôt que d'en faire une champ .
awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"
Je trouve cette syntaxe particulièrement intuitive. Mais, si vous le souhaitez, vous pouvez la raccourcir en faisant de l'élément print $0
implicite (c'est l'action par défaut, et 1
évalue à true, ce qui fait qu'il est fait pour chaque ligne) :
awk 'BEGIN{RS=":"} 1' <<<"$PATH"
Le séparateur d'enregistrements d'entrée et de sortie par défaut de AWK est la nouvelle ligne (saut de ligne). En définissant le séparateur d'enregistrement d'entrée ( RS
) à :
avant de lire l'entrée, AWK analyse automatiquement un texte séparé par des deux points. $PATH
en ses noms de répertoire constitutifs. AWK développe $0
à chaque enregistrement entier, le saut de ligne reste la sortie séparateur d'enregistrement, et aucune boucle ou gsub
est nécessaire.
ek@Io:~$ echo "$PATH"
/home/ek/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"
/home/ek/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
AWK est souvent utilisé pour analyser les enregistrements dans des champs séparés, mais il n'y a pas besoin de cela juste pour construire une liste de noms de répertoires.
Cela fonctionne même pour les entrées contenant des blancs (espaces et tabulations), voire plusieurs blancs consécutifs :
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<$'ab\t\t c:de fg:h'
ab c
de fg
h
C'est-à-dire, à moins que vous ne fassiez en sorte que AWK reconstruire l'enregistrement (voir ci-dessous), il n'y a aucun problème à avoir des espaces ou des tabulations (les séparateurs de champs par défaut) dans la saisie. Votre PATH
ne contient probablement pas d'espaces sur un système Ubuntu, mais si c'est le cas, cela fonctionnera quand même.
Il convient de mentionner, en passant, que la capacité d'AWK à interpréter un enregistrement comme une collection de champs devient utile pour le problème connexe de la construction d'une table d'annuaire composants :
ek@Io:~$ awk -F/ 'BEGIN{RS=":"; OFS="\t"} {$1=$1; print $0}' <<<"$PATH"
home ek bin
usr local sbin
usr local bin
usr sbin
usr bin
sbin
bin
usr games
usr local games
snap bin
Les curieux $1=$1
sert à forcer AWK pour reconstruire le dossier .
(Ceci est probablement plus utile pour les cas où un traitement supplémentaire doit être effectué sur les composants, que pour l'exemple exact montré de la simple impression du tableau).
Comment afficher séparément les chemins dans $PATH
Ce sont les méthodes que je préfère, en fonction de mes cas d'utilisation respectifs et de mes préoccupations en matière de compatibilité et d'utilisation des ressources.
tr
Tout d'abord, si vous avez besoin d'une solution rapide, facile à retenir et lisible, il suffit d'utiliser l'écho suivant PATH
et l'envoyer à traduire ( tr
) pour transformer les deux-points en nouvelles lignes :
echo $PATH | tr : "\n"
Il a l'inconvénient d'utiliser deux processus à cause du pipe, mais si nous ne faisons que pirater dans un terminal, est-ce que cela nous intéresse vraiment ?
Si vous voulez une solution assez permanente dans votre .bashrc
pour une utilisation interactive, vous pouvez aliaser la commande suivante en path
mais la lisibilité de cette solution est discutable :
alias path="echo \"${PATH//:/$'\n'}\""
Si le motif commence par '/', toutes les correspondances du motif sont remplacées par une chaîne de caractères. Normalement, seule la première correspondance est remplacée.
La commande ci-dessus remplace les deux-points par des nouvelles lignes en utilisant la fonction de Bash ShellExpansion de paramètre :
${parameter/pattern/string}
Pour l'expliquer :
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"
# ^^ ^^^^^----string, $ required to get newline character.
# \----------pattern, / required to substitute for *every* :.
Bonne chance pour s'en souvenir quand vous faites du piratage en ligne de commande, si vous ne l'avez pas aliasé, cependant.
Alternativement, une approche assez cross-compatible, lisible et compréhensible qui ne repose sur rien d'autre que le Shell est d'utiliser la fonction suivante (je suggère dans votre .bashrc
.)
La fonction suivante fait temporairement du séparateur de champ interne (ou d'entrée) (IFS) un deux-points, et lorsqu'un tableau est donné à printf
il s'exécute jusqu'à ce que le tableau soit épuisé :
path () {
local IFS=:
printf "%s\n" ${PATH}
}
Cette méthode de création de fonctions , IFS
et printf
sont fournis par Posix, et devraient donc fonctionner dans la plupart des shells de type Posix (en particulier Dash, qu'Ubuntu alias habituellement comme sh
).
Faut-il utiliser Python pour cela ? C'est possible. Voici la commande Python la plus courte à laquelle je pense pour cela :
python -c "print('\n'.join('${PATH}'.split(':')))"
ou Python 3 seulement (et peut-être plus lisible ?) :
python3 -c "print(*'${PATH}'.split(':'), sep='\n')"
Elles devraient également fonctionner dans tout environnement Shell habituel, pour autant que vous disposiez de Python.
SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.