Powiedzmy, że istnieje program, który przyjmuje dwa argumenty; plik wejściowy i plik wyjściowy.
Co jeśli nie chcę zapisać tego pliku wyjściowego na dysk, a raczej przekazać go bezpośrednio stdin
innemu programowi. Czy istnieje sposób na osiągnięcie tego?
Wiele poleceń, na które natrafiłem w systemie Linux, udostępnia opcję przekazania „-” jako argumentu pliku wyjściowego, który robi to, co określiłem powyżej. Czy to dlatego, że przekazanie stdin
programu jako argumentu nie jest możliwe? Jeśli tak, to jak to robimy?
Przykładem tego, w jaki sposób obrazowałbym za pomocą tego jest:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
Powłoka, której używam, to bash.
bash
io-redirection
arguments
Dziugas
źródło
źródło
cat <file | cmd /dev/fd/0
działa na większości jednorożców.cat < README.txt | cp /dev/fd/0
. Powiedziałcp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
program input-file /dev/stdout | another-program
? Zauważ też, żeecho
nic nie czyta ze standardowego wejścia.cp
nigdzie nie można utworzyć pliku.echo 1 2 3| cp /dev/fd/0 /dev/tty
wydrukuje1 2 3
. Nawiasem mówiąc,/dev/fd/[num]
jest bardziej prawdopodobne, że zadziała niż/dev/std(in|out|err)
w większości przypadków. Zobacz Przenośność linków deskryptorów plików, aby dowiedzieć się, gdzie możesz pracować.Odpowiedzi:
Jeśli program obsługuje zapis do dowolnego deskryptora pliku, nawet jeśli nie może wyszukiwać, możesz użyć go
/dev/stdout
jako pliku wyjściowego. To jest dowiązanie symboliczne do/proc/self/fd/1
mojego systemu. Deskryptor pliku 1 jest stdout.źródło
pdftotext
podobnie jak wiele (ale nie wszystkie) innych narzędzi obsługujących-
to (które działałyby nawet na systemach, które nie obsługują / dev / stdout, lub gdzie / dev / stdout nie działają zgodnie z oczekiwaniami, tak jak w Linuksie, gdzie stdout nie jest rura).pdftotext file.pdf - | wc -c
Ze strony podręcznika
pdftotext
:Więc w tym przypadku wszystko czego potrzebujesz to:
Lub jeśli chcesz potokować to do STDIN innego programu:
Używanie
-
jako zamiennika nazwy pliku jest konwencją stosowaną przez wiele narzędzi (w tym pdftotext), gdy chcemy wprowadzić dane wejściowe ze STDIN lub dane wyjściowe do STDOUT. Jednak nie wszystkie narzędzia są zgodne z tą konwencją. W takim przypadku idiomatycznym sposobem na zrobienie tego w bash jest użycie podstawienia procesu :Tutaj
>( )
zachowuje się w dużej mierze jak plik przesłany domy_utility
, ale zamiast być prawdziwym plikiem, strumień jest przesyłany strumieniowo do wejścia standardowego zawartego procesu, tj. Cat. Tak więc tekst powinien ostatecznie zostać wydrukowany zgodnie z wymaganiami.Użycie
cat
prawie zawsze uruchamia dzwonki alarmowe UUOC na takich forach. Twierdzę, że jeśli narzędzie nie obsługuje-
, to jest to użyteczne zastosowaniecat
, chociaż jeśli istnieją sposoby na zastąpienie tego procesu bezcat
, to jestem cały w uszach ;-).Jeśli jednak (jak stwierdza pytanie) ostatecznym miejscem docelowym strumienia jest STDIN innego programu, wówczas
cat
można go wyeliminować:źródło
prog2
pisze na standardowe wyjście, jest lepsze niż , ponieważ formularz czeka na zakończenie (tj. Zanim powłoka wyda następny monit lub przejdzie do następnego polecenia (np. Po lub )), podczas gdy - bez formularza czeka tylko na wypełnienie. Również po formularzu jest status wyjścia z , podczas gdy w drugim jest status wyjścia z . (Płacisz pieniądze i sam wybierasz.)prog1 input_file
>( cat ) |
prog2
prog1 input_file
>(
prog2
)
cat
prog2
;
&&
cat
prog1
cat
$?
prog2
$?
prog1
Jeśli twoja powłoka je obsługuje, najprostszym sposobem wykonywania takich manipulacji byłoby użycie podstawiania procesów :
<(…)
i>(…)
. Działa to w bash, zsh i ksh i ewentualnie w innych powłokach. Na przykład:Jednak to nie pomoże w podanym przykładzie, ponieważ
pdftotext
zostanie zapisany w pliku tekstowym. Podczas gdy twój najlepszy wybór (oprócz oczywistego wyboru-
) jest użycie/dev/stdout
zgodnie z sugestią @TiCPU, możesz również użyć innej funkcji powłoki. Konstrukt!:N
odwołuje się do N-tego argumentu poprzedniego polecenia. Dlatego możesz:źródło
cat <()
może to być przydatne w niektórych sytuacjach, w tym scenariuszu jednak w ogóle nie działa. Problem (bardzo źle opisany przez OP, muszę przyznać) polega na tym, żepdftotext
wymaga dwóch argumentów: pliku wejściowego i pliku wyjściowego . Jeśli brakuje drugiego argumentu, to nic nie produkuje, więccat <(pdftotext "file.pdf")
również nic nie zwraca. Można oszukiwaćpdftotext
polecenia, podając>(cat)
jako drugi argument, na który odpowiedział Digital Trauma, alecat <()
tutaj nie ma sensu. Oczywiście wpdftotext
przypadku, gdy najlepiej jest użyć-
jako nazwy pliku wyjściowego.>( )
skutecznie potokuje strumień do dowolnego procesu, który jest w środku - tak naprawdę potrzebujemycat
tutaj, aby wyprowadzić ten strumień. Zwykle powinniśmy być w stanie zrobić coś podobnegopdftotext input.pdf -
, ale najwyraźniejpdftotext
nie obsługuje-
parametru do wyświetlania bezpośrednio na wyjściu zamiast do pliku - spróbuj.>(grep something)
aby być bardziej użytecznym. BTW, mojapdftotext 3.04
Do wsparcia-
w postaci pliku wyjściowego, więc jestem trochę zaskoczony całej dyskusji.pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"
, które umieszcza dane wyjściowe w pliku o nazwieC BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt
, ale żaden tekst nie jest wysyłany do STDOUT w celu przesłania do innego programu.tty
zwraca nazwę podłączonego terminalastdout
.źródło
tty
nazwy terminala, a następnie na przykład użyj tego pliku jako danych wyjściowychpdftotext file.pdf /dev/pts/2
. W takim przypadku zgadzam się.prog1 input_file
$(tty)
prog1 input_file
/dev/tty
prog1