Saya memiliki skrip yang mengukur berapa lama beberapa perintah dijalankan.
Dibutuhkan perintah "real" time
, artinya, biner misalnya dalam /usr/bin/time
(karena bash-built-in tidak memiliki -f
flag).
Di bawah ini, skrip yang disederhanakan yang dapat di-debug:
#!/bin/bash
TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}')
echo ABC--$TIMESEC--DEF
if [ "$TIMESEC" -eq 0 ] ; then
echo "we are here!"
fi
Simpan sebagai "test.sh" dan jalankan:
$ bash test.sh
ABC--0--DEF
we are here!
Jadi itu berhasil.
Sekarang, mari kita coba debug ini dengan menambahkan "-x" ke bash command line:
$ bash -x test.sh
++ echo blah
++ awk -F. '{print $1}'
+ TIMESEC='++ /usr/bin/time -f %e grep blah
0'
+ echo ABC--++ /usr/bin/time -f %e grep blah 0--DEF
ABC--++ /usr/bin/time -f %e grep blah 0--DEF
+ '[' '++ /usr/bin/time -f %e grep blah
0' -eq 0 ']'
test.sh: line 10: [: ++ /usr/bin/time -f %e grep blah
0: integer expression expected
Mengapa skrip ini rusak ketika kita menggunakan "-x", dan berfungsi dengan baik tanpa itu?
bash
shell-script
Tomasz Chmielewski
sumber
sumber
-x
pada, bahwa$()
konstruksinya mendapatkan-x
output termasuk sebagai bagian dari nilai yang dihasilkan. Tidak tahu apakah itu perilaku "yang diharapkan" atau bug ... Atau mungkin itu adalah subkulit()
di dalam yang sebenarnya memberikan-x
output.BASH_XTRACEFD
memungkinkan Anda mengarahkanset -x
output ke suatu tempat yang lebih mudah.Jawaban:
Masalahnya adalah baris ini:
di mana Anda mengarahkan kesalahan standar agar sesuai dengan output standar. bash sedang menulis pesan jejaknya ke kesalahan standar, dan (misalnya) menggunakan built-in
echo
bersama dengan shell konstruksi lainnya semua dalam proses bash.Jika Anda mengubahnya menjadi sesuatu seperti
itu akan mengatasi masalah itu, dan mungkin kompromi yang dapat diterima antara melacak dan bekerja:
sumber
Anda juga bisa langsung melepas subshell. rupanya itu adalah cangkang bersarang yang akhirnya mengecewakan satu sama lain:
Jika kamu melakukan:
... Anda berakhir dengan subkulit yang diluncurkan untuk menangani bagian pipa yang menampung subkulit di dalamnya. Karena shell tanpa arahan ulang bahkan hasil debug dari subkulit di dalam (seperti yang juga akan dilakukan untuk semua jenis
{
perintah majemuk; } >redirect
yang mungkin Anda pilih untuk digunakan) ke bagian pipeline Anda berakhir mencampur aliran. Itu ada hubungannya dengan urutan pengalihan.Sebaliknya, jika Anda hanya mengarahkan ulang hanya output kesalahan dari perintah yang Anda coba ukur, dan biarkan output shell host membuatnya menjadi stderr, Anda tidak berakhir dengan masalah yang sama.
dan sebagainya...
... shell host bebas untuk terus menulis stderrnya di tempat yang diinginkannya sementara hanya mengarahkan output dari perintah yang dipanggilnya ke dalam pipa.
Untuk hal tersebut...
sumber