web-dev-qa-db-fra.com

Comment imprimer uniquement des variables définies (Variables Shell et / ou Environnement) dans Bash

La commande Bash intégrée set, si invoquée sans arguments, imprimera toutes les variables de la coque et de l'environnement, mais également toutes les fonctions définies. Cela rend la sortie inutilisable pour les humains et difficile à grep.

Comment puis-je faire la commande Bash intégrée set Imprimer uniquement les variables et non les fonctions?

Existe-t-il d'autres commandes qui impriment uniquement les variables de la coque, sans les fonctions?

Remarque: Bash se différencie entre les variables de coque et les variables d'environnement. Voir ici différence entre les variables d'environnement et les variables d'environnement exportées dans Bash

59
lesmana

"Y a-t-il d'autres commandes qui impriment uniquement les variables de la coque, sans les fonctions?"

Dans l'homme bash, dans la section Section des commandes intégrées (dans la section Définir), il est indiqué: "En mode POSIX, seules les variables de la coque sont répertoriées."

(set -o posix; set)

remarque: () Syntaxe apparaît un sous-vase, si vous n'aimez pas le forking, utilisez simplement la version plus verbeuse

set -o posix; set; set +o posix
54
temp

Je ne sais pas comment on peut faire set Imprimer uniquement des variables. Cependant, en examinant la sortie de set, j'ai pu proposer ce qui suit qui semble attraper juste des variables:

$ set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" 

Fondamentalement, je recherche des lignes qui commencent par des lettres, des chiffres ou une ponctuation suivies d'un "=". De la sortie que j'ai vue, cela attrape toutes les variables; Cependant, je doute que cela soit très portable.

Si, comme votre titre le suggère, vous souhaitez soustraire de cette liste les variables exportées et obtiennent ainsi une liste de variables non exportées, alors vous pourriez faire quelque chose comme ça.

$ set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars && env | sort | comm -23 ./setvars - 

Pour casser un peu ça, voici ce qu'il fait:

  1. set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars: J'espère que toutes les variables (comme indiqué précédemment), les trie et colle le résultat dans un fichier.
  2. && env | sort: Une fois la commande précédente terminée, nous allons appeler env et trier sa sortie.
  3. | comm -23 ./setvars -: Enfin, nous tuyons la sortie triée de env dans comm et utilisez l'option -23 pour imprimer les lignes propres au premier argument, dans ce cas, les lignes propres à notre sortie de ensemble.

Lorsque vous avez terminé, vous voudrez peut-être nettoyer le fichier temporaire qu'il a créé avec la commande rm ./setvars

7
Steven D

Utilisez simplement la commande env. Il n'imprime pas les fonctions.

6
unxnut

Essayez la commande printenv:

$printenv
2
Emilio R.

En Bash, cela n'imprimera que des noms de variables:

compgen -v

Ou, si des valeurs sont nécessaires aussi, utilisez:

declare -p
1
Isaac

La réponse acceptée est géniale. Je propose une alternative qui ne consiste pas à définir le mode POSIX:

Voici la technique que j'utilise pour stocker l'état de fonction dans un fichier afin que je puisse le poursuivre ultérieurement. Le premier produit un décharge d'état et la seconde ne produit qu'une liste des noms de variables.

set 2>/dev/null | while read a; do [[ $a == *=* ]] || break; echo $a; done 

set 2>/dev/null | while read a; do [[ $a == *=* ]] || break; echo ${a/=*}; done 

Les deux travaillent par des lignes de dumping jusqu'à ce qu'il en trouve un sans "=", ce qui se produit lorsque la première fonction est répertoriée. Ce dernier récolte l'affectation.

0
Wil

diffusion contre une coquille propre pour vous assurer que les varès varient des scripts RC sont laissés de côté

## get mostly local vars
diff_env(){
    diff <(bash -cl 'set -o posix && set') \
        <(set -o posix && set && set +o posix) | \
        grep -E "^>|^\+" | \
        grep -Ev "^(>|\+|\+\+) ?(BASH|COLUMNS|LINES|HIST|PPID|SHLVL|PS(1|2)|Shell|FUNC)" | \
        sed -r 's/^> ?|^\+ ?//'
}

la version avec comm serait trop compliqué

0
untore