【发布时间】:2018-12-12 12:03:24
【问题描述】:
我一直在尝试找出一个 Bash 脚本文件,它通过研究大量文档和在线搜索来启动一些 Docker 容器(我对 Bash 很陌生)。但是,我根本无法弄清楚以下行的作用:
which systemctl 2>&1 >/dev/null && systemctl stop firewalld && systemctl restart docker
我理解 2>&1 >/dev/null 部分。
我也明白“which”是一个实用程序,它基本上通过引用 PATH 信息将可执行文件的完整路径打印到 STDOUT(如果我错了,请纠正我),我相信它不是最推荐的实用程序,因为它不是在不同的 UNIX-y 系统中通用。
但是,我根本不理解那条线。
我尝试通过输入which node、which docker 之类的东西来玩它,它的行为与预期的一样,但我根本不明白上面一行发生了什么。
作为参考,整个代码及其输出如下:
PROVISION_PORT=3000
HLF_WORKSPACE=~/HLF_workspace
usage() {
echo "Usage: $0 [-p provision_port] [-d HLF_workspace_path]" # $0: 0th arg -> ./setupProvCont
}
if [ $# -eq 0 ]
then
echo "No input parameter, will use default settings"
fi
while getopts "p:d:h" arg #get options
do
case $arg in
h)
usage
exit #exit 0 -> normal exit
;;
p)
PROVISION_PORT=$OPTARG #optional arguments
;;
d)
HLF_WORKSPACE=$OPTARG
;;
?)
usage
exit 1 #exit 1 -> error exit, unknown flag used
;;
esac
done
which systemctl 2>&1 >/dev/null && systemctl stop firewalld && systemctl restart docker
echo "Starting Provision..."
echo "docker run -it -u `id -u $USER` --network=host -e "PROVISION_PORT=$PROVISION_PORT" -e \"BCS_DOCKER_WORKSPACE=$HLF_WORKSPACE\" -e \"VM_HOSTNAME=`hostname`\" -v /var/run:/var/run -v $HLF_WORKSPACE:$HLF_WORKSPACE -d oracle/HLF-provision"
docker run -it -u `id -u $USER` --network=host -e "PROVISION_PORT=$PROVISION_PORT" -e "BCS_DOCKER_WORKSPACE=$HLF_WORKSPACE" -e "VM_HOSTNAME=`hostname`" -v /var/run:/var/run -v $HLF_WORKSPACE:$HLF_WORKSPACE -d oracle/HLF-provision
输出:
[hlf@hlfdemo hlf_fabric]$ ./setupProvisionContainer.sh
No input parameter, will use default settings
Starting Provision...
docker run -it -u 1000 --network=host -e PROVISION_PORT=3000 -e "BCS_DOCKER_WORKSPACE=/home/hlf/HLF_workspace" -e "VM_HOSTNAME=hlfdemo.internal" -v /var/run:/var/run -v /home/hlf/HLF_workspace:/home/hlf/HLF_workspace -d hlf/HLF-provision
b7f3073cc218b70525341c1770aaef17fc41c8e76f858807e7fd6e995594c60d
[hlf@hlfdemo hlf_fabric]$
【问题讨论】:
-
which systemctl背后的一般想法是确定是否安装了 systemd,如果安装了,则调用两个下一个命令。除了返回给定命令的路径之外,当在$PATH中找不到命令时,which会以非零状态退出。 -
如前所述,
&&条件使每个步骤都基于前一个步骤,因此如果which失败,它不会停止firewalld并重新启动docker。它也不会跳过该行 after 的任何内容,也不会检查firewalld是否正在运行,所以我猜它要么没那么重要,要么来自 @ 的错误987654333@ 在某些日志中足以让管理员解决问题并重试。 -
@PaulHodges 和 user3159253,非常感谢您的澄清,我终于明白了!整个命令是一个 AND 列表,仅当组成它的所有三个命令都退出且没有错误时才会执行,即退出 0,并且 which systemctl 2>&1 >/dev/null 将 STDERR 重定向到 STDOUT 然后丢弃它(dev/ null),从而检查以确保 systemctl 存在。如果没有,将显示错误并且此行不执行任何其他操作,但以下行确实会执行。如果我在某个地方仍然出错,请纠正我!再次感谢您!
-
是的,虽然我们都需要注意它丢弃了错误,所以它甚至不会被记录,哈哈……但是是的,一般来说,你有它。
-
@PaulHodges 有道理,谢谢你的澄清!
标签: bash