Bagaimana cara kerja `>` dan `>>`?

9

Saya mencoba untuk revfile dan kemudian pipa ke cat > same_filetetapi file itu berubah menjadi kosong.

Sementara saya mencoba rev file.txt | cat > file2.txt && mv file.txt file2.txt;itu berhasil.

Bahkan rev file.txt | cat >> file.txt;berhasil.

Tetapi ketika saya mencobanya rev file.txt | cat > file.txtgagal.

Vintux
sumber
Anda juga dapat meninggalkan catkeluar seperti ini: rev file.txt > file2.txt && mv file2.txt file.txt. Ini adalah penggunaan berlebihancat . Dengan membiarkannya, Anda membiarkan proses ekstra.
matega

Jawaban:

19

Hal dasar yang perlu Anda pahami dalam kasus ini antara kedua cara pengalihan (> dan >>) adalah:

>

Arahkan ulang dan timpa informasi ke tempat yang ditunjuk. Ini terjadi ketika menerima informasi apa pun melalui pipa "|"

>>

Arahkan ulang dan menyatukan informasi yang ditunjuk. Ini terjadi ketika menerima informasi apa pun melalui pipa "|"

Dalam kedua kasus jika file tidak ada, itu akan dibuat sebagai gantinya. Hanya pada ">>" informasi akan digabungkan jika Anda menjalankannya lagi pada file yang sama. Dengan ">" Anda hanya akan menimpa semua yang Anda lakukan pada jalankan pertama.

Tapi di sini adalah kesepakatan ketika menggunakan file input yang sama dengan file output. Dalam kasus khusus itu, jika Anda menggunakan ">" Anda akan menghapus informasi yang bagian "input" perlu parsing, karena file output akan "menimpa itu". Jadi di:

rev file.txt | cat > file.txt

Apa yang sebenarnya terjadi dalam "penjelasan gerak lambat" adalah:

  1. revbersiap untuk membalikkan konten file.txtdan mengirimkannya ke pipa
  2. Saat revmengirim informasi ke pipa, pipa mengalirkannya langsung ke cat.
  3. Saat catmenerima informasi, ia akan secara otomatis menerapkannya ke informasi file.txtyang telah ditentukan sebelumnya.
  4. Kata kunci di sini adalah "sementara", karena semuanya terjadi pada saat yang bersamaan. Silakan lihat komentar luar biasa di bawah ini oleh Emil untuk memiliki pemahaman yang lebih dalam pada bagian ini.
  5. cattidak akan menunggu untuk revmem-pipe seluruh file. Ini hanya akan mulai saat bagian pertama dari informasi sampai ke sana, yang berarti, tergantung pada simbol apa yang Anda gunakan, itu akan membuka koneksi file.txt.
  6. Dalam hal ini karena Anda menggunakan > alih-alih >> , shell akan memotong file output yang artinya akan membuka dan menghapus informasi file.txtsambil menunggu informasi baru untuk sampai ke sana. Dengan >> itu akan membuka koneksi dengan file.txtdan menunggu informasi baru pada baris terakhir terdeteksi.
  7. Karena informasi sudah dikosongkan file.txtdengan > , revakan mencoba melakukannya dan tidak mendapatkan apa-apa karena catmenghapus semuanya sebagai persiapan untuk informasi baru.

Jadi mengapa yang lain bekerja setelah membaca di atas. Karena ini:

rev file.txt | cat > file2.txt && mv file.txt file2.txt

Di sini Anda mengirim piping ke kucing yang mengirimkan informasi ke file lain . Dalam hal ini, file input yang diproses file.txttidak sama dengan file output file2.txt. Setelah itu Anda benar-benar Timpa seluruh file2.txtdengan file.txt, sehingga semua proses yang dilakukan oleh cattelah dihapus. Pada dasarnya seluruh baris dapat disederhanakan seperti cp file.txt file2.txtkarena ia melakukan hal yang sama karena file2.txtpada akhirnya kehilangan revdan ditimpa dengan mvperintah.

