Можно ли написать команду, которая запустится my.sh
ирекурсивно выводит каждый путь, полученный или выполненный этим скриптом- То есть,без изменения исходного кодавообще? Идея состоит в том, чтобы проверить, какие файлы фактически используются для определенного пути выполнения, без трудоемкой и подверженной ошибкам ручной трассировки.
Например:
$ > my.sh cat <<'EOF'
#!/bin/sh
. ./foo.sh
EOF
$ > foo.sh cat <<'EOF'
#!/bin/sh
./bar.sh
EOF
$ > bar.sh cat <<'EOF'
#!/bin/sh
echo bar
EOF
$ chmod u+x my.sh bar.sh
$ magic command
[...]
./my.sh
./foo.sh
./bar.sh
решение1
Кажется, это срабатывает:
$ strace -fe open ./my.sh 2>&1 >/dev/null | \
grep --only-matching '^\(\[pid\s\+[0-9]*\] \)\?open("[^"]\+' | \
grep --only-matching '".*' | \
cut --characters 2-
Другими словами, отследите выполнение и выведите open
вызовы, поменяйте местами stdout и stderr, затем отформатируйте результат, чтобы удалить ненужный текст.
Он также выводит некоторые пути к библиотекам, что на самом деле не является большой проблемой:
/etc/ld.so.cache
/lib/x86_64-linux-gnu/libc.so.6
./my.sh
./foo.sh
/etc/ld.so.cache
/lib/x86_64-linux-gnu/libc.so.6
./bar.sh
Остались еще несколько вопросов:
- Есть ли способ надежно различать пути к оболочке и библиотеке? Последнее, похоже, возможно, поскольку все ссылки на библиотеки используют
O_CLOEXEC
опция, в то время как ни одна из ссылок на оболочку этого не делает. - Можно ли отличить исходные и выполненные пути?
- Существуют ли очевидные случаи, когда эта команда не сработает?