Bir programın standart girdisi diğerine arg olarak nasıl aktarılabilir?


17

Diyelim ki iki argüman alan bir program var; girdi dosyası ve çıktı dosyası.

Ya bu çıktı dosyasını diske kaydetmek istemiyorsam, doğrudan stdinbaşka bir programa aktarmak istersem . bunu arşivlemenin bir yolu var mı?

Linux'ta karşılaştığım birçok komut, çıktı dosyası argümanı olarak '-' iletme seçeneği sunuyor, bu da yukarıda belirttiğim şeyi yapıyor. Bunun nedeni stdinbir programın argüman olarak aktarılması mümkün değil mi? Öyleyse, nasıl yapıyoruz?

Bunu kullanarak görüntü nasıl bir örnek:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)

Kullandığım kabuk bash.


1
cat <file | cmd /dev/fd/0çoğu unice üzerinde çalışır.
mikeserv

Benim için çalışmıyor. İle denedim: cat < README.txt | cp /dev/fd/0. O dedicp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
Dziugas

1
program input-file /dev/stdout | another-program? Ayrıca echo, stdin'den hiçbir şey okumadığını unutmayın .
yaegashi

1
@Dziugas - tabii ki hayır - cphiçbir yerde bir dosya yapamazsınız . echo 1 2 3| cp /dev/fd/0 /dev/ttyyazdıracaktır 1 2 3. Bu arada, çoğu durumda /dev/fd/[num]çalışma olasılığı daha yüksektir /dev/std(in|out|err). Nerede çalışacağını bekleyebileceğiniz hakkında Dosya Tanımlayıcı Bağlantılarının Taşınabilirliği konusuna bakın .
mikeserv

1
İyi bir UNIX programı, standart çıktıya yazarak bir dosyaya veya kanalın başka bir komuta yönlendirmek isteyip istemediğine karar vermek için kullanıcıya bırakacaktır.
Jorge Bucaran

Yanıtlar:


13

Program, arama yapmasa bile herhangi bir dosya tanımlayıcıya yazmayı destekliyorsa /dev/stdout, çıktı dosyası olarak kullanabilirsiniz . Bu /proc/self/fd/1benim sistemime bir sembolik . Dosya tanımlayıcı 1 stdout'tur.


Bu sorgumu çözdü. Peki, program araması gerektiğinde bunu yapmanın bir yolu yok mu?
Dziugas

3
Disk erişimini engellemeye çalışıyorsanız, dosyayı / dev / shm / içine yazabilirsiniz, ancak dosya sisteminde herhangi bir dosya istemiyorsanız, bildiğim kadarıyla aramanın bir yolu yoktur. bir boru. İleriye bakmak, o noktaya gelinceye kadar bellekteki her şeyi arabelleğe alması gerektiği anlamına gelir ve geriye doğru arama, bellekteki her şeyi arabelleğe almayı ima eder.
TiCPU

pdftotextbunun gibi birçok yardımcı program da destekliyor -(/ dev / stdout'u desteklemeyen sistemlerde bile çalışacak veya / dev / stdout'un stdout'un olmadığı Linux'ta beklendiği gibi çalışmadığı gibi) bir boru). pdftotext file.pdf - | wc -c
Stéphane Chazelas

11

Gönderen pdftotextadam sayfası:

Metin dosyası ´- 'ise, metin stdout'a gönderilir.

Yani bu durumda ihtiyacınız olan tek şey:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -

Veya bunu başka bir programın STDIN'ına aktarmak istiyorsanız:

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog

-STDIN'den giriş yapmak veya STDOUT'a çıktı almak istediğimizde, bir dosya adının yerine kullanmak bir kuraldır (pdftotext dahil). Ancak, tüm hizmetler bu sözleşmeyi izlemez. Bu durumda, bunu bash'da yapmanın deyimsel yolu bir süreç ikamesi kullanmaktır :

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )

Burada >( )büyük ölçüde aktarılan bir dosya gibi davranır my_utility, ancak gerçek bir dosya olmak yerine, akış içerilen işlemin stdinine, yani kedine bağlanır. Yani burada, metin sonuçta gerektiği gibi çıktılanmalıdır.

Kullanımı catkapalı hemen her zaman setler UUOC alarm zilleri böyle forumlarında. Yardımcı program desteklemiyorsa -, o zaman bu yararlı bir kullanım olduğunu cat, ancak bu işlem ikamesi olmadan yapmanın herhangi bir yolu varsa cat, o zaman ben tüm kulaklar ;-) olduğunu iddia ediyorum.

Bununla birlikte, (sorunun belirttiği gibi) akışın nihai hedefi başka bir programın STDIN'si ise, catortadan kaldırılabilir:

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )

2
Ve bir kez daha geri vereyim: eğer prog2stdout'a yazarsa, daha iyidir , çünkü formun tamamlanmasını bekler (yani, kabuk bir sonraki istemi vermeden veya bir sonraki komuta geçmeden önce (örn. Veya sonra )) -siz form sadece tamamlanmasını bekler . Ayrıca, formdan sonra çıkış durumu , diğerinde ise çıkış durumu olur . (Paranızı prog1 input_file >( cat ) | prog2prog1 input_file >( prog2 )catprog2;&&catprog1cat$?prog2$?prog1
Scott

4

Kabuğunuz onları destekliyorsa, bu tür manipülasyonları yapmanın en basit yolu işlem ikamesini kullanmak olacaktır : <(…)ve >(…). Bu, bash, zsh ve ksh ve muhtemelen diğer kabuklarda çalışır. Örneğin:

$ sort <(printf "b\nc\na\n")
a
b
c
$ ls
foo
$ cp <(find . -name foo) bar
$ ls
bar  foo

Ancak, pdftotextbir metin dosyasına kaydedileceği için belirttiğiniz örnekte bu yardımcı olmaz . @TiCPU tarafından önerilen -şekilde kullanmak için en iyi seçiminiz (açık olanın dışında ) kullanmak /dev/stdoutolsa da, başka bir kabuk özelliğini de kullanabilirsiniz. Yapı !:N, önceki komutun N'inci argümanını ifade eder. Bu nedenle şunları yapabilirsiniz:

$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"  out.txt
$ cat !:2

1
cat <()Bazı durumlarda bunun yararlı olabileceğini kabul etsem de , bu senaryoda hiç çalışmıyor. Sorun (OP tarafından çok kötü tarif, itiraf etmeliyim) pdftotextiki argüman alır: giriş dosyası ve çıkış dosyası . İkinci argüman eksikse hiçbir şey üretmez, bu yüzden cat <(pdftotext "file.pdf")hiçbir şey döndürmez. Digital Trauma'nın yanıtladığı gibi ikinci bir argüman olarak pdftotextkomut hile yapabilir >(cat), ancak cat <()burada anlamsızdır. Açıkçası, pdftotextsadece -çıktı dosyası adı olarak kullanmak en iyisidir .
jimmij

1
@Scott Cevabım UUOC nasıl? Bu işlem ikamesini kedi olmadan nasıl yapardınız? >( )akışı içerideki tüm işlemlere etkili bir şekilde aktaracak - bu yüzden aslında catbu akışı çıkarmak için bir buraya ihtiyacımız var. Normalde böyle bir şey yapabilmeliyiz pdftotext input.pdf -, ancak görünüşe göre bir dosya yerine doğrudan stdout'a çıkış parametresini pdftotextdesteklemiyor -- deneyin.
Dijital Travma

1
@DigitalTrauma uuoc değil. İnanıyorum ki kedi sadece baskı durumunda alabileceğiniz en hızlı şeydir, ama aslında diğer komutları >(grep something)daha kullanışlı olarak kullanabilirsiniz. BTW, benim pdftotext 3.04 do destek -ım'öylesine bir çıkış dosyası olarak, biraz bütün tartışma sürpriz.
jimmij

1
@terdon Yapışkan olmaktan nefret ediyorum, ama bu işe yaramıyor. Özellikle pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf", çıktıyı denilen bir dosyaya koyan çalışandan farklı değildir C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt, ancak metnin hiçbiri başka bir programa borulama için STDOUT'a gönderilmez.
Dijital Travma

1
@DijitalTrauma, bir yapışkan olmuyor! Bu benim aptal olmak. İşaret ettiğiniz için teşekkür ederiz ve lütfen hataları işaret ederken asla özür dilemeyin. Benim hatamın bana işaret etmesini tercih ederim ve bu yüzden tüm şüpheli ihtişamıyla orada bırakmaktan daha fazla bir şey öğrenin.
terdon

-2
cmd tty

ttybağlı olan terminalin adını döndürür stdout.


Bunun komutları birleştirmeyle ilgili soruyu nasıl cevapladığından emin değilim; belki bunu nasıl başaracağınıza dair bir örnekle genişlersiniz.
dhag

Sanırım ttyterminalin adını kontrol etmeyi ve sonra bu dosyayı çıktı olarak kullanmayı söylüyorsunuz pdftotext file.pdf /dev/pts/2. Bu durumda katılıyorum.
jimmij

Bu kısaltılabilir / otomatikleştirilebilir ; Bu genellikle eşittir . Ama bu yaklaşım amaç çıkışını görüntülemek için olduğunu varsayar (terminalde yani) ve bu soruya (bkz soruyor ne değildir bir yorum üzerine Terdon cevabı sorunun anlam bazı açıklamalar). prog1  input_file $(tty)prog1  input_file /dev/ttyprog1
Scott
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.