GNU/Linux >> Belajar Linux >  >> Linux

Mencoba Memahami Sintaks Pengalihan Bash Dan Outputnya?

Saya baru mengenal Linux dan mencoba memahami cara kerja pengalihan.

Saya telah menguji berbagai sintaks untuk mengarahkan ulang stdout dan stderr ke file yang sama, yang tidak semuanya menghasilkan hasil yang sama.

Misalnya, jika saya mencoba membuat daftar 2 file yang tidak ada (file1 dan file2 ) dan 2 yang melakukan (foo dan fz ):

Sintaks #1 (tanpa pengalihan):

$ ls file1 foo fz file2

Inilah output yang saya dapatkan di terminal:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo  fz

Sintaks #2:

Sekarang, dengan pengalihan:

$ ls file1 foo fz file2 > redirect 2>&1

redirect file berisi sama dengan hasil untuk Sintaks #1:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Jadi dengan kedua sintaks di atas, tampaknya shell mencetak stderr pertama, lalu stdout .

Sintaks #3:

Sekarang, jika saya mencoba dengan salah satu sintaks berikut:

$ ls file1 foo fz file2 > redirect 2> redirect

atau

$ ls file1 foo fz file2 2> redirect > redirect

Kemudian redirect file akan berisi ini:

foo
fz
nnot access file1: No such file or directory
ls: cannot access file2: No such file or directory

Di sini terlihat seperti stdout dicetak sebelum stderr , tetapi kemudian kita melihat bahwa awal stderr "dipotong" dengan jumlah karakter yang sama dengan stdout .

stdout panjangnya 6 karakter (foo fz , carriage return termasuk), jadi 6 karakter pertama dari stderr (ls: ca ) telah ditimpa oleh stdout .
Jadi sepertinya stderr dicetak terlebih dahulu, dan stdout kemudian dicetak di atas stderr bukannya ditambahkan ke dalamnya.

Namun, akan lebih masuk akal bagi saya jika stderr telah sepenuhnya dihapus dan diganti dengan stdout , bukan hanya ditipu sebagian.

Sintaks #4:

Satu-satunya cara yang saya temukan untuk memperbaiki Sintaks #3 adalah dengan menambahkan operator append ke stdout :

$ ls file1 foo fz file2 >> redirect 2> redirect

atau

$ ls file1 foo fz file2 2> redirect >> redirect

Yang menghasilkan sama dengan Sintaks #2:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Artikel ini di sini menjelaskan bahwa Sintaks #3 salah (mungkin, begitu pula Sintaks #4). Tapi demi argumen:mengapa Sintaks #3 salah? Apa sebenarnya yang dikatakannya (atau tidak mengatakan) shell yang harus dilakukan sebagai lawan dari Sintaks #2?

Terkait:Apa perbedaan antara $(…) dan `…` di Bash?

Juga, apakah ada alasan mengapa output selalu menampilkan stderr sebelum stdout ?

Terima kasih!

Jawaban yang Diterima:

Ini seperti menjalankan dua proses untuk menulis ke file yang sama pada saat yang sama…ide yang buruk. Anda berakhir dengan dua pegangan file terbuka yang berbeda dan data Anda bisa kacau (seperti yang terjadi pada # 3 di atas). Menggunakan sintaks #2 sudah benar; itu membuat satu menangani file dan mengarahkan stderr dan stdout ke tempat yang sama.

Adapun stderr selalu dicetak terlebih dahulu, tidak ada aturan tentang ini sama sekali. Saya curiga dengan ls itu karena ls perlu memeriksa setiap entri dalam direktori sebelum benar-benar dapat menyatakan bahwa file tertentu tidak ada. Jadi daripada membuat N melewati tabel direktori, itu membuat satu lintasan, memeriksa semua argumen baris perintah yang diberikan, melaporkan kesalahan, dan mencetak file yang ditemukan. Perintah lain mungkin mencetak ke stderr setelah stdout, atau bahkan bergantian di antara mereka.


Linux
  1. Cara Membuat File dan Direktori Tidak Dapat Dihapus, Bahkan Dengan Root di Linux

  2. Bekerja dengan Input Output dan Error Redirection di Linux

  3. Bagaimana Cara Mencatat Setiap Perintah yang Diketik Ke Bash Dan Setiap Operasi File?

  1. Pengalihan Io Dan Perintah Kepala?

  2. Pipes dan Redirection di Linux - Dijelaskan!

  3. Bagaimana cara mengurutkan berdasarkan ekstensi file dan kemudian nama?

  1. Skenario Waktu Nyata Linux dan masalah dengan solusinya

  2. Cara membuat perintah alias berfungsi di skrip bash atau file bashrc

  3. bash:redirect stderr ke file dan stdout + stderr ke layar