rev file.txt | cat >> file.txt

Dalam hal ini Anda menggabungkan informasi ke file yang sama. Jadi itu hanya membuka koneksi ke file itu tetapi tidak menghapus informasi seperti yang terlihat dengan satu > . Hasil akhirnya seharusnya, informasi asli ditambah informasi terbalik.

Luis Alvarado
sumber
5
File tidak terpotong oleh cat. Itu terpotong oleh shell, bahkan sebelum salah satu perintah dalam pipeline dimulai.
Emil Jeřábek
Benar, sedang mencari kata-kata yang lebih mudah untuk dijelaskan. Karena agak sulit untuk menjelaskan jika OP tidak tahu apa itu shell dan semua itu. Mencoba menjadikannya "seramah" mungkin.
Luis Alvarado
1
Yah, tidak masalah bahwa itu dilakukan oleh shell, tetapi bahwa waktu yang Anda berikan salah. Pemotongan tidak akan terjadi di langkah 6, tetapi di langkah 0. rev file.txt | cat --bogus-option > file.txtjuga akan memotong file, meskipun kucing tidak akan berusaha membukanya.
Emil Jeřábek
@ EmilJeřábek Anda benar. Masih pengguna yang tidak tahu bagaimana perilakunya akan lebih mudah jika kita langkah demi langkah hanya dengan perintah. Contoh Anda juga masih mengirimkan informasi ke file yang sama, jadi bash akan membaca seluruh baris itu, melihat hasilnya dan masih terbuka DAN memotongnya. Kesalahannya hanyalah stderr keluaran ke stdout.
Luis Alvarado
4
Lihat juga moreutils , koleksi alat yang fantastis (tersedia dari repositori paket sebagai moreutils) yang mencakup sponge, alat yang dirancang khusus untuk penggunaan file yang ditimpa oleh file input. Misalnya, rev file.txt >file2.txt && mv file2.txt file.txtsolusi akan menjadi rev file.txt | sponge file.txt, yang akan bekerja dengan benar bahkan ketika sudah ada sesuatu yang dinamai file2.txt.
Daniel Wagner
9

Ketika shell melihat pengalihan, itu membuka file yang relevan terlebih dahulu, sebelum menjalankan salah satu perintah yang terlibat. Jadi, ketika Anda melakukannya:

foo file.txt | bar > file.txt

Pengalihan ke file.txtmenyebabkannya terpotong sebelum foo dijalankan dan dapat membaca file.txt. Di samping catatan, inilah sebabnya Anda tidak dapat melakukan:

sed 'blah' file.txt > file.txt

Dan mengapa sedmemiliki opsi pengeditan di tempat.

Terakhir, melakukan:

.. | cat > file.txt

adalah penggunaan kucing yang tidak berguna , terutama jika Anda mencoba membaca dari file.txtawal.

Jika Anda ingin membalikkan file di tempat, tidak ada pintasan . Anda mungkin dapat menggunakan sedatau awktrik dengan pengeditan di tempat.

muru
sumber
3

>adalah redirector (operator) mengirimkan output ke sesuatu yang lain
(input dari perintah berikutnya, printer ..)

Dalam kasus Anda, outputnya masuk ke file file.txt, jika file ini sudah ada itu ditimpa, jika tidak dibuat.

>>adalah operator append, jika file.txtsudah ada output ditambahkan ke akhir file. jika file tidak ada itu dibuat, dan output ditulis ke file baru, sama seperti >(redirector).

Ken Mollerup
sumber
OP tampaknya memahami ini. Kebingungan tampaknya berasal hanya dari file yang sama berada di kedua sisi >dan >>operator.
bzlm
0

Anda dapat menggunakan Vim dalam mode Ex:

ex -sc '%!rev' -cx file.txt
  1. % pilih semua baris

  2. ! jalankan perintah

  3. x Simpan dan tutup

Steven Penny
sumber