Bash:运行命令并在进程退出时退出并出错的优雅方式



我在 Bash 脚本中有这样的逻辑:

运行一些东西;
如果失败,请打印某些内容并停止;
如果没有,请运行其他内容。
所有这些都在ssh会话中运行。

如果我使用$?if / else,这可能是微不足道的。 但是由于脚本的可维护性,我正在寻找一些优雅的 2 行解决方案。

这就是我到目前为止所拥有的

ssh ... '
ls attributes/*'$CONF_FILE'.rb || ls -l attributes/ && exit 1;
'$EDITOR' attributes/*'$CONF_FILE'.rb '$PART_VER';'

但是,无论如何,这都会退出。所以我尝试了:

ssh ... '
ls attributes/*'$CONF_FILE'.rb || (ls -l attributes/ && exit 1);
'$EDITOR' attributes/*'$CONF_FILE'.rb '$PART_VER';'

但是,exit仅退出子外壳。从子外壳中退出脚本一点也不优雅。

有没有简单的 2 线解决方案?也许其他运算符优先?

为清晰、正确和可维护性而编写 -而不是简洁:

# store your remote script as a string. Because of the quoted heredoc, no variables are
# evaluated at this time; $1, $2 and $3 are expanded only after the code is sent to the
# remote system.
script_text=$(cat <<'EOF'
CONF_FILE=$1; PART_VER=$2; EDITOR=$3
shopt -s nullglob                   # Return an empty list for any failed glob
set -- attributes/*"$CONF_FILE".rb  # Replace our argument list with a glob result
if (( $# )); then                   # Check length of that result...
"$EDITOR" "$@" "$PART_VER"        # ...if it's nonzero, run the editor w/ that list
else
ls attributes                     # otherwise, run ls and fail
exit 1
fi
EOF
)
# generate a single string to pass to the remote shell which passes the script text
# ...and the arguments to place in $0, $1, etc while that script is running
printf -v ssh_cmd_str '%q ' 
bash -c "$script_text" '_' "$CONF_FILE" "$PART_VER" "$EDITOR"
# ...thereafter, that command can be run as follows:
ssh -tt ... "$ssh_cmd_str"

不要使用子外壳;使用命令组。

ssh ... "
ls attributes/*'$CONF_FILE'.rb || { ls -l attributes/ && exit 1; };
'$EDITOR' attributes/*'$CONF_FILE'.rb '$PART_VER';"

(请注意引号的变化;这更好地确保本地参数扩展的结果在远程端正确引用,尽管如果参数扩展本身包含单引号,仍然存在问题。正确的解决方案是在远程端运行显式 shell,将本地参数作为参数,而不是使用插值来构建脚本。以下内容未经测试,但我认为我正确引用了所有内容。

ssh ... sh -c '
ls attributes/*"$1.rb" || { ls -l attributes/ && exit 1; };
"$EDITOR" attributes/*"$1.rb" "$2";
' _ "$CONF_FILE" "$PART_VER"

(

现在,我诉诸于复制条件,如下所示:

ssh ... '
ls attributes/*'$CONF_FILE'.rb >  /dev/null || ls -l --color=always attributes/
ls attributes/*'$CONF_FILE'.rb >  /dev/null || exit 1;
'$EDITOR' attributes/*'$CONF_FILE'.rb '$PART_VER';'

(我使用&>-作为将 stdout 和 stderr 重定向到/dev/null的缩写,但这可能不正确,请参阅评论。

相关内容

  • 没有找到相关文章

最新更新