Output langsung dari perintah ke file termasuk perintah asli, DAN cetak di terminal

8

Saat menjalankan beberapa tes, saya perlu menjalankan serangkaian perintah. Ini akan sangat berguna bagi saya, dan menghemat banyak waktu, jika ada cara untuk melakukan semua hal ini:

  • Jalankan perintah yang harus saya jalankan
  • Redirect semua output dari perintah ke file yang ditentukan
  • Sertakan perintah asli dalam file yang ditentukan
  • Cetak output dari perintah asli di terminal

Orang-orang menyarankan menggunakan tee kepada saya yang melakukan pekerjaan mencetak dengan baik ke terminal serta mengirim ke file tetapi tidak termasuk perintah asli. Yang ingin saya akhiri adalah file di mana baris pertama adalah perintah yang saya jalankan, dan kemudian di bawahnya adalah output dari perintah.

Seseorang menyarankan ini:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Tapi ini tidak bisa mencetak output di terminal atau memasukkan perintah asli dalam file.

Saya menghargai ide apa pun.

shaneoh
sumber
2
Hampir duplikat dari askubuntu.com/q/688498/295286 .
Sergiy Kolodyazhnyy
Saya tidak menemukan ini dalam pencarian saya - tidak persis sama, tetapi mungkin akan mengarahkan saya ke jawabannya.
shaneoh
ya, dan inilah sebabnya saya mengatakan hampir duplikat. Tapi jujur ​​saja dengan pendapat saya, Anda bisa mengambil hampir semua solusi dari sana, dan memanfaatkannya dengan perpipaan tee.
Sergiy Kolodyazhnyy

Jawaban:

14

Itu yang teeAnda cari.

ls -l | tee outfile

mencetak output ls -lke stdout (yaitu terminal) dan menyimpannya di file outfilepada saat yang bersamaan. Tetapi : Itu tidak menulis nama perintah untuk stdout atau ke file. Untuk mencapai itu, hanya echonama perintah sebelum menjalankan perintah dan pipa kedua output ke tee:

( echo "ls -l" && ls -l ) | tee outfile

Itu rumit untuk diketik, jadi mengapa tidak mendefinisikan suatu fungsi?

both(){ ( echo "$@" && "$@" ) | tee outfile ;}

Setelah itu Anda bisa langsung berlari

both ls -l

untuk mendapatkan hasil yang diinginkan. Masukkan fungsi Anda ~/.bashrcuntuk mendefinisikannya di setiap terminal baru.

Jika Anda ingin dapat menentukan file output sebagai argumen pertama seperti di

both output ls -l

alih-alih membuatnya:

both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}

Jika Anda tidak ingin file keluaran ditimpa tetapi ditambahkan, tambahkan -aopsi ke tee.

pencuci mulut
sumber
9

Anda dapat menggunakan scriptperintah yang akan membuat file naskah semua yang dicetak ke terminal Anda. Itu membuat shell bercabang dan akan merekam semuanya sampai shell itu keluar.

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Maka jika saya cat my_outputsaya mendapatkan output yang sama:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC
AJefferiss
sumber
6

Anda dapat menggunakan fungsi debugging shell bersama dengan tee:

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )memulai sub-shell yang memungkinkan Anda untuk "mengumpulkan" aliran output dari semua perintah yang dijalankan dalam sub-shell. Ini juga berisi efek dari setperintah di bawah ini ke sub-shell ini.

  • set -xmengaktifkan xopsi shell yang mencetak semua perintah yang dijalankan shell ke aliran kesalahan standar sebelum menjalankannya.

  • 2>&1 redirect aliran 2 (kesalahan standar) ke streaming 1 (output standar).

  • | mengalihkan aliran output standar dari perintah kiri ke aliran input standar dari perintah kanan.

  • tee FILEmenyalin aliran input standar ke file FILEdan ke output standar.

Jika urutan perintah Anda sudah ada dalam file skrip, akan lebih masuk akal untuk menjalankannya seperti ini:

bash -x /path/to/script args... 2>&1 | tee output.log
David Foerster
sumber