Disons qu'un programme existe, qui prend deux arguments; fichier d'entrée et fichier de sortie.
Que faire si je ne souhaite pas enregistrer ce fichier de sortie sur le disque, mais plutôt le transmettre directement à stdin
un autre programme. Existe-t-il un moyen d'y parvenir?
Beaucoup de commandes que je rencontre sous Linux fournissent une option pour passer '-' comme argument de fichier de sortie, ce qui fait ce que j'ai spécifié ci-dessus. Est-ce parce que le passage stdin
d'un programme en argument n'est pas possible? Si tel est le cas, comment procédons-nous?
Un exemple de la façon dont je voudrais l'image en utilisant ceci est:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
Le shell que j'utilise est bash.
bash
io-redirection
arguments
Dziugas
la source
la source
cat <file | cmd /dev/fd/0
fonctionne sur la plupart des unités.cat < README.txt | cp /dev/fd/0
. Il a ditcp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
program input-file /dev/stdout | another-program
? Notez également queecho
ne lit rien de stdin.cp
un fichier nulle part.echo 1 2 3| cp /dev/fd/0 /dev/tty
va imprimer1 2 3
. Et en passant,/dev/fd/[num]
est plus susceptible de fonctionner que/dev/std(in|out|err)
dans la plupart des cas. Voir Portabilité des liens descripteurs de fichiers sur ce à quoi vous pouvez vous attendre à travailler où.Réponses:
Si le programme prend en charge l'écriture dans n'importe quel descripteur de fichier même s'il ne peut pas le rechercher, vous pouvez l'utiliser
/dev/stdout
comme fichier de sortie. Il s'agit d'un lien symbolique vers/proc/self/fd/1
mon système. Le descripteur de fichier 1 est stdout.la source
pdftotext
comme beaucoup (mais pas tous) d'autres utilitaires prennent également en charge-
cela (qui fonctionnerait même sur des systèmes qui ne prennent pas en charge / dev / stdout, ou où / dev / stdout ne fonctionne pas comme prévu comme sur Linux où stdout n'est pas un tuyau).pdftotext file.pdf - | wc -c
Depuis la
pdftotext
page de manuel:Donc, dans ce cas, tout ce dont vous avez besoin est:
Ou si vous voulez diriger ceci vers STDIN d'un autre programme:
L'utilisation
-
comme substitut d'un nom de fichier est une convention que de nombreux utilitaires suivent (y compris pdftotext) lorsque nous voulons une entrée depuis STDIN ou une sortie vers STDOUT. Cependant, tous les utilitaires ne suivent pas cette convention. Dans ce cas, la façon idiomatique de le faire dans bash est d'utiliser une substitution de processus :Ici, le
>( )
comportement se fait en grande partie comme un fichier transmis àmy_utility
, mais au lieu d'être un vrai fichier, le flux est canalisé dans le stdin du processus contenu, c'est-à-dire cat. Donc, ici, le texte devrait finalement sortir comme requis.L'utilisation de
cat
presque toujours déclenche des sonneries d'alarme UUOC sur des forums comme celui-ci. Je soutiens que si l'utilitaire ne prend pas en charge-
, c'est une utilisation utile decat
, bien que s'il existe des moyens de faire cette substitution de processus sans lecat
, alors je suis à l'écoute ;-).Cependant, si (comme l'indique la question) la destination finale du flux est STDIN d'un autre programme, alors le
cat
peut être éliminé:la source
prog2
écrit sur stdout, c'est mieux que , car le formulaire attend la fin (c'est-à-dire avant que le shell émette l'invite suivante ou passe à la commande suivante (par exemple, après ou )), tandis que le -les formulaires n'attendent que d' être complétés. En outre, après le formulaire, est le statut de sortie de , tandis que, dans l'autre, est le statut de sortie de . (Vous payez votre argent et vous faites votre choix.)prog1 input_file
>( cat ) |
prog2
prog1 input_file
>(
prog2
)
cat
prog2
;
&&
cat
prog1
cat
$?
prog2
$?
prog1
Si votre shell les prend en charge, la manière la plus simple de faire de telles manipulations serait d'utiliser la substitution de processus :
<(…)
et>(…)
. Cela fonctionne dans bash, zsh et ksh et éventuellement dans d'autres shells. Par exemple:Cependant, cela n'aidera pas dans l'exemple que vous indiquez, car il
pdftotext
sera enregistré dans un fichier texte. Bien que votre meilleur choix (en dehors de l'utilisation évidente-
) soit d'utiliser/dev/stdout
comme suggéré par @TiCPU, vous pouvez également utiliser une autre fonctionnalité de shell. La construction!:N
fait référence au Nième argument de la commande précédente. Par conséquent, vous pourriez faire:la source
cat <()
peut être utile dans certaines situations, dans ce scénario, cependant, cela ne fonctionne pas du tout. Le problème (très mal décrit par OP, je dois l'avouer) est qu'ilpdftotext
prend deux arguments: le fichier d'entrée et le fichier de sortie . Si le deuxième argument est manquant, il ne produit rien, donccat <(pdftotext "file.pdf")
ne retournerait rien non plus. On peut tricherpdftotext
commande en donnant>(cat)
comme deuxième argument comme Digital Trauma a répondu, maiscat <()
est inutile ici. Évidemment, dans lepdftotext
cas où il est préférable de l'utiliser-
comme nom de fichier de sortie.>( )
dirigera efficacement le flux vers le processus à l'intérieur - nous avons donc réellement besoin d'uncat
ici pour sortir ce flux. Normalement, nous devrions pouvoir faire quelque chose commepdftotext input.pdf -
, mais apparemmentpdftotext
ne prend pas en charge le-
paramètre pour sortir directement vers stdout au lieu d'un fichier - essayez-le.>(grep something)
pour être plus utile. BTW, monpdftotext 3.04
do support en-
tant que fichier de sortie, donc je suis un peu surpris par toute discussion.pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"
, qui place la sortie dans un fichier appeléC BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt
, mais aucun du texte n'est sorti vers STDOUT pour être redirigé vers un autre programme.tty
renvoie le nom du terminal connectéstdout
.la source
tty
le nom du terminal, puis d'utiliser ce fichier comme sortie, par exemplepdftotext file.pdf /dev/pts/2
. Dans ce cas, je suis d'accord.prog1 input_file
$(tty)
prog1 input_file
/dev/tty
prog1