Katakanlah ada program, yang membutuhkan dua argumen; file input dan file output.
Bagaimana jika saya tidak ingin menyimpan file output ini ke disk, melainkan meneruskannya langsung ke stdin
program lain. Apakah ada cara untuk mencapai ini?
Banyak perintah yang saya temui di Linux memberikan opsi untuk meneruskan '-' sebagai argumen file output, yang melakukan apa yang saya tentukan di atas. Apakah ini karena melewatkan stdin
program sebagai argumen tidak mungkin? Jika ya, bagaimana kita melakukannya?
Contoh bagaimana saya akan menggunakan gambar ini adalah:
pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)
Shell yang saya gunakan adalah bash.
bash
io-redirection
arguments
Dziugas
sumber
sumber
cat <file | cmd /dev/fd/0
bekerja pada sebagian besar unix.cat < README.txt | cp /dev/fd/0
. Dikatakancp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
program input-file /dev/stdout | another-program
? Perhatikan juga bahwaecho
tidak membaca apa pun dari stdin.cp
file di mana pun.echo 1 2 3| cp /dev/fd/0 /dev/tty
akan dicetak1 2 3
. Dan omong-omong,/dev/fd/[num]
lebih cenderung bekerja daripada/dev/std(in|out|err)
dalam kebanyakan kasus. Lihat Portabilitas Link Deskriptor File tentang apa yang dapat Anda harapkan untuk bekerja di mana.Jawaban:
Jika program mendukung penulisan ke deskriptor file apa pun meskipun tidak dapat dicari, Anda dapat menggunakan
/dev/stdout
sebagai file output. Ini adalah tautan ke/proc/self/fd/1
sistem saya. Deskriptor file 1 adalah stdout.sumber
pdftotext
seperti banyak (tetapi tidak semua) utilitas lain mendukung-
untuk itu juga (yang akan bekerja bahkan pada sistem yang tidak mendukung / dev / stdout, atau di mana / dev / stdout tidak berfungsi seperti yang diharapkan seperti di Linux di mana stdout tidak sebuah pipa).pdftotext file.pdf - | wc -c
Dari
pdftotext
halaman manual:Jadi dalam hal ini yang Anda butuhkan adalah:
Atau jika Anda ingin mengirim pipa ini ke STDIN dari program lain:
Menggunakan
-
sebagai pengganti nama file adalah konvensi yang diikuti banyak utilitas (termasuk pdftotext) ketika kita ingin input dari STDIN atau output ke STDOUT. Namun tidak semua utilitas mengikuti konvensi ini. Dalam hal ini cara idiomatis untuk melakukan ini di bash adalah dengan menggunakan proses substitusi :Di sini
>( )
sebagian besar berperilaku seperti file yang diteruskanmy_utility
, tetapi alih-alih menjadi file nyata, aliran dialirkan ke stdin dari proses yang terkandung, yaitu cat. Jadi di sini, teks pada akhirnya harus keluar sesuai kebutuhan.Penggunaan lonceng alarm UUOC
cat
hampir selalu mematikan di forum seperti ini. Saya berpendapat bahwa jika utilitas tidak mendukung , maka ini adalah penggunaan yang bermanfaat , meskipun jika ada cara untuk melakukan proses substitusi ini tanpa , maka saya semua telinga ;-).-
cat
cat
Namun, jika (seperti yang dinyatakan pertanyaan) tujuan akhir dari aliran adalah STDIN dari program lain, maka
cat
dapat dihilangkan:sumber
prog2
menulis ke stdout, lebih baik daripada , karena formulir menunggu untuk selesai (yaitu, sebelum shell mengeluarkan prompt berikutnya atau melanjutkan ke perintah berikutnya (misalnya, setelah atau )), sedangkan -bentuk tanpa menunggu hanya untuk menyelesaikan. Selain itu, setelah formulir, adalah status keluar dari , sedangkan, di lain, adalah status keluar dari . (Anda membayar uang Anda dan mengambil pilihan Anda.)prog1 input_file
>( cat ) |
prog2
prog1 input_file
>(
prog2
)
cat
prog2
;
&&
cat
prog1
cat
$?
prog2
$?
prog1
Jika shell Anda mendukungnya, cara paling sederhana untuk melakukan manipulasi seperti itu adalah dengan menggunakan substitusi proses :
<(…)
dan>(…)
. Ini bekerja di bash, zsh dan ksh dan mungkin shell lainnya. Sebagai contoh:Namun, ini tidak akan membantu dalam contoh yang Anda nyatakan karena
pdftotext
akan menyimpan dalam file teks. Meskipun pilihan terbaik Anda (selain dari yang sudah jelas digunakan-
) adalah untuk digunakan/dev/stdout
seperti yang disarankan oleh @TiCPU, Anda juga bisa menggunakan fitur shell lainnya. Konstruk!:N
mengacu pada argumen ke-N dari perintah sebelumnya. Karena itu, Anda dapat melakukan:sumber
cat <()
ini dapat berguna dalam beberapa situasi, namun dalam skenario ini tidak berfungsi sama sekali. Masalahnya (sangat buruk dijelaskan oleh OP, saya harus akui) adalah bahwapdftotext
dibutuhkan dua argumen: file input dan file output . Jika argumen kedua hilang maka tidak menghasilkan apa-apa, demikiancat <(pdftotext "file.pdf")
juga tidak akan mengembalikan apa pun. Seseorang dapat menipupdftotext
perintah dengan memberi>(cat)
sebagai argumen kedua seperti Digital Trauma yang dijawab, tetapicat <()
tidak ada gunanya di sini. Jelaspdftotext
kalau-kalau yang terbaik hanya digunakan-
sebagai nama file output.>( )
akan secara efektif menyalurkan aliran ke proses apa pun yang ada di dalam - jadi kami benar-benar perlu dicat
sini untuk menampilkan aliran itu. Biasanya kita harus dapat melakukan sesuatu sepertipdftotext input.pdf -
, tetapi ternyatapdftotext
tidak mendukung-
parameter untuk langsung keluaran ke stdout daripada file - coba saja.>(grep something)
agar lebih bermanfaat. BTW, dukunganpdftotext 3.04
do saya-
sebagai file output, jadi saya sedikit terkejut dengan seluruh diskusi.pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"
, yang menempatkan output dalam file yang dipanggilC BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt
, tetapi tidak ada teks yang di-output ke STDOUT untuk disalurkan ke program lain.tty
mengembalikan nama terminal yang terhubungstdout
.sumber
tty
nama terminal, dan kemudian menggunakan file itu sebagai keluaran, misalnyapdftotext file.pdf /dev/pts/2
. Dalam hal itu, saya setuju.prog1 input_file
$(tty)
prog1 input_file
/dev/tty
prog1