Ist es möglich, einen Befehl zu schreiben, der ausgeführt wird my.sh
unddruckt jeden Pfad, der von diesem Skript bezogen oder ausgeführt wird, rekursiv- Das ist,ohne den Originalcode zu verändernüberhaupt? Die Idee besteht darin, zu überprüfen, welche Dateien tatsächlich für einen bestimmten Ausführungspfad verwendet werden, ohne zeitaufwändige und fehleranfällige manuelle Nachverfolgung.
Zum Beispiel:
$ > 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
Antwort1
Das hier scheint zu funktionieren:
$ strace -fe open ./my.sh 2>&1 >/dev/null | \
grep --only-matching '^\(\[pid\s\+[0-9]*\] \)\?open("[^"]\+' | \
grep --only-matching '".*' | \
cut --characters 2-
Mit anderen Worten: Verfolgen Sie die Ausführung und die Druckaufrufe open
, vertauschen Sie stdout und stderr und formatieren Sie anschließend das Ergebnis, um irrelevanten Text zu entfernen.
Es werden auch einige Bibliothekspfade gedruckt, was aber kein großes Problem darstellt:
/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
Einige verbleibende Fragen:
- Gibt es eine Möglichkeit, zuverlässig zwischen Shell- und Bibliothekspfaden zu unterscheiden? Letzteres scheint möglich zu sein, da alle Bibliotheksreferenzen den
O_CLOEXEC
Option, während dies bei keiner der Shell-Referenzen der Fall ist. - Ist es möglich, zwischen bezogenen und ausgeführten Pfaden zu unterscheiden?
- Gibt es nachweisbare Sonderfälle, in denen dieser Befehl fehlschlägt?