Une commande tar normale
tar cvf foo.tar ./foo >foo.out 2>foo.err
a trois flux d'E / S de sortie
- archiver les données dans foo.tar
- liste des noms de fichiers vers STDOUT (redirigé vers foo.out)
- messages d'erreur vers STDERR (redirigé vers foo.err)
Je peux ensuite inspecter foo.err pour les messages d'erreur sans avoir à lire la liste des noms de fichiers.
si je veux faire quelque chose avec les données d'archive (les diriger via netcat ou un programme de compression spécial), je peux utiliser l' -f -
option de tar ainsi
tar cvf - ./foo 2>foo.err | squish > foo.tar.S
Mais maintenant, ma liste de noms de fichiers est mélangée à mes messages d'erreur parce que la -v
sortie de tar ne peut évidemment pas aller vers STDOUT (c'est là que les données d'archives circulent), donc tar écrit intelligemment cela dans STDERR à la place.
En utilisant le shell Korn, existe-t-il un moyen de construire une commande qui redirige le flux d'archive vers une autre commande tout en capturant la -v
sortie séparément des messages d'erreur.
tee
? Cela semble être un cas d'utilisation assez valable pour cela.Réponses:
Si votre système prend en charge
/dev/fd/n
:Avec les implémentations AT&T de
ksh
(oubash
ouzsh
), vous pourriez écrire en utilisant la substitution de processus :Cela fait exactement la même chose, sauf que cette fois, le shell décide du descripteur de fichier à utiliser au lieu de
3
(généralement au-dessus de 9). Une autre différence est que cette fois, vous obtenez le statut de sortie detar
au lieu desquish
. Sur les systèmes qui ne prennent pas en charge/dev/fd/n
, certains shells peuvent recourir à des canaux nommés pour cette fonctionnalité.Si votre système ne prend pas en charge
/dev/fd/n
ou que votre shell ne peut pas utiliser de canaux nommés pour sa substitution de processus, c'est là que vous devrez traiter les canaux nommés à la main .la source
Vous devez utiliser un canal nommé pour cela.
Créez d'abord un dans le dossier:
Utilisez ensuite cette commande:
Remarque: la
cat
partie-, peut maintenant aussi êtregzip
ou quoi que ce soit, qui peut lire à partir d'un tuyau:Explication:
La sortie est écrit à la conduite de nom (
foo.pipe
), où un autre proccess (cat
,gzip
,netcat
) lit à partir. Vous ne perdez donc pas les canaux stdout / stderr pour plus d'informations.la source
umask 077
(ou d'utiliser un répertoire temporaire privé) pour empêcher d'autres processus de lire ou d'écrire dessus (sur de nombreux systèmes, les canaux nommés, comme d'autres fichiers sont créés lisibles par défaut par le monde), 2) vous devez vous assurer le canal nommé n'est utilisé que par chaque instance de votre script (encore une fois, un répertoire temporaire privé unique aide) 3) Cela signifie que vous devez nettoyer par la suite ou s'il est interrompu.p="/tmp/pipe$$"; mkfifo "$p"; (read na; cmd[s]...) <>"$p" & (echo;rm "$p"; cmd[s]...) >"$p"
L'
--index-file
option de GNU tar fonctionne bien:la source