如果未定义变量,请避免运行脚本

use*_*780 43 shell bash shell-script

我有一个脚本看起来像:

c=0
for f in */*; do
cp -v "$f" "/myhome/CE$(printf '%0*d' 2 $BATCHNUM)-new-stuctures_extracted/test-$(printf '%0*d' 5 $c)"
c=$((c=c+1))
done
Run Code Online (Sandbox Code Playgroud)

但是,用户必须提供一个变量调用 BATCHNUM,否则我需要强制此脚本停止运行。如果我可以强制调用此脚本的脚本也停止(甚至调用调用此脚本的 #2 脚本的 #1 脚本)会更好。

Tom*_*unt 58

最快的方法可能是将这两行添加到脚本的开头:

set -u # or set -o nounset
: "$BATCHNUM"
Run Code Online (Sandbox Code Playgroud)

第一行在nounset运行脚本的 shell 中设置选项,如果您尝试扩展未设置的变量,该选项将中止;第二个$BATCHNUM在无操作的上下文中扩展,以在执行任何其他操作之前触发中止。

如果你想要更有用的错误信息,你可以写:

if [[ -z "$BATCHNUM" ]]; then
    echo "Must provide BATCHNUM in environment" 1>&2
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

或者类似的。


cuo*_*glm 32

这里要检查BATCHNUM是否设置为空。

POSIX shell为这项工作提供了一个参数扩展。只需在使用前添加这一行BATCHNUM

: "${BATCHNUM:?Variable not set or empty}"
Run Code Online (Sandbox Code Playgroud)

或者更好地设置默认值,BATCHNUM如果用户没有提供:

: "${BATCHNUM:=3}"
Run Code Online (Sandbox Code Playgroud)

  • 您也可以省略错误消息,并写入“${BATCHNUM:?}”。这将打印一条通用错误消息:“bash:BATCHNUM:参数为空或未设置” (2认同)

Tho*_*ker 6

线条

if [ -z "$BATCHNUM" ]; then
    exit 2;
fi
Run Code Online (Sandbox Code Playgroud)

检查是否为空$BATCHNUM。有了$PPID你,你就可以为所欲为了地伤害你的父母(kill $PPID)。为了谋杀你的祖父母,你需要通过其他方式获取进程ID,比如查看/proc/$PPID.

然而,如果你的父母死了,它会SIGHUP向你发送一个信号( ),所以你必须在开始杀死任何人之前捕获它:

trap '' SIGHUP
Run Code Online (Sandbox Code Playgroud)

更新:如果你认为你必须杀死你的父母,那你就错了。只需返回一个有意义的退出代码即可。父脚本应该检查被调用脚本的返回代码并做出相应的反应。

  • 有点残酷......:) (5认同)

PSk*_*cik 5

[ -n "$BATCHNUM" ] || { kill "$PPID"; exit 1; }
#Unless $BATCHNUM is defined and unempty, ask parent process to exit and exit w/ 1
Run Code Online (Sandbox Code Playgroud)

这将适用于 bash 和 POSIX sh。我不想区分空变量和未定义变量(即,我不喜欢set -u,但这只是我自己)。