Je suis assez nouveau dans les scripts Bash. J'ai un "script de test", que j'ai utilisé comme base pour un script plus avancé / utile:
#!/bin/bash
files=$1
for a in $files
do
echo "$a"
done
Lorsque j'appelle cela sans guillemets, il prend simplement un fichier dans un répertoire:
testscript *.txt
Mais quand je l'appelle avec des guillemets, cela fonctionne correctement et sélectionne tous les fichiers texte:
testscript '*.txt'
Qu'est-ce qui se passe ici?
bash
shell-script
gornvix
la source
la source
for a in "$@"; do
(oufor a; do
) dans votre script, laissant ainsi le globbing au shell externe, et non de laisser de côté les guillemets.Réponses:
Lorsque vous appelez un programme
alors votre shell fait l'expansion et calcule toutes les valeurs. Il est donc possible d'appeler efficacement votre programme
Maintenant, votre programme ne regarde que
$1
et ne fonctionne donc que surfile1.txt
.En citant sur la ligne de commande, vous passez la chaîne littérale
*.txt
au script, et c'est ce qui est stocké dans$1
. Votrefor
boucle l'agrandit ensuite.Normalement, vous utiliseriez
"$@"
et non$1
dans des scripts comme celui-ci.Il s'agit d'un "piège" pour les personnes provenant de scripts CMD, où le shell de commande ne fait pas de globalisation (comme on le sait) et passe toujours la chaîne littérale.
la source
"$@"
(par opposition à$@
ou$1
$2
$3
) provoquera chaque nom de fichier à rappeler"file1.txt"
"file2.txt"
etc. Pourfile1.txt
cela n'a pas de sens, mais si vous avezmy file.txt
, la citation est essentiel pour empêcher le shell analyse pour le transformer en deux noms de fichiers, un nommémy
et un nomméfile.txt
. Citez toujours l'entrée utilisateur et l'expansion globale de peur que vous ne soyez très mécontent un jour.Sans guillemets, le shell se développe
*.txt
avant d'appeler le script, tout$1
comme le premier fichier qui est développé. Tous lestxt
fichiers sont des arguments pour votre script à ce stade (en supposant qu'il n'y en a pas trop).Avec des guillemets, cette chaîne est passée sans être développée dans le script, ce qui permet ensuite de
for
faire l'expansion, comme vous l'espérez.la source