set
Si elle est appelée sans arguments, la commande intégrée bash imprimera toutes les variables d'environnement et d'environnement, mais également toutes les fonctions définies. Cela rend la sortie inutilisable pour les humains et difficile à grep
.
Comment puis-je faire en sorte que la commande intégrée bash n'imprime set
que les variables et non les fonctions?
Existe-t-il d'autres commandes n'imprimant que les variables du shell, sans les fonctions?
Remarque: bash distingue les variables shell et les variables d'environnement. voir ici Différence entre les variables d'environnement et les variables d'environnement exportées dans bash
la source
_
, et qui sont faciles à éliminer:(set -o posix ; set | grep -v ^_)
set -o posix; set | sed -e '/^_/,$d'; set +o posix;
(set -o posix; set)
. Sans les crochets, le comportement du shell Bash actuel serait modifié pour correspondre au standard Posix. (Je ne sais pas ce que cela signifie, mais ça a l'air important.) Avec les crochets, le Bash reste inchangé.POSIXLY_CORRECT=y
et ajouteposix
à$SHELLOPTS
Voici quelques solutions de contournement:
panne:
declare
imprime chaque variable définie (exportée ou non) et chaque fonction.declare -f
imprime seulement les fonctions.comm -3
supprimera toutes les lignes communes aux deux. En effet, cela supprimera les fonctions, ne laissant que les variables.Pour n’imprimer que les variables non exportées:
Une autre solution de contournement:
Cela n’imprimera que les variables, mais avec quelques attributs laids.
Vous pouvez couper les attributs en utilisant ... cut:
Un inconvénient est que la valeur de IFS est interprétée au lieu d'être affichée.
comparer:
Cela rend très difficile l'utilisation de cette sortie pour un traitement ultérieur, à cause de cette seule
"
ligne. Peut-être que quelques IFS-fu peuvent être faits pour empêcher cela.Encore une autre solution de contournement, en utilisant
compgen
:La bash intégrée a
compgen
été conçue pour être utilisée dans les scripts de complétion. À cette fin,compgen -v
répertorie toutes les variables définies. L'inconvénient: il ne répertorie que les noms de variables, pas les valeurs.Voici un hack pour lister également les valeurs.
L'avantage: c'est une solution pure bash. L'inconvénient: certaines valeurs sont brouillées à cause de l'interprétation
printf
. De plus, le sous-shell du tuyau et / ou de la boucle ajoute des variables supplémentaires.la source
declare ...| cut
conduite est-elle rompue s'il n'y a pas d'attribut pour une variable? Je suppose que cela--
est utilisé dans ce cas, mais je suis toujours mal à l'aise.sed
pourrait être plus sûr, c'est-àdeclare -p | sed 's/^.* \([^ ]\+\)$/\1/'
compgen
:)Le mode
typeset
intégré a étrangement une option pour afficher uniquement les fonctions (-f
) mais pas uniquement pour afficher les paramètres. Heureusement,typeset
(ouset
) affiche tous les paramètres avant que toutes les fonctions, les noms de fonctions et de paramètres ne puissent pas contenir de nouvelle ligne ou de signe égal, et les nouvelles lignes dans les valeurs de paramètre sont indiquées (elles apparaissent sous la forme\n
). Vous pouvez donc vous arrêter à la première ligne sans signe égal:Cela n’imprime que les noms de paramètres; si vous voulez les valeurs, changez
print $1
enprint $0
.Notez que ceci affiche tous les noms de paramètres (les paramètres et les variables sont utilisés ici de manière synonyme), pas uniquement les variables d'environnement («variable d'environnement» est synonyme de «paramètres exportés»).
Notez également que cela suppose qu'il n'y a pas de variable d'environnement dont le nom ne correspond pas aux contraintes de bash sur les noms de paramètres. De telles variables ne peuvent pas être créées dans bash, mais peuvent avoir été héritées de l'environnement au démarrage de bash:
la source
set | sed '/=/!Q'
Je ne sais pas comment on peut
set
imprimer uniquement des variables. Cependant, en examinant le résultat deset
, j’ai été en mesure de proposer les éléments suivants qui semblent ne saisir que des variables:En gros, je cherche des lignes qui commencent par des lettres, des chiffres ou des signes de ponctuation suivis d'un "=". D'après la sortie que j'ai vue, cela saisit toutes les variables. Cependant, je doute que cela soit très portable.
Si, comme le suggère votre titre, vous souhaitez soustraire de cette liste les variables exportées et obtenir ainsi une liste de variables non exportées, vous pouvez procéder de la sorte.
Pour décomposer un peu, voici ce qu'il fait:
set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars
: Cela espère obtenir toutes les variables (comme discuté précédemment), les trier et coller le résultat dans un fichier.&& env | sort
: Une fois la commande précédente terminée, nous allons appelerenv
et trier sa sortie.| comm -23 ./setvars -
: Enfin, nous canalisons la sortie triée deenv
danscomm
et utilisons l'-23
option pour imprimer les lignes qui sont uniques au premier argument, dans ce cas les lignes uniques à notre sortie de set.Lorsque vous avez terminé, vous voudrez peut-être nettoyer le fichier temporaire qu’il a créé avec la commande
rm ./setvars
la source
f () {|cat <<EOF|foo=bar|EOF|}
où|
représente un saut de ligne).Il suffit d'utiliser la commande
env
. Il n'imprime pas les fonctions.la source
Essayez la commande printenv:
la source
En bash, cela n'imprimera que les noms de variables:
Ou, si des valeurs sont également nécessaires, utilisez:
la source
diffing contre un shell propre pour assurer également vars de scripts rc sont laissés de côté
la version avec
comm
serait trop compliquéela source
La réponse acceptée est géniale. Je propose une alternative qui n'implique pas la définition du mode POSIX:
Voici la technique que j'ai utilisée pour stocker l'état de la fonction dans un fichier afin de pouvoir le continuer plus tard. Le premier produit un vidage d'état et le second ne produit qu'une liste des noms de variables.
Les deux fonctionnent en vidant les lignes jusqu'à ce qu'il en trouve une sans caractère '=', ce qui se produit lorsque la première fonction est listée. Ce dernier coupe la tâche.
la source