Perbedaan kinerja antara stdin dan argumen baris perintah

11

Untuk beberapa perintah, dimungkinkan untuk menentukan input tertentu sebagai stdin atau argumen baris perintah.

Secara khusus, misalkan commanddapat mengambil input stdin dan nama file sebagai argumen baris perintah, dan command < myfile, cat myfile | command dan command myfiledapat menghasilkan hasil yang sama.

Sebagai contoh,

Ketika perintahnya adalah sed:

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

Ketika perintahnya adalah cat:

cat < myfile
cat myfile
  1. Saya bertanya-tanya apakah ada beberapa aturan umum tentang penampilan mereka, yaitu mana yang biasanya paling efisien, dan yang paling tidak?
  2. Apakah pengalihan selalu lebih baik daripada pipa?
Tim
sumber
1
Saya berharap semua orang yang mengajukan pertanyaan (duplikat) ini pergi dan menulis cangkang mereka sendiri dari awal sebagai latihan.
alex
1
tolong jangan gunakan "Terima kasih!" dalam pertanyaan Anda. Pilih jawaban untuk mengekspresikan rasa terima kasih Anda.
alex
@Alex: Jika ini adalah dupe, harap tautkan ke duplikat dan kami akan berusaha untuk menutupnya. Biasanya Anda akan menahan diri untuk tidak menjawab pertanyaan yang Anda tahu adalah duplikat dan menandai untuk perhatian moderator.
Caleb
1
@alex: Di mana saya bisa belajar cara menulis shell saya sendiri?
Tim
@ Caleb: Saya yakin ini diminta seperti 2 atau 3 kali dalam sebulan terakhir, hanya saja tidak ada tautannya :-p
alex

Jawaban:

6

The cat file | commandsintaks dianggap sebagai Gunakan Useless dariCat . Dari semua opsi Anda, dibutuhkan kinerja yang baik karena harus memunculkan proses lain di kernel. Betapapun tidak signifikannya ini ternyata dalam gambaran besar, itu di atas kepala yang tidak dimiliki bentuk-bentuk lain. Ini telah dibahas pada pertanyaan seperti: Haruskah saya peduli dengan kucing yang tidak perlu?

Antara dua bentuk lainnya hampir tidak ada perbedaan kinerja. STDIN adalah simpul file khusus yang harus dibuka dan dibaca sama seperti yang lain. Melewati nama file bukannya STDIN hanya membuatnya membuka file yang berbeda.

Perbedaannya terletak pada fitur / fleksibilitas apa yang Anda cari.

  • Melewati nama file ke program berarti file input dapat dicari. Ini mungkin atau mungkin tidak penting bagi program tetapi beberapa operasi dapat dipercepat jika aliran dapat dicari.
  • Mengetahui file input aktual memungkinkan program Anda berpotensi menulis padanya. Misalnya sed -iuntuk pengeditan di tempat. (Catatan: karena ini harus membuat file baru di belakang layar, itu bukan keuntungan kinerja dari pengalihan lain tetapi itu adalah langkah yang mudah.)
  • Menggunakan pengalihan shell memberi Anda kemampuan untuk menggabungkan beberapa file atau bahkan menggunakan pengalihan proses. sed [exp] < file1 file2atau bahkan sed [exp] < <(grep command). Rincian kasus penggunaan ini dapat ditemukan pada pertanyaan ini: Proses penggantian dan pipa
Caleb
sumber
Substitusi proses harus bekerja tanpa mengharuskan Anda menyalurkan hasilnya; sed [exp] < <(grep command)akan berfungsi dengan baik sed [exp] <(grep command)(karena <(grep command)membuat file sementara bernama untuk panjang perintah yang sedbenar-benar mampu membuka sendiri tanpa bantuan shell).
ShadowRanger
2
  1. Mengingat bahwa command filehanya membuka file dan sejak saat itu berfungsi seperti jika itu stdin, ada sedikit perbedaan. Dengan pengalihan shell Anda hanya membuka file sebelumnya (shell tidak,) sebagai lawan dari perintah biner itu sendiri.

  2. Jika kita berbicara tentang cat file | commandvs. command <file, maka yang terakhir lebih disukai. Anda tidak akan melihat perbedaan kinerja yang signifikan antara keduanya, tetapi yang pertama tidak perlu rumit (proses tambahan dan buffer memori bersama untuk pipa, dengan throughput terbatas.) Juga, Anda tidak bisa seek(mengubah posisi penunjuk file secara sewenang-wenang) dalam pipa, sementara Anda bisa dalam file biasa. Beberapa perintah mungkin menggunakan algoritma yang lebih efisien ketika seekdimungkinkan dalam file input.

alex
sumber
Saya akan mengatakan bahwa file perintah lebih disukai daripada perintah <file, karena perintah mungkin melakukan semacam akses non-sekuensial.
user606723
Dan apa yang akan menghentikannya melakukannya <file? Poin Anda valid untuk menggunakan nama file input untuk mendapatkan tangguh nama file output, misalnya: gzip filemenghasilkan file.gz.
alex
mungkin saya tidak mengerti bagaimana pengalihan bekerja secara internal. Katakanlah kita mengarahkan film 12GB ke mplayer / vlc, dan kemudian kita lewati sampai akhir. Apa sebenarnya yang akan terjadi dalam kasus ini?
user606723
1
Shell membuka file dan melakukan sub-proses, yang mewarisi deskriptor file. Proses bercabang closes stdindan memanggil dupdeskriptor file yang dibuka, sehingga menggantikan yang lama stdin(yang merupakan semacam tty dalam kebanyakan kasus.) Dari sudut pandang pemain film tidak ada perbedaan antara itu dan membuka file dengan nama itu di pemain itu sendiri. Deskriptor file dapat dicari di kedua skenario, jadi ketika kita lewati sampai akhir tidak ada perbedaan yang dapat dideteksi pengguna.
alex