Як я можу визначити, чи був запущений в даний час скрипт bash з -x для налагодження?


11

У мене є сценарій, launch.shякий виконує себе як інший користувач, щоб створити файли з правильним власником. Я хочу передати -x до цього виклику, якщо він був спочатку переданий до сценарію

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

Я прочитав сторінку налагодження bash, але, здається, немає чіткого варіанту, який би визначав, чи був запущений оригінальний сценарій -x.

Відповіді:


15

Багато прапорів, на які можна передати bashкомандний рядок, є setпрапорами. setце вбудована оболонка, яка може перемикати ці прапори під час виконання. Наприклад, виклик сценарію як bash -x foo.shтакий же, як і виконання set -xу верхній частині сценарію.

Знаючи, що setсаме вбудована оболонка відповідає за це, дає нам знати, де шукати. Тепер ми можемо зробити, help setі ми отримаємо наступне:

$ 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.
...

Тож із цього ми бачимо, що $-має говорити про те, які прапори включені.

$ bash -c 'echo $-'
hBc

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

Тому в основному вам просто потрібно зробити:

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

Як бонус, якщо ви хочете скопіювати всі прапори, ви також можете це зробити

bash -$- /other/script.sh

1
Вам потрібно буде скористатися [[ $- == *x* ]]для відповідності шаблонів.
glenn jackman

1
Або ви могли використовувати стандарт case $- in *x*) ... ;; *) ... ;; esac. Корисно знати це використання caseдля скриптів, які призначені для переносу, і тепер, коли я знаю про це, мені стає легше просто запам'ятати це, ніж запам’ятовувати «якщо баш-специфічний, то [[, інше case».
hvd

Добре, тоді всю цю серію коментарів можна було б видалити.
l0b0

$-виходи hB. Що роблять -hта -Bпрапори / аргументи? Не бачимо тоді на сторінці " bash man" .
Дан Даскалеску

3

set -oвиведе, xtrace onякщо -xвикористовується, в іншому випадку xtrace off.


2

Хоча відповідь @Patrick є "правильною", ви також можете просто передати параметр або експортовану змінну у свій дочірній скрипт, який підкаже, що робити, як увімкнути трасування.

Це має той недолік, що (я вважаю) вам доведеться реекспортувати його на кожен рівень сценарію, який ви збираєтеся ввести.

Вона має перевагу в тому, що можна вибірково відстежувати (або впливати іншим чином) лише сценарій (и), на який потрібна вихідна / модифікована поведінка, - щоб скоротити сторонній вихід та ін. все ще вмикається у названому сценарії. Це не все або нічого пропозиція.

Не входить у ваше запитання, але пов’язане з цим:

Я інколи визначаю подібну змінну

E=""
E="echo "

або

E=""
E=": "

і використовувати його (у кількох висловлюваннях), як

"${E}" rsync ...

або, лише для другого варіанту,

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

Тоді я просто коментую друге визначення, коли хочу, щоб команда (команда) виконувалася. Ви також можете використовувати цю техніку з параметром або експортованою змінною.

З будь-яким із них ви повинні стежити за складеними висловлюваннями, оскільки метод гарантовано працює лише над першим твердженням у списку складених елементів.


1

Ви можете схопити PID процесу, а потім вивчити таблицю процесу з ps, щоб побачити, що це за аргументи.


Ви можете схопити процес "PID" через: $$
Пол Калабро

2
Я не думаю, що це взагалі гарна ідея, тому що якщо -xсценарій був встановлений всередині сценарію, він не відображатиметься у psвисновку. І це рішення все одно неефективне.
vinc17

Це справедливий аргумент. Я фактично не знав про змінну $. Це здається набагато кращим підходом до вирішення цього питання.
Пол Калабро

1
Також є set -oрішення, яке я запропонував. Він також повинен працювати для варіантів, які не мають асоційованого прапора типу -x.
vinc17
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.