Переменная окружения Bash, эквивалентная -x? - PullRequest
4 голосов
/ 05 октября 2011

У меня есть куча сценариев, которые я отлаживаю, все они вложенные и довольно неприятные.

Просто интересно, могу ли я установить какую-то переменную окружения, эквивалентную опции -x для bash.Это сэкономит мне невероятное количество времени.

Я искал ответ, но, кажется, его не существует - надеясь, что вы, умные люди, сможете предложить совет или, возможно, альтернативное решение.

Спасибо!

Ответы [ 2 ]

8 голосов
/ 05 октября 2011

Поскольку вам кажется, что вы в тяжелом положении, я предложу несколько ужасных вариантов (и один вариант, который звучит ужасно, но не так уж и плохо).

Первый выбор: использовать другой инструмент. strace(1) и ltrace(1) могут дать удивительный массив информации - хотя никто не понимает ничего о переменных оболочки, они покажут , как сценарии взаимодействуют с остальной частью системы и некоторыми из них. внутренние состояния программы. Это может быть достаточно хорошо. (Если вы новичок в strace(1), попробуйте strace -f -o /tmp/foo ./program - он будет следовать вызовам fork(2), vfork(2) и clone(2), поэтому дочерние процессы также отслеживаются и выводятся. Вывод идет на /tmp/foo .)

Второй вариант: замените все #!/bin/bash на #!/bin/bash -x во всех ваших сценариях:

find . -type f -print0 | xargs -0 sed -i -e 's/^#!\/bin\/bash$/#!\/bin\/bash -x/'

Возможно, есть лучший механизм для замены строки shebang во всех ваших сценариях, но с этим все в порядке. Он пропустит все варианты использования system(3), popen(3) и т. Д. В программах на C, вызываемых через ваши скрипты, но это может быть просто замечательно. Если какие-либо сценарии основаны на аргументах /bin/bash, вам может потребоваться больше усилий, чтобы правильно добавить -x.

Самый последний выбор: запустить sash(1) оболочку от имени пользователя root. Скопируйте /bin/bash в /bin/real.bash. Напишите быстро-грязную C-программу, которая добавит -x к аргументам командной строки в /bin/real.bash, а поместит ее в /bin/bash. Это получит все : каждый system(3), каждый popen(3), каждый скрипт инициализации, все задания cron, все логины пользователей, все.

Вы могли бы немного изменить этот последний выбор; ядро Linux предоставляет частные пространства имен для каждого процесса, которые можно использовать, чтобы сделать новый /bin/bash видимым только для потомков данного процесса. Это немного сложнее ...

  1. Сделайте копию bash: cp /bin/bash /bin/real.bash
  2. Напишите свою обертку C, чтобы добавить -x к аргументам командной строки и вызвать /bin/real.bash. (Давайте назовем это /bin/wrapper.bash.)
  3. Сделать / крепление shared: mount --make-shared /
  4. Создать новое пространство имен файловой системы: unshare --mount bash
  5. В пределах новых bash, сделайте / рабами: mount --make-slave /
  6. В пределах new bash, закрепите замену bash: mount -B /bin/wrapper.bash /bin/bash
  7. В new bash запустите сценарии оболочки. Все они будут перенаправлены на ваш упаковщик. Процессы, не произошедшие от new bash, продолжат использовать "реальный" /bin/bash, который остался неизменным.

Когда умирает последний (великий) * дочерний процесс, закрываются пространство имен и забавное монтирование привязки.

Результатом всего этого забавного дела является то, что все ваши сценарии оболочки остаются неизменными, и вы можете использовать инструмент отладки, который вы считаете наиболее полезным. Если вы правильно прищурите глаза, это не будет слишком навязчиво.

Я выполнил многие из этих шагов на своей рабочей станции (за исключением того, что вместо этого использовал --make-rshared и --make-rslave и проверил с /bin/dir и /bin/ls вместо /bin/bash), и проверил номера инодов с помощью ls -li /bin/dir /bin/ls из оболочек в новом пространстве имен и вне нового пространства имен, а процессы вне пространства имен продолжали видеть, что номера инодов остаются неизменными, но процессы в пространстве имен видели dir и ls, разделяющие номера инодов.

Для получения полной информации о пространствах имен, личных монтированиях и монтированиях связывания, я рекомендую прочитать файл Documentation/filesystems/sharedsubtree.txt из дерева исходных кодов ядра, страницу руководства clone(2), страницу руководства unshare(1) и справочную страницу mount(8).

При перезагрузке системы привязные крепления исчезают, поэтому вы ничего не можете испортить слишком сильно. :)

2 голосов
/ 05 октября 2011

Нет, она не контролируется переменной окружения, но вы можете сделать set -x там, где вам нужно, и set +x, чтобы выключить ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...