La siguiente línea crea file_c-6.txtpero genera 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 se elimina >, se enumeraría file_c-6.txty generaría 5:
No puedo entender por qué no mantiene el valor de ien el primer ejemplo.
$ 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

echolugar dels, funciona de la segunda manera en ambos casos./bin/echoconserva la diferencia, por lo que parece que las redirecciones de salida para comandos externos suceden en una subshell.Respuestas:
Si ejecuta esto bajo strace, puede ver que la versión que usa
lsinicia el comando en un subshell, donde la versión que usa echo lo ejecuta todo en el shell existente.Compare la salida de
en contra
Verás en el primero:
Y en el segundo:
En este último ejemplo, verá
cloneun nuevo proceso (desde 1258 -> 1259), por lo que ahora estamos en un subproceso. La apertura de file_c-6.txt, lo que significa que hemos evaluado$((++i))en el subshell, y la ejecuciónlscon su stdout establecido en ese archivo.Finalmente, vemos que el subproceso sale, cosechamos al niño, luego continuamos donde lo dejamos ... con el
$iconjunto a 5, y eso es lo que hacemos eco nuevamente.(Recuerde que los cambios variables en un subproceso no se filtran al proceso padre, a menos que haga algo explícitamente en el padre para tomar los cambios del niño)
fuente
i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i.