Bagaimana saya bisa tahu jika skrip bash yang sedang dijalankan telah dipanggil dengan -x untuk debugging?

11

Saya memiliki skrip launch.shyang mengeksekusi dirinya sebagai pengguna lain untuk membuat file dengan pemilik yang benar. Saya ingin meneruskan -x ke doa ini jika awalnya dilewatkan ke skrip

if [ `whoami` == "deployuser" ]; then
  ... bunch of commands that need files to be created as deployuser
else
  echo "Respawning myself as the deployment user... #Inception"
  echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
  sudo -u deployuser -H bash $0 "$@"  # How to pass -x here if it was passed to the script initially?
fi

Saya telah membaca halaman debugging bash tetapi tampaknya tidak ada opsi yang jelas yang memberitahukan apakah skrip asli diluncurkan -x.

Dan Dascalescu
sumber

Jawaban:

15

Banyak flag yang dapat diteruskan ke bashbaris perintah adalah setflag. setadalah built-in shell yang dapat mengaktifkan flag-flag ini saat runtime. Misalnya, memanggil skrip seperti bash -x foo.shpada dasarnya sama dengan melakukan set -xdi bagian atas skrip.

Mengetahui bahwa setini adalah shell bawaan yang bertanggung jawab untuk hal ini membuat kami tahu ke mana harus mencari. Sekarang kita dapat melakukan help setdan kita mendapatkan yang berikut:

$ help set
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
...
      -x  Print commands and their arguments as they are executed.
...
    Using + rather than - causes these flags to be turned off.  The
    flags can also be used upon invocation of the shell.  The current
    set of flags may be found in $-.  The remaining n ARGs are positional
    parameters and are assigned, in order, to $1, $2, .. $n.  If no
    ARGs are given, all shell variables are printed.
...

Jadi dari sini kita melihat bahwa $-harus memberi tahu kita apa bendera diaktifkan.

$ bash -c 'echo $-'
hBc

$ bash -x -c 'echo $-'
+ echo hxBc
hxBc

Jadi pada dasarnya Anda hanya perlu melakukan:

if [[ "$-" = *"x"* ]]; then
  echo '`-x` is set'
else
  echo '`-x` is not set'
fi

Sebagai bonus, jika Anda ingin menyalin semua bendera, Anda juga bisa melakukannya

bash -$- /other/script.sh
Patrick
sumber
1
Anda harus menggunakan [[ $- == *x* ]]untuk pencocokan pola.
glenn jackman
1
Atau Anda bisa menggunakan standar case $- in *x*) ... ;; *) ... ;; esac. Sangat berguna untuk mengetahui penggunaan caseskrip yang dimaksudkan untuk portabel, dan sekarang saya mengetahuinya, saya merasa lebih mudah untuk hanya mengingatnya, daripada mengingat "jika spesifik bash, lalu [[, lain case".
hvd
Oke, seluruh rangkaian komentar ini bisa dihapus.
l0b0
$-output hB. Apa yang dilakukan oleh flag -hdan -Bargumen? Jangan lihat di halaman bash man .
Dan Dascalescu
3

set -oakan ditampilkan xtrace onjika -xdigunakan, jika tidak xtrace off.

vinc17
sumber
2

Meskipun jawaban @Patrick adalah jawaban yang "benar", Anda juga dapat hanya meneruskan parameter atau variabel yang diekspor ke skrip anak Anda yang memberi tahu apa yang harus dilakukan - seperti mengaktifkan penelusuran.

Ini memiliki kelemahan yaitu (saya percaya) Anda harus mengekspornya kembali ke setiap tingkat skrip yang akan Anda masuki.

Ini memiliki keuntungan karena dapat secara selektif melacak (atau memengaruhi) hanya skrip (s) yang Anda perlukan dari perilaku keluaran / modifikasi - untuk mengurangi keluaran asing, dll. Misalnya pelacakan dapat dinonaktifkan untuk skrip panggilan dan masih bisa diaktifkan dalam skrip yang dipanggil. Itu bukan proposisi semua atau tidak sama sekali.

Bukan bagian dari pertanyaan Anda, tetapi terkait:

Saya terkadang mendefinisikan variabel like

E=""
E="echo "

atau

E=""
E=": "

dan menggunakannya (dalam banyak pernyataan) seperti

"${E}" rsync ...

atau, hanya untuk variasi kedua,

"${E}" echo "this is a debugging message"

Kemudian, saya hanya mengomentari definisi kedua ketika saya ingin perintah dijalankan. Anda juga bisa menggunakan teknik ini dengan parameter atau variabel yang diekspor.

Dengan salah satu dari ini, Anda harus berhati-hati terhadap pernyataan majemuk karena metode ini hanya dijamin untuk bekerja pada pernyataan pertama dalam daftar majemuk.

Joe
sumber
1

Anda bisa mengambil PID dari proses dan kemudian memeriksa tabel proses dengan ps untuk melihat apa argumennya.

Paul Calabro
sumber
Anda dapat mengambil proses 'PID melalui: $$
Paul Calabro
2
Saya tidak berpikir itu ide yang baik secara umum, karena jika -xdiatur di dalam skrip, itu tidak akan ditampilkan dalam psoutput. Dan solusi ini tidak efisien.
vinc17
Itu argumen yang adil. Saya sebenarnya tidak tahu tentang variabel $ -. Itu sepertinya pendekatan yang jauh lebih baik untuk menyelesaikan ini.
Paul Calabro
1
Ada juga set -osolusi yang saya usulkan. Ini juga harus berfungsi untuk opsi yang tidak memiliki flag terkait -x.
vinc17