Поскольку вам кажется, что вы в тяжелом положении, я предложу несколько ужасных вариантов (и один вариант, который звучит ужасно, но не так уж и плохо).
Первый выбор: использовать другой инструмент. 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
видимым только для потомков данного процесса. Это немного сложнее ...
- Сделайте копию
bash
: cp /bin/bash /bin/real.bash
- Напишите свою обертку C, чтобы добавить
-x
к аргументам командной строки и вызвать /bin/real.bash
. (Давайте назовем это /bin/wrapper.bash
.)
- Сделать
/
крепление shared
: mount --make-shared /
- Создать новое пространство имен файловой системы:
unshare --mount bash
- В пределах новых
bash
, сделайте /
рабами: mount --make-slave /
- В пределах new
bash
, закрепите замену bash
: mount -B /bin/wrapper.bash /bin/bash
- В 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)
.
При перезагрузке системы привязные крепления исчезают, поэтому вы ничего не можете испортить слишком сильно. :)