Saya mencoba menemukan jawaban untuk pertanyaan ini, tetapi sejauh ini tidak berhasil:
Saya memiliki skrip yang menjalankan beberapa skrip lain, dan banyak skrip lainnya memiliki "set -x" di dalamnya, yang membuat mereka mencetak setiap perintah yang mereka jalankan. Saya ingin menyingkirkan itu tetapi menyimpan informasi jika ada skrip yang mengirim pesan kesalahan ke stderr.
Jadi saya tidak bisa begitu saja menulis ./script 2>/dev/null
Selain itu, saya tidak memiliki hak istimewa untuk mengedit skrip-skrip lain itu, jadi saya tidak bisa mengubah opsi setel secara manual.
Saya sedang berpikir tentang mencatat semuanya dari stderr ke file yang terpisah dan menyaring perintah penelusuran, tapi mungkin ada cara yang lebih sederhana?
./script 2>some_file
Jawaban:
Dengan
bash
4.1 ke atas, Anda bisa melakukannya(juga berfungsi saat
bash
dipanggil sebagaish
).Pada dasarnya, kami menyuruh
bash
outputxtrace
output pada file descriptor 7 bukannya default 2, dan mengarahkan file descriptor ke/dev/null
. Nomor fd sewenang-wenang. Gunakan fd di atas 2 yang tidak digunakan dalam skrip Anda. Jika shell yang Anda masukkan perintah ini adalahbash
atauyash
, Anda bahkan dapat menggunakan angka di atas 9 (meskipun Anda dapat mengalami masalah jika deskriptor file digunakan secara internal oleh shell).Jika shell yang Anda gunakan
bash
untuk skrip ituzsh
, Anda juga dapat melakukan:untuk variabel yang secara otomatis diberikan fd gratis pertama di atas 9.
Untuk versi yang lebih lama dari
bash
, opsi lain, jikaxtrace
dihidupkan denganset -x
(sebagai lawan#! /bin/bash -x
atauset -o xtrace
) akan mendefinisikan kembaliset
sebagai fungsi yang diekspor yang tidak melakukan apa-apa ketika disahkan-x
(meskipun itu akan merusak skrip jika (ataubash
skrip lain yang diminta) digunakanset
untuk mengatur parameter posisi).Suka:
Pilihan lain adalah menambahkan perangkap DEBUG dalam
$BASH_ENV
file yang dilakukanset +x
sebelum setiap perintah.Itu tidak akan bekerja ketika
set -x
dilakukan di sub-shell.Seperti yang dikatakan @ilkkachu, asalkan Anda memiliki izin menulis ke folder apa pun di sistem file, Anda setidaknya harus dapat membuat salinan skrip dan mengeditnya.
Jika tidak ada tempat Anda dapat menulis salinan skrip, atau jika tidak nyaman membuat dan mengedit salinan baru setiap kali ada pembaruan untuk skrip asli, Anda mungkin masih dapat melakukan:
Itu (dan pendekatan penyalinan) mungkin tidak berfungsi dengan baik jika skrip melakukan sesuatu yang disukai
$0
atau variabel khusus seperti$BASH_SOURCE
(seperti mencari file yang relatif terhadap lokasi skrip itu sendiri), jadi Anda mungkin perlu melakukan beberapa pengeditan seperti ganti$0
dengan jalur skrip ...sumber
{BASH_XTRACEFD}>
trick bekerja dibash
4.1 atau lambat juga.ksh93
ataubash
bahwa variabel tidak dilewatkan di lingkungan perintah (bandingkan<shell> -c 'export fd; printenv fd {fd}> /dev/null'
dalamzsh
,bash
danksh93
). Anda dapat membuatnya bekerja dalamksh93
/bash
dengan melakukannya dalam dua langkah atau mungkin menggunakaneval
, tetapi untukbash
, itu akan memiliki efek samping jika opsi xtrace aktif.Karena itu skrip, Anda dapat membuat salinannya, dan mengeditnya.
Selain itu, memfilter output akan tampak sederhana, Anda dapat secara eksplisit mengatur
PS4
sesuatu yang lebih tidak biasa daripada satu plus, untuk membuat pemfilteran lebih mudah:(tentu saja itu akan meruntuhkan stdout dan stdin, tetapi hanya memipkan stderr di Bash menjadi sedikit berbulu, jadi saya akan mengabaikannya)
sumber
PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%')
.bash
memiliki masalah karenagrep
dijalankan secara tidak serempak (bash tidak menunggu, jadi itu bisa (dan sering kali) menghasilkan sesuatu setelah perintah berikutnya dalam skrip dimulai).