Comment différencier un fichier et sortir de la commande?

32

Normalement, vous écririez:

diff file1 file2

Mais je voudrais différencier un fichier et sortir de la commande (ici, je fais une commande triviale):

diff file1 <(cat file2 | sort)

Ok, ce travail lorsque je le saisis manuellement à l'invite du shell, mais lorsque je mets exactement la même ligne dans le script shell, puis que j'exécute le script, j'obtiens une erreur.

Donc, la question est - comment faire cela correctement?

Bien sûr, je voudrais éviter d'écrire la sortie dans un fichier temporaire.

greenoldman
la source

Réponses:

39

Je soupçonne que votre script et votre shell sont différents. Peut-être que vous avez #!/bin/shen haut de votre script en tant qu'interprète, mais que vous utilisez bashcomme shell personnel. Vous pouvez découvrir quel shell vous exécutez dans un terminal en exécutant echo $SHELL.

Un moyen plus simple de faire cela, qui devrait fonctionner sur la plupart des shells, serait d'utiliser une redirection de canal au lieu de l'opérateur de lecture de fichier que vous donnez. Le symbole «-» est une nomenclature standard pour la lecture de STDIN et peut fréquemment être utilisé en remplacement d'un nom de fichier dans une liste d'arguments:

cat file2 | sort | diff file1 -

Ou pour éviter une utilisation inutile du chat :

sort < file2 | diff file1 -
Caleb
la source
Ah, tu es bon, en effet, je n'ai pas vérifié si sh est bash ou pas. Merci beaucoup pour la solution.
greenoldman
C'est un fichier différent avec stdout. Maintenant, comment différencier une sortie standard avec un fichier? Je veux dire, la direction opposée. c'est -Ren cas d'utilisationgit diff --no-index
Nakilon
@Nakilon Vous voulez simplement changer l'ordre des arguments: diff - file1.
Caleb
Cool. Cela n'a pas fonctionné git diff.
Nakilon
@Nakilon Bien sûr que non, pourquoi le ferait-il? git diffest une bête complètement différente et fonctionne sur les références aux objets glob dans son index interne, pas sur les fichiers; difffonctionne sur le système de fichiers. La -syntaxe n'est que du sucre syntaxique shell pour /dev/stdin, le fichier représentant le flux STDIN. Par conséquent, pourquoi diffpeut-il l'utiliser comme substitut d'un nom de fichier. Pendant ce temps, il git diffne recherche pas de fichiers, il recherche des objets, vous devez donc lui transmettre quelque chose qu'il reconnaît. Ne l'utilisez pas pour comparer des fichiers entre eux, utilisez diffpour cela.
Caleb
-4

La portée de l'entrée standard est le script lui-même, alors mettez simplement votre code dans un bloc comme celui-ci:

{
  diff file1 <(sort file2)
}

De cette façon, la portée du STDIN est à l'intérieur du bloc ..

J'ai essayé et ça marche.

tmow
la source
Ce n'est pas une fonction, c'est un bloc, et cela ne fait aucune différence.
Gilles 'SO- arrête d'être méchant'
@gilles Thx pour la correction. BTW je me suis essayé et ça fonctionne. As tu?
tmow
3
Le bloc n'a aucun effet sur la validité de la <(…)construction. Votre script fonctionnera ou ne fonctionnera pas selon que vous l'exécutez dans un shell qui prend en charge <(…)ou non (ksh93 / bash / zsh vs Bourne / ash / kshk88). La réponse de Caleb résume tout.
Gilles 'SO- arrête d'être méchant'
1
@ gilles ok, merci pour l'explication.
tmow