Desde /unix//a/458074/674
Recuerde usar
--
cuando pase argumentos arbitrarios a los comandos (o use redirecciones cuando sea posible). Asísort -- "$f1"
o mejor ensort < "$f1"
lugar desort "$f1"
.
¿Por qué se prefiere usar --
y redireccionar?
¿Por qué se sort < "$f1"
prefiere más sort -- "$f1"
?
¿Por qué se sort -- "$f1"
prefiere más sort "$f1"
?
Gracias.
Respuestas:
falla para los valores
$f1
que comienzan con-
o aquí para el caso desort
algunos que comienzan con+
(puede tener graves consecuencias para un archivo llamado,-o/etc/passwd
por ejemplo).(donde
--
señala el final de las opciones) aborda la mayoría de esos problemas pero aún falla para el archivo llamado-
(quesort
en su lugar interpreta que significa su stdin).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
(al contrario de
sort -- "$f1" > out
), si"$f1"
no se puede abrir,out
no se creará / truncará ysort
ni 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 lolseek()
contenga dentro (no losort
hace 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 lugarcat file | cmd
dondecmd
el stdin de esta vez es una tubería que no puede mapearse / buscarse.fuente
sort
a leer los datos secuencialmente y no puede hacermmap
el archivo. Si bien essort
posible que no tenga muchos problemas, considere el rendimiento deless <file
yless file
. En el primer casoless
tiene 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 quefile
es un archivo de registro de 100GB ...less <file
mantiene todo el archivo en la memoria, pero no está obligado a hacerlo, esta es una deficiencia de menos. Solocat file | less
se ve obligado a hacerlo. Echa un vistazoless /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.read()
lee datos secuencialmente de un archivo, mientrasmmap()
lee todo el archivo en la memoria a la vez?sort
POSIX. Pero es cierto que no siempre es compatible.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.El problema son los nombres de archivo que comienzan con un guión.
sort "$f1"
no funciona si el valor def1
comienza-
porque el comando interpretará el valor como una opción. Esto generalmente produce un error, pero incluso podría causar un agujero de seguridad . Consort -- "$f1"
, el argumento de doble guión--
significa "no hay opciones más allá de este punto", por lo que el valor def1
no se interpretará como una opción. Pero todavía hay un caso límite: si el valor def1
es 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
.fuente
sort < "$f1"
funcionaría si el valor fuera igual a-
? En ningún caso, lo he intentado.seq 10 > -; sort -
conseq 10 > -; sort < -
.