Disons que j'ai un script que je veux diriger vers une autre commande ou rediriger vers un fichier (canalisation vers sh
pour les exemples). Supposons que j'utilise bash.
Je pourrais le faire en utilisant echo
:
echo "touch somefile
echo foo > somefile" | sh
Je pourrais aussi faire presque la même chose en utilisant cat
:
cat << EOF
touch somefile
echo foo > somefile
EOF
Mais si je remplace "EOF" par "EOF | sh", il pense simplement que cela fait partie de l'hérédoc.
Comment puis-je faire en sorte que cat
génère du texte à partir de stdin, puis le redirige vers un emplacement arbitraire?
Il existe plusieurs façons de procéder. Le plus simple est probablement celui-ci:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Un autre, qui est une syntaxe plus agréable à mon avis:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
Cela fonctionne également, mais sans le sous-shell:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
Plus de variations:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
Ou:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
Soit dit en passant, je m'attends à ce que l'utilisation de cat
dans votre question soit un espace réservé pour autre chose. Sinon, retirez-le, comme ceci:
sh <<EOF
touch somefile
echo foo > somefile
EOF
Ce qui pourrait être simplifié à ceci:
sh -c 'touch somefile; echo foo > somefile'
ou:
sh -c 'touch somefile
echo foo > somefile'
Rediriger la sortie au lieu de la tuyauterie
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Utiliser cat
pour obtenir l'équivalent de echo test > out
:
cat >out <<EOF
test
EOF
Plusieurs documents ici
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
Cela produit la sortie:
hi
---
there
Voici ce qui se passe:
( ... )
et exécute les commandes incluses dans un sous-shell.cat <&3
dit d'exécuter cat avec le descripteur de fichier (fd) 0 (stdin) redirigé depuis fd 3; en d'autres termes, éliminez l'entrée de fd 3.(...)
est démarré, le Shell voit les deux redirections et substitutions de document ici fd 0 (<<EOF
) et fd 3 (3<<EOF2
) avec le côté lecture des tuyauxJe veux juste souligner que l'utilisation de meow
est tout aussi valable que EOF
.
Ce script ajoutera Meow!
dans un fichier nommé cat
:
#!/bin/sh
cat <<meow>> cat
Meow!
meow
Enregistrez sous cats
et rendez-le exécutable avec chmod +x cats
, puis exécutez-le avec ./cats
:
$ ./cats
$ cat cat
Meow!
$ ./cats
$ cat cat
Meow!
Meow!
Explication:
cat <<meow
est la syntaxe ici du document . Il demande au script de récupérer le bloc de texte qui suit cette ligne, jusqu'à ce qu'il rencontre la chaîne meow
. Le contenu sera ensuite sorti (ou canalisé).>> cat
redirige vers le fichier nommé cat
.>
au lieu de >>
écraserait le fichier au lieu de l'ajouter.Meow!
est le contenu du document ici .meow
est le marqueur de fin du document ici . Le contenu est, avec l'utilisation de >>
, ajouté à cat
.Piping à la fois vers stdout et vers un fichier:
Pour faire la tuyauterie que vous demandez, aucun document ici n'est requis.
cat
ne peut pas à la fois produire du texte et transmettre le texte, mais tee
correspond parfaitement à ce que vous demandez:
echo echo | tee tee
Cela produira à la fois la chaîne echo
et écrit echo
dans un fichier nommé tee
.
Vous pouvez également transmettre la sortie via cat
, si cela fait partie de l'exigence, soit avec:
echo echo | tee tee | cat </dev/stdin
Ou juste:
echo echo | tee tee | cat
Contenu du dossier:
$ cat tee
echo