bash-herdoc能否将其结果直接放入变量中?
我有一些这样的代码:bash-herdoc能否将其结果直接放入变量中?,bash,Bash,我有一些这样的代码: CMD=$(cat <<EOC docker run -p $MY_IP:$LOCAL_PORT:$LOCAL_PORT -p $MY_IP:$PEER_PORT:$PEER_PORT -v $CERT_DIR:/cert $ETCD_IMAGE --name $MACHINE.$DOMAIN --peer-cert-file=/cert/server-cert.pem --peer-key-file=/cert/s
CMD=$(cat <<EOC
docker run
-p $MY_IP:$LOCAL_PORT:$LOCAL_PORT -p $MY_IP:$PEER_PORT:$PEER_PORT
-v $CERT_DIR:/cert
$ETCD_IMAGE
--name $MACHINE.$DOMAIN
--peer-cert-file=/cert/server-cert.pem
--peer-key-file=/cert/server-key.pem --peer-ca-file=/cert/ca.pem
--peer-addr=$MY_IP:$PEER_PORT
--peers=$OIPPC
EOC
)
CMD=$(cat)
如何在Bash中将here字符串放入变量中:
在Bash中,使用read
,并将-d
分隔符设置为null:
IFS= read -r -d '' cmd <<EOC
...blah blah...
EOC
但有时你会引用很多的话,以至于使用它会变得更简单、更好
微妙提示。使用此功能,read
返回失败返回代码(1),因为在EOF之前未读取空字节分隔符。虽然大多数情况下这是正常的,但如果使用set-e
(但是),则可能会出现问题。如果要确定,请添加:
IFS= read -r -d '' cmd <<EOC || true
...blah blah...
EOC
(注意我花时间输入的引语,带着爱)。
然后您可以安全地运行它(安全地说,我的意思是,如果您的参数中有glob字符、引号或空格,那么就可以了),如下所示:
(再次观察正确的引号)。如果要打印命令,请使用以下命令:
printf '%s\n' "${mycommand[*]}"
不幸的是,这里不会保留换行符。但实际上,这根本不应该是一个问题。如果真的需要,您应该通过某种形式的格式化程序传递此命令(很可能它不存在,所以您必须自己编写代码)。但请按正确的顺序排列:您要定义一个命令,然后执行它(并且,为了用户显示,可以选择对其进行格式化),而不是相反,使用一个对用户眼睛很好的字符串,然后您必须(危险地)解析该字符串以转换为代码。为什么在这里使用herdoc?如果您只想在CMD
变量中使用该字符串(顺便说一句,您不需要,请参阅原因)然后直接使用带引号的字符串CMD=“docker run…”
。感谢指针。我使用herdoc是因为我想回显命令(如果调用程序请求verbose),记录命令,最后运行它。我已经习惯了python/perl中的herdoc,并且对它们很熟悉。我发现它们使用起来是错误的。herdoc与回显命令有什么关系?对变量的赋值让您可以不必担心。另外,set-x
可能是一种更好的verbose
模式手动回显命令(尽管有时会更加冗长,阅读起来也有点奇怪)。
mycommand=(
docker run
-p "$MY_IP:$LOCAL_PORT:$LOCAL_PORT"
-p "$MY_IP:$PEER_PORT:$PEER_PORT"
-v "$CERT_DIR":/cert
"$ETCD_IMAGE"
--name "$MACHINE.$DOMAIN"
--peer-cert-file=/cert/server-cert.pem
--peer-key-file=/cert/server-key.pem
--peer-ca-file=/cert/ca.pem
--peer-addr="$MY_IP:$PEER_PORT"
--peers="$OIPPC"
)
"${mycommand[@]}"
printf '%s\n' "${mycommand[*]}"