¿Cómo diferenciar un archivo y salida del comando?

32

Normalmente escribirías:

diff file1 file2

Pero me gustaría diferenciar un archivo y salida del comando (aquí hago que el comando sea trivial):

diff file1 <(cat file2 | sort)

Ok, esto funciona cuando ingreso esto manualmente en el indicador de comandos de shell, pero cuando pongo exactamente la misma línea en el script de shell y luego ejecuto el script, obtengo un error.

Entonces, la pregunta es: ¿cómo hacer esto correctamente?

Por supuesto, me gustaría evitar escribir la salida en un archivo temporal.

Greenoldman
fuente

Respuestas:

39

Sospecho que tu guión y tu caparazón son diferentes. Quizás tenga #!/bin/shen la parte superior de su guión como intérprete, pero lo está utilizando bashcomo su caparazón personal. Puede averiguar qué shell ejecuta en una terminal ejecutando echo $SHELL.

Una manera más fácil de hacer esto, que debería funcionar en la mayoría de los shells, sería utilizar una redirección de tubería en lugar del operador de lectura de archivos que usted proporciona. El símbolo '-' es una nomenclatura estándar para leer STDIN y con frecuencia se puede usar como reemplazo del nombre de un archivo en una lista de argumentos:

cat file2 | sort | diff file1 -

O para evitar un uso inútil del gato :

sort < file2 | diff file1 -
Caleb
fuente
Ah, eres bueno, de hecho, no verifiqué si sh es bash o no. Muchas gracias por la solución.
greenoldman
Es un archivo diferente con stdout. ¿Ahora cómo diferir stdout con un archivo? Quiero decir, la dirección opuesta. es -Ren caso de usogit diff --no-index
Nakilon
@Nakilon Usted acaba de cambiar el orden de los argumentos: diff - file1.
Caleb
Guay. Esto no funcionó git diff.
Nakilon
@Nakilon Por supuesto que no, ¿por qué lo haría? git diffes una bestia completamente diferente y opera con referencias a objetos globales en su índice interno, no a archivos; diffopera en el sistema de archivos. La -sintaxis es solo azúcar sintáctica de shell para /dev/stdin, el archivo que representa la secuencia STDIN. Por lo tanto, ¿por qué diffpuede usarlo como sustituto de un nombre de archivo? Mientras tanto, git diffno está buscando archivos, está buscando objetos, por lo que debe pasarle algo que reconozca. No lo use para comparar archivos entre sí, úselo diffpara eso.
Caleb el
-4

El alcance de la entrada estándar es el script en sí mismo, así que simplemente coloque su código dentro de un bloque como este:

{
  diff file1 <(sort file2)
}

De esta manera, el alcance del STDIN está dentro del bloque.

Lo he intentado y funciona.

tmow
fuente
Esa no es una función, es un bloque y no hace ninguna diferencia.
Gilles 'SO- deja de ser malvado'
@gilles Thx para la corrección. Por cierto, lo he probado y funciona. ¿Tuviste?
mm
3
El bloque no tiene ningún efecto sobre la validez de la <(…)construcción. Su script funcionará o no, dependiendo de si lo ejecuta en un shell compatible <(…)o no (ksh93 / bash / zsh vs Bourne / ash / kshk88). La respuesta de Caleb lo clava todo.
Gilles 'SO- deja de ser malvado'
1
@gilles ok, gracias por la explicación.
mañana