Di aliran mana Bash menulis bisikannya?

8

Saya mencoba mengalihkan semua output dari bash (prompt, input pengguna, hasil) ke file

Contoh:

/bin/bash > file.txt 2>&1

Saya pikir itu akan berhasil, tetapi saya tidak mendapatkan prompt. Adakah yang bisa memberitahu saya apa yang saya lakukan salah?

Gilles 'SANGAT berhenti menjadi jahat'
sumber

Jawaban:

9

Bash menampilkan prompt hanya dalam mode interaktif. Yaitu biasanya output ke terminal (/ dev / tty di linux). Itu bukan / dev / stdout atau / dev / stdin :)

Sekarang, saya tidak yakin tetapi saya bisa membayangkan bahwa bash akan memungkinkan mode interaktif terbatas ketika tidak ada tty yang berfungsi penuh. Dalam hal ini saya berharap prompt akan ditulis ke stdout. Saya belum mengujinya.

Bukti Konsep:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

hanya akan menampilkan 1..10 seolah-olah tidak ada redirection. Seperti prompt, output langsung dikirim ke terminal (yang akan gagal jika tidak ada)

PETUNJUK: jika Anda ingin semuanya dikumpulkan lihatlah

lihat
sumber
Petunjuk tambahan tentang cara berpotensi mendapatkan lebih banyak bash output ke dalam pipa
sehe
seqadalah perintah eksternal yang sangat tidak standar, dan tidak boleh digunakan dengan cara ini. Jika Anda menggunakan bash, lakukan sesuatu seperti for x in {1..10}, atau for ((x=1; x<=10; x++))sebagai gantinya.
Chris Down
@ Chris: poin yang bagus, terima kasih untuk kepala Anda
sehe
2

Untuk mengelabui bashberpikir itu dalam mode interaktif (meskipun stdouttidak dikirim ke terminal), Anda dapat menggunakan perintah yang sudah disebutkan script.

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)

sumber
2

Cara paling sederhana untuk melakukannya adalah

bash -i >/tmp/logfile 2>&1

Bash akan menulis semuanya /tmp/logfiledan terus menjalankan perintah saat Anda mengetiknya, tetapi tidak ada yang ditampilkan di terminal. Anda dapat keluar saat Anda keluar dari sesi terminal - dengan menekan Ctrl+ Datau mengetik exit.

Perhatikan bahwa jika Anda menjalankan hal yang sama tanpa stderrpengalihan, Anda hanya akan memiliki pesan ucapan yang dicatat ke file, semua sisanya akan bekerja di terminal Anda saat ini. Jadi jawaban untuk pertanyaan Anda tentang aliran yang bash menampilkan promptnya (dan semua perintah berikut) tampaknya: stderr .

Oh ya, dan -iparameternya hanya memaksa bash untuk berjalan dalam mode interaktif. Jangan dengarkan orang-orang itu - Anda tidak perlu trik sulap untuk melakukan itu;)

rozcietrzewiacz
sumber
+1 untuk penggunaan <sub>format. Saya baru belajar sesuatu yang baru hari ini. : D
Chris K
2

Prompt ditulis ke stderr ketika truss (pada Solaris di sini) menunjukkan:

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2
Jlliagre
sumber