La ligne suivante crée file_c-6.txt
mais affiche 5
:
$ i=5; ls file_a-${i}.txt file_b-${i}.txt > file_c-$(( ++i )).txt; echo $i
5
$ cat file_c-6.txt
file_a-5.txt
file_b-5.txt
Si l' on supprime >
elle la liste file_c-6.txt
et de sortie 5
:
Je ne comprends pas pourquoi il ne garde pas la valeur de i
dans le premier exemple.
$ i=5; ls file_a-${i}.txt file_b-${i}.txt file_c-$(( ++i )).txt; echo $i
file_a-5.txt file_b-5.txt file_c-6.txt
6
echo
place dels
, cela fonctionne de la deuxième façon dans les deux cas./bin/echo
préserve la différence, il semble donc que les redirections de sortie pour les commandes externes se produisent dans un sous-shell.Réponses:
Si vous l'exécutez sous strace, vous pouvez voir que la version qui utilise
ls
démarre la commande dans un sous-shell, où la version qui utilise echo exécute tout dans le shell existant.Comparez la sortie de
contre
Vous verrez dans le premier:
Et dans le second:
Dans ce dernier exemple, vous voyez le
clone
dans un nouveau processus (de 1258 -> 1259), donc maintenant nous sommes dans un sous-processus. L'ouverture de file_c-6.txt, ce qui signifie que nous avons évalué$((++i))
dans le sous-shell, et l'exécution dels
avec sa sortie standard définie sur ce fichier.Enfin, nous voyons que le sous-processus se termine, nous récoltons l'enfant, puis nous continuons là où nous nous sommes arrêtés ... avec un
$i
ensemble de 5, et c'est ce que nous répétons.(N'oubliez pas que les modifications de variables dans un sous-processus ne se répercutent pas sur le processus parent, sauf si vous faites quelque chose explicitement dans le parent pour récupérer les modifications de l'enfant)
la source
i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i
.