tl; dr
No. >>
es esencialmente "siempre buscar el final del archivo" mientras >
mantiene un puntero a la última ubicación escrita.
Respuesta completa
(Nota: todas mis pruebas realizadas en Debian GNU / Linux 9).
Otra diferencia
No, no son equivalentes. Hay otra diferencia Puede manifestarse independientemente de si el archivo de destino existía antes o no.
Para observarlo, ejecute un proceso que genere datos y redirija a un archivo con >
o >>
(por ejemplo pv -L 10k /dev/urandom > blob
). Deje que se ejecute y cambie el tamaño del archivo (por ejemplo, con truncate
). Verá que >
mantiene su desplazamiento (creciente) mientras >>
siempre se agrega al final.
- Si trunca el archivo a un tamaño más pequeño (puede ser de tamaño cero)
>
no le importará, escribirá en el desplazamiento deseado como si nada hubiera pasado; justo después de truncar el desplazamiento está más allá del final del archivo, esto hará que el archivo recupere su tamaño anterior y crezca aún más, los datos faltantes se rellenarán con ceros (de manera dispersa, si es posible);
>>
se agregará al nuevo final, el archivo crecerá desde su tamaño truncado.
- Si amplías el archivo
>
no le importará, escribirá en el desplazamiento deseado como si nada hubiera pasado; justo después de cambiar el tamaño, el desplazamiento está en algún lugar dentro del archivo, esto hará que el archivo deje de crecer por un tiempo, hasta que el desplazamiento llegue al nuevo final, entonces el archivo crecerá normalmente;
>>
se agregará al nuevo final, el archivo crecerá desde su tamaño ampliado.
Otro ejemplo es agregar (con un aparte >>
) algo extra cuando el proceso de generación de datos se está ejecutando y escribiendo en el archivo. Esto es similar a agrandar el archivo.
- El proceso de generación con
>
escribirá en su desplazamiento deseado y eventualmente sobrescribirá los datos adicionales.
- El proceso de generación con
>>
omitirá los nuevos datos y los agregará más allá (puede ocurrir una condición de carrera, las dos transmisiones pueden intercalarse, aún no se deben sobrescribir los datos).
Ejemplo
¿Importa en la práctica? Hay esta pregunta :
Estoy ejecutando un proceso que produce una gran cantidad de resultados en stdout. Enviarlo todo a un archivo [...] ¿Puedo usar algún tipo de programa de rotación de registros?
Esta respuesta dice que la solución es logrotate
con la copytruncate
opción que actúa así:
Trunca el archivo de registro original en su lugar después de crear una copia, en lugar de mover el archivo de registro anterior y, opcionalmente, crear uno nuevo.
De acuerdo con lo que escribí anteriormente, la redirección con >
hará que el registro truncado sea grande en poco tiempo. La escasez salvará el día, no debe desperdiciarse un espacio significativo en el disco. Sin embargo, cada registro consecutivo tendrá cada vez más ceros a la izquierda que son completamente innecesarios.
Pero si logrotate
crea copias sin preservar la escasez, estos ceros iniciales necesitarán más y más espacio en disco cada vez que se haga una copia. No he investigado el comportamiento de la herramienta, puede ser lo suficientemente inteligente con escasez o compresión sobre la marcha (si la compresión está habilitada). Aún así, los ceros solo pueden causar problemas o ser neutrales en el mejor de los casos; Nada bueno en ellos.
En este caso, usar en >>
lugar de >
es significativamente mejor, incluso si el archivo de destino está a punto de crearse todavía.
Actuación
Como podemos ver, los dos operadores actúan de manera diferente no solo cuando comienzan sino también más tarde. Esto puede causar alguna diferencia (¿sutil?) De rendimiento. Por ahora no tengo resultados de prueba significativos para respaldarlo o refutarlo, pero creo que no debería suponer automáticamente que su rendimiento es el mismo en general.
>>
lo tanto, es esencialmente "siempre buscar el final del archivo" mientras se>
mantiene un puntero a la última ubicación escrita. Parece que también puede haber una sutil diferencia de rendimiento en la forma en que funcionan ...>>
usa elO_APPEND
indicador paraopen()
. Y en realidad,>
usaO_TRUNC
, mientras>>
que no. La combinación deO_TRUNC | O_APPEND
también sería posible, el lenguaje de shell simplemente no proporciona esa característica.O_APPEND
con unlseek()
antes de cada unowrite()
sería diferente, habría una sobrecarga de llamadas al sistema adicional. (Y, por supuesto, no funcionaría, ya que otro proceso podría estarwrite()
en el medio.)