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 ?
Puisque tous les langages de script ont déjà été utilisés, je vais choisir le C. Il est assez facile d'obtenir des variables d'environnement avec get_env()
(voir Documentation sur la bibliothèque C de GNU ). Le reste n'est que manipulation de caractères
bash-4.3$ cat get_path.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *path = getenv("PATH");
int length = strlen(path) -1;
for(int i=0;i<=length;i++){
if (path[i] == ':')
path[i] = '\n';
printf("%c",path[i]);
}
printf("\n");
return 0;
}
bash-4.3$ gcc get_path.c
bash-4.3$ ./a.out
/home/xieerqi/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/opt/microchip/xc16/v1.25/bin
/opt/microchip/xc32/v1.40/bin
/opt/microchip/xc8/v1.35/bin
/home/xieerqi/bin
/home/xieerqi/bin/sh
Mais aussi parce que "pourquoi pas", voici une version alternative en Python via les arguments de la ligne de commande. sys.argv
python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"
Ruby n'est pas livré par défaut avec Ubuntu, contrairement au compilateur C et à l'interpréteur Python, mais si vous vous retrouvez un jour à l'utiliser, la solution en Ruby serait la suivante :
ruby -ne 'puts $_.split(":")' <<< "$PATH"
Comme l'a suggéré 7stud (Merci beaucoup !) dans le cadre de l'enquête sur l'utilisation de l'Internet. commentaires ce qui peut aussi être raccourci avec
ruby -F: -ane 'puts $F' <<<$PATH
ruby -0072 -ne 'puts chomp' <<<$PATH
Nous pouvons utiliser split()
pour décomposer la ligne lue en tableau, et utiliser la fonction for-each
boucle pour imprimer chaque élément sur une ligne séparée.
awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH
Voici l'équivalent en Go :
$ cat path.go
package main
import (
"fmt"
"os"
"strings"
)
func main() {
for _, p := range strings.Split(os.Getenv("PATH"), ":") {
fmt.Println(p)
}
}
$ go run path.go
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/nathan/.local/bin
/home/nathan/go/bin
Voici quelques autres approches. J'utilise un PATH
avec des répertoires contenant des barres obliques inverses, des espaces et même une nouvelle ligne pour montrer qu'ils devraient fonctionner avec n'importe quoi (à l'exception de la commande cut
un qui échoue sur les nouvelles lignes) :
$ echo "$PATH"
/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
Quelques méthodes Perl :
$ perl -pe 's/:/\n/g' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
El -p
signifie "imprimer chaque ligne d'entrée après avoir appliqué le script donné par -e
". Le script utilise l'opérateur de substitution ( s/oldnew/
) pour remplacer tous les :
avec des nouvelles lignes.
$ perl -lne 'print for split /:/' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
El -l
ajoute une nouvelle ligne à chaque print
appel. Ici, le script divise son entrée sur :
puis boucle sur chaque élément fractionné et l'imprime.
$ perl -F: -ane '$"="\n";print "@F"' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
El -a
fait perl
se comporter comme awk
: il divisera chacune de ses lignes d'entrée sur le caractère donné par -F
(donc :
ici) et sauvegarder le résultat dans le tableau @F
. Le site $"
est une variable Perl spéciale, le "séparateur de liste", dont la valeur est imprimée entre chaque élément d'une liste imprimée. Ainsi, en lui attribuant la valeur d'un saut de ligne, on obtient print @list
imprimer chaque élément de @list
et ensuite une nouvelle ligne. Ici, nous l'utilisons pour imprimer @F
.
$ perl -F: -ane 'print join "\n", @F' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
Même idée que ci-dessus, mais avec moins de golf. Au lieu d'utiliser $"
nous sommes explicitement join
en ajoutant des retours à la ligne dans le tableau, puis en imprimant.
Simple grep
avec la magie du PCRE :
$ grep -oP '(^|:)\K[^:]+' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
El -o
fait grep
n'imprime que la partie correspondante de chaque ligne, de sorte que chaque correspondance est imprimée sur une ligne distincte. Le site -P
permet d'utiliser des expressions régulières compatibles avec Perl (PCRE). La regex recherche des tronçons de caractères non :
( [^:]+
) qui suivent soit le début de la ligne ( ^
) ou un :
caractère. Le site \K
est une astuce de la PCRE qui signifie "écarter tout ce qui correspond à ce point" et qui est utilisée ici pour éviter d'imprimer l'indicateur :
également.
Et un cut
(celle-ci échoue sur les nouvelles lignes, mais peut traiter les barres obliques inversées et les espaces) :
$ cut -d: -f 1- --output-delimiter=$'\n' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
Les options utilisées sont -d:
qui définit le délimiteur d'entrée à :
, -f 1-
ce qui signifie imprimer tous les champs (du 1er à la fin) et --output-delimiter=$'\n'
qui définit le, eh bien, le délimiteur de sortie. Le site $'\n'
es Cotation ANSI C et est un moyen d'imprimer un caractère de nouvelle ligne dans le Shell.
Dans tous les exemples ci-dessus, j'utilise la fonction de bash (et d'autres shells) ici la chaîne ( <<<
) pour transmettre une chaîne de caractères en entrée d'un programme. Ainsi, command <<<"foo"
est équivalent à echo -n "foo" | command
. Notez que je cite toujours "$PATH"
Sans les guillemets, le Shell aurait mangé le caractère de nouvelle ligne.
@7stud a donné une autre approche dans les commentaires c'est juste trop bon pour ne pas l'inclure :
$ perl -0x3a -l012 -pe '' <<<"$PATH"
C'est ce que l'on appelle le golf . Le site -0
spécifie le séparateur d'enregistrement d'entrée sous la forme d'un nombre octal ou hexadécimal. C'est ce qui définit une "ligne" et sa valeur par défaut est \n
un caractère de nouvelle ligne. Ici, nous le définissons comme un :
qui est x3a
en hexagone (essayez printf '\x3a\n'
). Le site -l
fait trois choses. Premièrement, il supprime le séparateur d'enregistrement d'entrée ( $/
) à la fin de chaque ligne, ce qui a pour effet de supprimer l'élément :
et deuxièmement, il définit le séparateur d'enregistrement de sortie ( $\
) à la valeur octale ou hexagonale qui lui est donnée ( 012
es \n
). Si $\
est définie, elle est ajoutée à la fin de chaque fichier print
ce qui entraînera l'ajout d'un saut de ligne à chaque appel print
.
El -pe
sera p rint chaque ligne d'entrée après avoir appliqué le script donné par -e
. Ici, il n'y a pas de script car tout le travail est fait par les drapeaux d'option comme décrit ci-dessus !
Nous avons besoin de plus de Java !
public class GetPathByLine {
public static void main(String[] args) {
for (String p : System.getenv("PATH").split(":")) {
System.out.println(p);
}
}
}
Sauvegardez ceci sur GetPathByLine.java
et compiler en utilisant :
javac GetPathByLine.java
Fonctionne avec :
java GetPathByLine
[17:06:55][kazwolfe@BlackHawk]
> ~ $ cat GetPathByLine.java
public class GetPathByLine {
public static void main(String[] args) {
for (String p : System.getenv("PATH").split(":")) {
System.out.println(p);
}
}
}
[17:06:58][kazwolfe@BlackHawk]
> ~ $ javac GetPathByLine.java
[17:07:02][kazwolfe@BlackHawk]
> ~ $ java GetPathByLine
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
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.