Die folgende Zeile erzeugt file_c-6.txt
aber Ausgaben 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
Wenn man es entfernt >
, würde es auflisten file_c-6.txt
und ausgeben 5
:
Ich kann nicht verstehen, warum es i
im ersten Beispiel nicht den Wert von behält .
$ 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
stattls
, funktioniert es die zweite Möglichkeit , in beiden Fällen./bin/echo
Der Unterschied bleibt erhalten, sodass die Ausgabeumleitungen für externe Befehle scheinbar in einer Subshell erfolgen.Antworten:
Wenn Sie dies unter Strace ausführen, können Sie feststellen, dass die verwendete Version
ls
den Befehl in einer Subshell startet, in der die Version, die Echo verwendet, alles in der vorhandenen Shell ausführt.Vergleichen Sie die Ausgabe von
gegen
Sie werden in der ersten sehen:
Und im zweiten:
In diesem letzten Beispiel sehen Sie das
clone
in einem neuen Prozess (von 1258 -> 1259). Jetzt befinden wir uns in einem Unterprozess. Das Öffnen von file_c-6.txt bedeutet, dass wir ausgewertet haben$((++i))
in der Subshell haben, und das Ausführen vonls
stdout mit dieser Datei.Schließlich sehen wir, dass der Unterprozess beendet wird, wir ernten das Kind, dann fahren wir dort fort, wo wir aufgehört haben ... mit
$i
Einstellung 5, und das ist, was wir wieder ausgeben.(Denken Sie daran, dass Variablenänderungen in einem Unterprozess nicht bis zum übergeordneten Prozess durchdringen, es sei denn, Sie führen im übergeordneten Prozess eine explizite Aktion aus, um die Änderungen des untergeordneten Prozesses zu erfassen.)
quelle
i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i
.