A seguinte linha cria file_c-6.txt
mas gera 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
Se alguém remover >
, listará file_c-6.txt
e produzirá 5
:
Não consigo entender por que não mantém o valor i
no primeiro exemplo.
$ 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
vez dels
, funciona da segunda maneira nos dois casos./bin/echo
preserva a diferença; portanto, parece que os redirecionamentos de saída para comandos externos ocorrem em um subshell.Respostas:
Se você executar isso no strace, poderá ver que a versão que usa
ls
inicia o comando em uma subshell, onde a versão que usa eco executa tudo no shell existente.Compare a saída de
contra
Você verá no primeiro:
E no segundo:
Neste último exemplo, você vê
clone
um novo processo (de 1258 a 1259), então agora estamos em um subprocesso. A abertura do arquivo_c-6.txt, o que significa que avaliamos$((++i))
no subshell e a execuçãols
com o seu stdout definido para esse arquivo.Finalmente, vemos que o subprocesso sai, colhemos a criança e continuamos com o ponto em que paramos ... com o
$i
conjunto de 5, e é isso que ecoamos novamente.(Lembre-se de que as alterações variáveis em um subprocesso não são abrangidas pelo processo pai, a menos que você faça algo explicitamente no pai para obter as alterações do filho)
fonte
i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i
.