J'ai lu que je devrais citer des variables en bash, par exemple "$ foo" au lieu de $ foo. Cependant, lors de l'écriture d'un script, j'ai trouvé un cas où cela fonctionne sans guillemets mais pas avec eux:
wget_options='--mirror --no-host-directories'
local_root="$1" # ./testdir recieved from command line
remote_root="$2" # ftp://XXX recieved from command line
relative_path="$3" # /XXX received from command line
Celui-ci fonctionne:
wget $wget_options --directory_prefix="$local_root" "$remote_root$relative_path"
Ce n'est pas le cas (notez les guillemets doubles autour de $ wget_options):
wget "$wget_options" --directory_prefix="$local_root" "$remote_root$relative_path"
Quelle est la raison pour ça?
La première ligne est-elle la bonne version; ou devrais-je soupçonner qu'il y a une erreur cachée quelque part qui provoque ce comportement?
En général, où puis-je trouver une bonne documentation pour comprendre comment bash et ses citations fonctionnent? Lors de l'écriture de ce script, j'ai l'impression d'avoir commencé à travailler sur une base d'essais et d'erreurs au lieu de comprendre les règles.
wget
ne sait pas ce que --mirror --no-host-directories
signifie (comme un argument), mais il le gère lorsqu'il est divisé en deux arguments. Très peu de programmes traitent les espaces et les guillemets spécialement une fois qu'ils sont à l'intérieur du vecteur argument. Le problème est que bash
, et d'autres obus, sont censés être>
bash
, vous pouvez donc imaginer que cela $a
équivaut exactement à écrire directement son contenu. Maintenant, le problème est évident: a="-a -b"; cmd "$a"
s'étend à cmd "-a -b"
, mais cmd
ne sait probablement pas ce que cela signifie. cmd $a
se développe pour cmd -a -b
, ce qui a probablement fait le travail.