Ah, pero sponge
no es la única opción; no tiene que obtener moreutils
para que esto funcione correctamente. Cualquier mecanismo funcionará siempre que satisfaga los siguientes dos requisitos:
- Acepta el nombre del archivo de salida como parámetro.
- Solo crea el archivo de salida una vez que se ha procesado toda la entrada.
Verá, el problema bien conocido al que se refiere el OP es que el shell creará todos los archivos que son necesarios para que las tuberías funcionen incluso antes de comenzar a ejecutar los comandos en la tubería, por lo que es el shell el que realmente se trunca el archivo de salida (que desafortunadamente también es el archivo de entrada) antes de que cualquiera de los comandos haya tenido la oportunidad de comenzar a ejecutarse.
El tee
comando no funciona, aunque cumple con el primer requisito, porque no cumple con el segundo requisito: siempre creará el archivo de salida inmediatamente después del inicio, por lo que es esencialmente tan malo como crear una tubería directamente en el archivo de salida. (En realidad, es peor, porque su uso introduce un retraso aleatorio no determinista antes de que el archivo de salida se trunca, por lo que podría pensar que funciona, mientras que de hecho no lo hace).
Entonces, todo lo que necesitamos para resolver este problema es algún comando que almacenará todas sus entradas antes de producir cualquier salida, y que sea capaz de aceptar el nombre de archivo de salida como un parámetro, de modo que no tengamos que canalizar su salida a El archivo de salida. Uno de esos comandos es shuf
. Entonces, lo siguiente logrará lo mismo que sponge
hace:
shuf --output=file --random-source=/dev/zero
La --random-source=/dev/zero
parte engaña shuf
para hacer lo suyo sin hacer ningún movimiento aleatorio, por lo que amortiguará su entrada sin alterarla.