Bash trap在Python出错后未执行

1 投票
1 回答
938 浏览
提问于 2025-04-18 11:31

我有一个在Ubuntu 12上运行的bash脚本:

#!/bin/bash -e
if [[ -f ".build.lock" ]]; then
   echo "A build is already in progress by another user. Unable to continue, exiting."
   echo "   If this is a mistake, delete the '.build.lock' file to forcefully unlock"
   exit 1
else
   touch .build.lock
   echo "Build Lock Created"

   pushd ~/build-server-scripts > /dev/null

   # Execute main build script
   python3 my-build.py "$@"

   popd > /dev/null
fi

__cleanup()
{
   echo "Build Lock Removed"
   [[ -f ".build.lock" ]] && rm ".build.lock"
}

trap __cleanup EXIT

每当我的Python脚本抛出异常(大多数是未处理的异常)时,我希望bash脚本也能随之失败并执行TRAP命令。但是,它并没有这样做。我漏掉了什么呢?

下面是我在Python(使用Python 3.2)脚本中处理错误的一个例子:

try:
   # Do lots of other business logic here

   # 'os.setsid' needed to terminate process later for interrupts.
   process = subprocess.Popen('./ziosk-build.sh', preexec_fn=os.setsid)
   process.communicate()

except KeyboardInterrupt:
   print('\n\nSIGINT (CTRL+C?) received; stopping\n')
   try:
      os.killpg(process.pid, signal.SIGTERM)
   except NameError:
      pass

except RuntimeError as e:
   print('>>> ERROR >>>', e)
   sys.exit(1)

在上面的脚本中,我明确处理了一些异常。当我收到键盘中断时,我想退出,并且调用这个脚本的bash脚本应该通过trap来清理构建锁。当发生其他运行时错误时,我也会处理并打印出来,以便提供上下文和信息。

当然,还有其他类型的异常我没有明确处理,但目前这些并没有导致trap被执行。

希望能得到帮助!!

1 个回答

2

你的 __cleanup 函数在 Python 脚本出错时不会被执行,因为脚本在到达 trap __cleanup EXIT 这个语句之前就已经退出了,而这个语句是用来注册处理函数的。你应该把 trap 语句和 __cleanup 函数放在脚本的最上面。

#!/bin/bash -e

__cleanup()
{
   echo "Build Lock Removed"
   [[ -f ".build.lock" ]] && rm ".build.lock"
}
trap __cleanup EXIT

if [[ -f ".build.lock" ]]; then
   echo "A build is already in progress by another user. Unable to continue, exiting."
   echo "   If this is a mistake, delete the '.build.lock' file to forcefully unlock"
   exit 1
else
   touch .build.lock
   echo "Build Lock Created"

   pushd ~/build-server-scripts > /dev/null

   # Execute main build script
   python3 my-build.py "$@"

   popd > /dev/null
fi

撰写回答