web-dev-qa-db-fra.com

Utiliser grep avec pipe et esperluette pour filtrer les erreurs de find

J'utilise cygwin pour trouver un fichier sur le disque.

Cependant, je dois supprimer les messages d'autorisation refusés (sinon, les résultats sont masqués dans les messages d'erreur). La commande suivante fonctionne:

find -name 'myfile.*' |& grep -v "Permission denied"

Je ne comprends pas pourquoi l'esperluette doit être placée dans cette commande, je m'attendais à ce que cela fonctionne, mais ce n'est pas le cas.

find -name 'myfile.*' | grep -v "Permission denied"

S'il vous plaît expliquer la signification de l'esperluette.

21
HKK

Dans les systèmes de type Unix, il existe deux chemins de sortie qui, s'ils ne sont pas modifiés, enverront la sortie à votre écran. L'erreur standard (ou stderr) est celle qui capture la plupart des défaillances et des conditions d'erreur.

Pour transmettre le message d'autorisation refusée dans stderr au même flux de sortie que "sortie normale", vous devez combiner les deux. Dans votre exemple, pour que votre grep -v fonctionne correctement, vous combinez stdout (sortie standard) et stderr avec la syntaxe arcane que vous voyez.

De Manuel GNU Bash section .2.2 Pipelines :

Si '|&' est utilisé, l'erreur standard de command1 , en plus de sa sortie standard, est connectée à L'entrée standard de command2 à travers le tuyau; c'est un raccourci pour 2>&1 |. Cette redirection implicite de l'erreur standard vers la sortie standard est effectuée après les redirections spécifiées par la commande.

En outre, comme le souligne geirha, si vous souhaitez simplement vous débarrasser de la sortie stderr, vous voudrez faire quelque chose comme:

find -name 'myfile.*' 2> /dev/null

ou peut-être

find -name 'myfile.*' 2> /tmp/errorlog

Et notez que si vous avez des chaînes de commandes, telles que find transmettant sa sortie à xargs, vous devez placer l'intégralité du pipeline de commandes entre parenthèses pour capturer la sortie de tous les composants de la commande. Par exemple.,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Si vous avez omis les parenthèses et si vous avez fait cela à la place -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

vous verriez toujours les autorisations refusées par find ou egrep, mais stderr serait redirigé pour xargs.

Comme vous l'avez vu, vous ne jeterez probablement le stderr qu'après avoir visualisé son contenu lors d'un test.

Notez qu'avec GNU find et autant que je sache, aucun find conforme à POSIX, l'option -print est implicite. Vous pouvez toujours le fournir explicitement si vous le souhaitez.

24
belacqua

Les messages d'erreur sont écrits dans stderr , pas stdout , mais | ne conduit que stdout .

Vous voulez probablement |&, quels tubes stderr ainsi que stdout .

10
Florian Diesch

Si vous voulez ignorer les messages d'erreur, redirigez simplement stderr vers/dev/null.

find . -name 'myfile.*' -print 2>/dev/null

Aussi, envisagez de lire http://mywiki.wooledge.org/UsingFind .

1
geirha