Bagaimana perintah ini legal? “> File1 <file2 cat”

61

Anggap file2sudah ada, perintahnya

> file1 < file2 cat

tampaknya menyalin konten file2ke file1.

Tetapi saya tidak dapat memahami struktur ini.

Saya mengerti bahwa "Tidak Ada" sedang diarahkan file1, (membuat atau menghapus kontennya). Kemudian konten file2diarahkan ke file1.

Kenapa catsetelah file2? bagaimana ia tahu cat file2jika operan tidak dalam urutan yang benar?

shaqed
sumber
11
Apa "urutan yang benar"? Bisakah Anda memberikan tautan ke beberapa materi sumber daya / pembelajaran di mana "urutan yang benar" dijelaskan?
Lightness Races dengan Monica
7
Saat mengajukan pertanyaan seperti ini, Anda harus menentukan shell; yang berbeda memiliki kasus tepi yang berbeda, terutama di sekitar pengalihan.
chrylis -on strike-

Jawaban:

117

Sebelum shell mengeksekusi catperintah pada baris perintah, shell mencari pengalihan.

Ada dua pengalihan:

  1. >file1 Ini akan membuat output standar perintah pergi ke file1.
  2. <file2 Ini akan membuat input standar perintah berasal file2.

Fakta bahwa pengalihan ini ditempatkan di lokasi miring pada baris perintah tidak masalah.

$ cat <file2 >file1

sama dengan

$ <file2 cat >file1

yang sama dengan

$ <file2 >file1 cat

dll

Perhatikan bahwa catutilitas dalam semua instance ini dijalankan tanpa argumen baris perintah . Pengalihan bukan operan ke catperintah, itu adalah instruksi ke shell untuk mengatur pengalihan masuk dan keluar dari perintah (menghubungkan input dan output standar ke file). Shell mengatur pengalihan sebelum menjalankan perintah.

Perbedaan antara cat filedan cat <file(atau, jika Anda mau, <file cat) adalah bahwa dalam kasus pertama, catutilitas itu sendiri membuka file, yang diberikan sebagai operan pada baris perintah, untuk membaca, sedangkan dalam kasus kedua, shell akan buka file dan hubungkan cataliran input ke sana². Dalam kasus kedua, catakan melihat itu tidak diberikan file operan dan secara otomatis akan beralih ke membaca dari input standarnya. Ini adalah fitur cat, dan beberapa utilitas lain, bukan sesuatu yang dilakukan semua utilitas.

catjuga akan membaca dari input standarnya jika diberi operan -. Sekali lagi, ini hanya khusus untuk catdan untuk beberapa utilitas lain (yaitu tidak ada yang shell lakukan). Untuk menggunakan catpada file dalam direktori saat ini yang namanya adalah - , tambahkan jalan untuk nama file, seperti ./-.

¹ Urutan pengalihan masih penting dalam beberapa keadaan; Dengan cat <file2 >file1, misalnya, file1tidak akan terpotong jika file2tidak dapat diakses (pengalihan diurai dari kiri ke kanan). Namun, penempatan relatif kata cattersebut masih arbitrer dan tidak akan memengaruhi ini.

² Lihat juga pertanyaan " cat memberikan kesalahan berbeda saat membuka file yang tidak ada ".


Fakta bahwa shell mengatur pengalihan bahkan sebelum mengeksekusi perintah pada baris perintah adalah mengapa hal-hal seperti ini gagal dan Anda berakhir dengan file output kosong:

$ sort file >file

Di sini, shell akan memotong (mengosongkan) file filesebelum mengeksekusi sort filedan menghubungkan sortoutput standar ke file. The sortutilitas maka akan membuka filedan menyortir isinya (yang ada). Hasilnya (tidak ada) dilewatkan melalui aliran output standar ke file.

Obat dalam kasus khusus ini (untuk menyortir file "di tempat") adalah

$ sort -o file file

atau

$ sort file >file.sorted && mv file.sorted file

yang lebih atau kurang apa yang sortdilakukan saat menggunakan -ofile untuk menentukan nama file output.


Hanya untuk mendukung pernyataan bahwa pengalihan dapat mendahului nama sebenarnya dari utilitas pada baris perintah:

"Perintah sederhana" adalah urutan penugasan dan pengarahan variabel opsional, dalam urutan apa pun, secara opsional diikuti oleh kata-kata dan pengalihan, diakhiri oleh operator kontrol. [ref: POSIX Shell Command Language 2.9.1 Perintah Sederhana]

Dan juga tentang pengalihan bukan menjadi bagian dari operan utilitas:

Nomor opsional, operator pengalihan, dan kata tidak akan muncul dalam argumen yang disediakan untuk perintah yang akan dieksekusi (jika ada). [ref: POSIX Shell Command Language 2.7 Redirection]

Kusalananda
sumber
14
@Steve Kebebasan untuk memindahkan pengalihan dapat digunakan untuk membuat beberapa perintah lebih jelas, seperti pipa dengan pengalihan input di awal <in foo | bar >outmenempatkan semuanya dalam urutan logis. Saya juga suka jika echo >&2 Something bad happeneduntuk output kesalahan dari skrip shell. Tetapi >out <in cathanya kebingungan
2
Bagaimana mungkin sort file >filedicapai dengan benar?
seth10
11
@setht Dengan sort -o file file.
Kusalananda
6
Jawaban yang bagus Perhatikan bahwa pesanan penting. < file1 > file2 catakan lebih baik daripada > file2 < file1 catitu akan menghindari file2terpotong jika file1tidak bisa dibuka.
Stéphane Chazelas
3
Sesuatu yang perlu diperhatikan: saat menautkan ke POSIX dengan fragmen HTML, lebih baik untuk menentukan edisi yang tepat (seperti pubs.opengroup.org/onlinepubs/9699919799.2016edition ) karena fragmen telah diketahui berubah di antara edisi dari revisi yang sama dengan spesifikasi. (banyak tautan dalam jawaban di situs ini termasuk milik saya sekarang salah karena titik fragmen di tempat yang salah setelah edisi 2016 dirilis).
Stéphane Chazelas