Следующая строка создает file_c-6.txt
но выводит 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
Если удалить >
его, он выведет список file_c-6.txt
и выведет 5
:
Я не могу понять, почему это не сохраняет значение i
в первом примере.
$ 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
вместоls
, это работает вторым способом в обоих случаях./bin/echo
сохраняет разницу, поэтому кажется, что перенаправление вывода для внешних команд происходит в подоболочке.Ответы:
Если вы запустите это в режиме strace, вы увидите, что версия, которая использует,
ls
запускает команду в подоболочке, где версия, которая использует echo, выполняет все это в существующей оболочке.Сравните вывод
против
Вы увидите в первом:
И во втором:
В этом последнем примере вы видите
clone
новый процесс (от 1258 до 1259), так что теперь мы находимся в подпроцессе. Открытие file_c-6.txt, что означает, что мы оценили$((++i))
в подоболочке, и выполнениеls
с его stdout, установленным для этого файла.Наконец, мы видим, что подпроцесс завершается, мы пожинаем дочерний процесс, затем мы продолжаем с того места, где мы остановились ... с
$i
установленным на 5, и это то, что мы повторяем снова.(Помните, что изменения переменных в подпроцессе не распространяются на родительский процесс, если вы не делаете явно что-то в родительском процессе, чтобы получить изменения дочернего процесса)
источник
i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i
.