Cara menghentikan pengalihan di bash

8

Saya menggunakan :

exec >script.log 2>&1

dalam skrip saya untuk mengarahkan semua output ke file. Di akhir skrip saya ingin mencetak pesan ke layar. Bagaimana cara menghentikan pengalihan?

Willem
sumber

Jawaban:

12

Anda dapat menelepon execlagi untuk mengembalikan penjelas asli. Anda harus menyimpannya di suatu tempat.

exec 3>&1 4>&2 1>script.log 2>&1
 logged portion 
exec 1>&3 2>&4
echo >&2 "Done"

Di dalam bagian yang dicatat, Anda dapat menggunakan deskriptor asli untuk satu perintah dengan mengarahkan kembali ke deskriptor tambahan.

echo "30 seconds remaining" >&3

Sebagai alternatif, Anda dapat meletakkan bagian log yang telah dicatat di dalam perintah gabungan dan mengarahkan ulang perintah gabungan tersebut. Ini tidak berfungsi jika Anda ingin menggunakan deskriptor asli dalam perangkap di suatu tempat di dalam bagian yang diarahkan itu.

{
 logged portion 
} >script.log 2>&1
echo >&2 "Done"
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Komentar tentang gema >&3menjadikan ini solusi pilihan saya. Terima kasih lagi)!
Willem
6

Gunakan tambahan fd 3 dan 4 untuk stdout dan stderr dan cukup arahkan 1 dan 2 ke mereka di akhir skrip Anda:

exec 3>&1 4>&2
exec >script.log 2>&1

echo "Some code"

exec >&3 2>&4
echo "Done"
buru-buru
sumber
Ini mengembalikan kesalahan:exec 3>/dev/stdout 4>/dev/stderr -bash: /dev/stdout: Permission denied
Willem
Kesalahan ini dapat terjadi ketika Anda mencoba meluncurkan skrip Anda di dalam pengguna lain. Apakah Anda menggunakan skrip Anda melalui sudo?
buru
Ya, itu dia: Saya melakukan su ke akun lain dan menjalankan kodenya. Script yang saya tulis akan dijalankan melalui sudo, jadi saya akan mengalami masalah yang sama di sana. Apakah ada alternatif?
Willem
Saya percaya ada beberapa solusi elegan, sayangnya saya tahu satu-satunya pilihan, yang mungkin benar-benar tidak dapat diterima dari sudut pandang keamanan: tambahkan pengguna target Anda ke grup utama pengguna awal Anda dan tambahkan izin menulis grup untuk / proc / self / fd / 1 sebelum peluncuran skrip. (atau bahkan lebih rentan - cukup buat izin menulis sementara untuk semua dan hapus setelah script selesai tanpa perubahan grup).
buru
1
@ Willem Ini mudah diperbaiki dengan menggunakan deskriptor file alih-alih membuka kembali file, lihat edit saya.
Gilles 'SO- stop being evil'
1

Pertama, Anda harus memeriksa apakah Anda memiliki tty atau tidak.

if tty -s; then
    echo "Hello, World" > $(tty)
fi
David Baggerman
sumber
1
Perhatikan, bahwa cara ini tidak dapat memasukkan output ke program eksternal.
buru
Tidak perlu menggunakan ttyutilitas eksternal . Anda dapat mengalihkan ke perangkat khusus /dev/tty.
Dijeda sampai pemberitahuan lebih lanjut.