我必须对这个由程序调用的 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