Adakah yang tahu jika kami dapat mengatakan set +x
dalam bash tanpa dicetak:
set -x
command
set +x
jejak
+ command
+ set +x
tetapi seharusnya hanya dicetak
+ command
Bash adalah Versi 4.1.10 (4). Ini mengganggu saya untuk beberapa waktu sekarang - output berantakan dengan set +x
baris yang tidak berguna , membuat fasilitas pelacakan tidak berguna seperti yang seharusnya.
script.sh 2>&1 | grep -v 'set +x'
Jawaban:
Saya memiliki masalah yang sama, dan saya dapat menemukan solusi yang tidak menggunakan subkulit:
set -x command { set +x; } 2>/dev/null
sumber
set +x
adalah perintah yang sangat suksescommand
, variasi ini adalah solusi:{ STATUS=$?; set +x; } 2>/dev/null
. Kemudian periksa$STATUS
di baris berikutnya di waktu luang Anda.{ set +x; } 2>&-
. Itu menutup fd 2 secara langsung daripada membuatnya mengarah ke / dev / null. Beberapa program tidak menanganinya dengan baik ketika mereka mencoba mencetak ke stderr, itulah sebabnya / dev / null secara umum adalah gaya yang bagus; tapiset -x
pelacakan shell menanganinya dengan baik, jadi ini bekerja dengan sempurna di sini, dan itu membuat mantera ini sedikit lebih pendek.Anda dapat menggunakan subkulit. Setelah keluar dari subkulit, setelan ke
x
akan hilang:( set -x ; command )
sumber
( set -x \n command \n )
bisa lebih buruk dariset -x \n command \n set +x
.cd
: itu tidak mengubah direktori saat ini di shell induk.Saya meretas solusi untuk ini baru-baru ini ketika saya merasa kesal dengannya:
shopt -s expand_aliases _xtrace() { case $1 in on) set -x ;; off) set +x ;; esac } alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'
Ini memungkinkan Anda untuk mengaktifkan dan menonaktifkan xtrace seperti berikut ini, di mana saya mencatat bagaimana argumen ditetapkan ke variabel:
xtrace on ARG1=$1 ARG2=$2 xtrace off
Dan Anda mendapatkan hasil yang terlihat seperti:
sumber
/dev/stdin
bagiannya). Peringatannya adalah bahwa mengaktifkan perluasan alias dalam skrip dapat memiliki efek samping yang tidak diinginkan./dev/stdin
. Saya tidak mengetahui adanya efek samping tertentu, karena lingkungan non-interaktif seharusnya tidak memuat file apa pun yang menentukan alias. Apa efek sampingnya?set +x
jauh lebih sulit (jika bukan tidak mungkin) untuk berkompromi. Tetapi ini masih merupakan solusi yang baik dan lurus - mungkin yang terbaik sejauh ini.Bagaimana dengan solusi yang didasarkan pada versi @ user108471 yang disederhanakan:
shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ set +x; } 2>/dev/null' trace_on ...stuff... trace_off
sumber
function () { set_plus_x='{ set +x; } 2>/dev/null' }
Ini adalah kombinasi dari beberapa ide yang dapat menyertakan blok kode dan mempertahankan status keluar.
#!/bin/bash shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ PREV_STATUS=$? ; set +x; } 2>/dev/null; (exit $PREV_STATUS)' trace_on echo hello trace_off echo "status: $?" trace_on (exit 56) trace_off echo "status: $?"
Saat dijalankan:
$ ./test.sh + echo hello hello status: 0 + exit 56 status: 56
sumber
()
sekitarexit
tidak perlu. Baik. Mungkin itu yang paranoid, tetapi jika kode ini digunakan secara umum Anda memiliki vektor serangan yang baik: mendefinisikan kembalitrace_on
dantrace_off
dan kode inject yang bertuliskan perintah dieksekusi. Jika Anda menggunakan "kegunaan" seperti itu saja, itu instruktif, tetapi jika kode digunakan dengan orang lain, Anda harus mempertimbangkan apakah manfaat dari fungsi non-standar tersebut lebih besar daripada kerugiannya. Secara pribadi saya telah menyelesaikan{ set +x; } 2>/dev/null
karena konstruksi ini umumnya dipahami dan juga tidak mengubah status keluar.()
sekitarexit 56
; itu hanya agar saya bisa menunjukkan bahwa status keluar dari subproses dapat diakses di skrip bash; tanpa tanda kurung, itu tidak akan menjadi subproses dan skrip akan keluar pada saat itu dengan status = 65.