如何对程序调用的 python 脚本调用的 bash 脚本进行故障排除?

如何对程序调用的 python 脚本调用的 bash 脚本进行故障排除?

我必须对这个由程序调用的 python 脚本调用的 bash 脚本进行故障排除,所有脚本都在 Ubuntu 18.04 中运行。

python脚本和程序都是黑匣子。我所掌握的唯一信息是它们工作正常,并且 python 脚本仅在调用 bash 脚本时失败,因为脚本本身失败。

bash 脚本非常简单,本身可以正常工作,但每当从此脚本调用时都会失败,这使我相信存在某种权限错误。问题是,我需要找到一种方法来获取它在失败时给出的错误消息。在这种情况下我怎样才能得到这些信息?

当从 python 脚本运行 bash 脚本时,不会向终端输出任何set -x信息。set -v

以下是 bash 脚本的内容:

#!/bin/bash

echo "$1" >> /scripts/vomit
mv $1/*.mp4 .

问题线是mv $1/*.mp4.如果我注释掉该行,则该脚本在从程序调用的 python 脚本中调用时会起作用。我只是不知道为什么mv线路出问题了。

答案1

使用strace用于调试程序及其所有子进程的命令。

对于新流程:

strace -f command

对于现有流程:

strace -fp PID

如果您不知道进程 ID(因为它运行得太快),您可以sleep 20在 shell 脚本的开头添加,这样您就有时间找到它的 PID,ps wuax | grep bash然后使用上面的命令和找到的 PID。

要过滤输出,请使用-e.要保存到文件中,请使用-o.要增加消息的大小,请使用-s.如需更多帮助,请运行:man strace

要获得更好的格式,请参阅:如何将shell中的strace解析为纯文本?


这是实际的例子。给定以下myscript.sh文件:

#!/bin/bash -x
echo "$1"

我运行了以下命令:

strace -f -e trace=execve,read,write -s1000 bash -x ./myscript.sh foo bar

产生以下输出:

execve("/bin/bash", ["bash", "-x", "./myscript.sh", "foo", "bar"], [/* 41 vars */]) = 0
...
read(3, "#!/bin/bash -x\necho \"$1\"\n", 80) = 25
read(255, "#!/bin/bash -x\necho \"$1\"\n", 25) = 25
write(2, "+ echo foo\n", 11+ echo foo
)            = 11
write(1, "foo\n", 4foo
)                    = 4
read(255, "", 25)                       = 0
+++ exited with 0 +++

答案2

如果终端上没有显示任何内容,您可以将输出重定向到文件中,例如

将整个脚本(所有输出)放入文件中(在 Python 中更改它):

./script.sh &> output.log

对于单个命令:

mv -v $1/*.mp4 . 2> errors.log

还可以考虑添加set -x或使用#!/bin/bash -x.


要将所有 stdout 和 stderr 重定向到文件,请参阅:在 Bash 中重定向 stderr 和 stdout,即:

# Close STDOUT file descriptor
exec 1<&-
# Close STDERR FD
exec 2<&-

# Open STDOUT as $LOG_FILE file for read and write.
exec 1<> output.log

# Redirect STDERR to STDOUT
exec 2>&1

相关内容