¿Por qué se prefiere `sort <“ $ f1 ”` sobre `sort -“ $ f1 ”`, y por qué se prefiere esto sobre `sort '$ f1” `?

Respuestas:

55
sort "$f1"

falla para los valores $f1que comienzan con -o aquí para el caso de sortalgunos que comienzan con +(puede tener graves consecuencias para un archivo llamado, -o/etc/passwdpor ejemplo).

sort -- "$f1"

(donde -- señala el final de las opciones) aborda la mayoría de esos problemas pero aún falla para el archivo llamado -(que sorten su lugar interpreta que significa su stdin).

sort < "$f1"

No tiene esos problemas.

Aquí, es el shell que abre el archivo. También significa que si el archivo no se puede abrir, también recibirá un mensaje de error potencialmente más útil (por ejemplo, la mayoría de los shells indicarán el número de línea en el script), y el mensaje de error será coherente si usa redirecciones siempre que sea posible para abrir archivos.

Y en

sort < "$f1" > out

(al contrario de sort -- "$f1" > out), si "$f1"no se puede abrir, outno se creará / truncará y sortni siquiera se ejecutará.

Para aclarar alguna posible confusión (siguiendo los comentarios a continuación), eso no impide que el comando mmap()ingrese el archivo o lo lseek()contenga dentro (no lo sorthace tampoco) siempre que el archivo en sí sea buscable. La única diferencia es que el archivo se abre antes y en el descriptor de archivo 0 por el shell en lugar de más tarde por el comando posiblemente en un descriptor de archivo diferente. El comando aún puede buscar / mmap que fd 0 como le plazca. Eso no debe confundirse con el lugar cat file | cmddonde cmdel stdin de esta vez es una tubería que no puede mapearse / buscarse.

Stéphane Chazelas
fuente
44
Solo recuerde que el uso de una redirección obliga sorta leer los datos secuencialmente y no puede hacer mmapel archivo. Si bien es sortposible que no tenga muchos problemas, considere el rendimiento de less <filey less file. En el primer caso lesstiene que mantener todo el contenido del archivo en la memoria, en el segundo caso se le permite leer solo las partes que desea. Ahora imagine que filees un archivo de registro de 100GB ...
styrofoam fly
77
@styrofoamfly: Es correcto que less <filemantiene todo el archivo en la memoria, pero no está obligado a hacerlo, esta es una deficiencia de menos. Solo cat file | lessse ve obligado a hacerlo. Echa un vistazo less /dev/fd/0 <f, que no mantiene el archivo en memoria, aunque lo recibe en stdin. Es un error común pensar que stdin en Unix no se puede buscar. De hecho, puede ser buscable, dependiendo del tipo de archivo.
pts
@styrofoamfly ¿Quiere decir que read()lee datos secuencialmente de un archivo, mientras mmap()lee todo el archivo en la memoria a la vez?
Tim
1
@JohnBollinger No. Eso se remonta al menos a getopt de SysIII en 1980 antes de que se iniciara el proyecto GNU y debe ser compatible con la mayoría de las utilidades estándar, incluido sortPOSIX. Pero es cierto que no siempre es compatible.
Stéphane Chazelas
2
Mis disculpas, @ StéphaneChazelas, tiene razón sobre el origen de la convención, y además estipularé que la especificación POSIX para la getopt()función C reconoce esta importancia del argumento --. Pero el punto principal es el que usted acepta: el manejo de argumentos es el dominio de programas individuales, y no todos tratan --especialmente.
John Bollinger
17

El problema son los nombres de archivo que comienzan con un guión. sort "$f1"no funciona si el valor de f1comienza -porque el comando interpretará el valor como una opción. Esto generalmente produce un error, pero incluso podría causar un agujero de seguridad . Con sort -- "$f1", el argumento de doble guión --significa "no hay opciones más allá de este punto", por lo que el valor de f1no se interpretará como una opción. Pero todavía hay un caso límite: si el valor de f1es un guión y nada más, entonces no es una opción, es el argumento -, que significa "entrada estándar" (porque el argumento es un archivo de entrada; para un archivo de salida significaría "salida estándar").

El uso de la redirección evita todas estas trampas.

Esto se aplica a la mayoría de los comandos, no solo sort.

Gilles 'SO- deja de ser malvado'
fuente
¿Estás diciendo que sort < "$f1"funcionaría si el valor fuera igual a -? En ningún caso, lo he intentado.
Grawity
@grawity, compara seq 10 > -; sort -con seq 10 > -; sort < -.
Stéphane Chazelas