bash heredoc可以将其结果直接放入变量中吗? [英] Can a bash heredoc put its result directly into a variable?

查看:65
本文介绍了bash heredoc可以将其结果直接放入变量中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些类似这样的代码:

I have some code like this:

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
)

有没有一种方法可以获取此处的文档,从而直接将结果分配给bash中的变量,而无需进行干预(cat)?该代码有效,只是感觉工作太多.

is there a way to get a here doc to assign result directly to variable in bash without intervening process (cat)? This code works, it just feels like too much work.

推荐答案

如何将here-string放入Bash中的变量:

How to put a here-string into a variable in Bash:

在Bash中,将 -d 分隔符设置为null的情况下,使用 read :

In Bash use read with the -d delimiter set to null:

IFS= read -r -d '' cmd <<EOC
    ...blah blah...
EOC

请确保您确实在 read 前面使用了如图所示的 IFS = ,否则所有前导和尾随空格都会被剪裁.确保使用 -r ,否则某些反斜杠将被理解为转义反斜杠.

Make sure you really use IFS= like shown, in front of read, otherwise any leading and trailing spaces will be trimmed. Make sure you use -r otherwise some backslashes would be understood as escape backslashes.

有人会认为,仅将简单分配用于以下内容会更简单:

Some would argue that it's simpler to just use a plain assignment as:

cmd='
    ...blah blah...
'

但是有时您会引号很多,以至于使用它变得越来越简单.

But sometimes you have lots of quotes to the point that it becomes simpler and nicer to use this.

细微的注释.这样,由于未在EOF之前读取空字节定界符,因此 read 返回失败返回码(1).虽然大多数时候都可以,但是如果您使用 set -e (但您真的不应该使用 set -e ).如果要确定,请添加:

Subtle note. With this, read returns a failure return code (1) since the null-byte delimiter is not read before EOF. While this is alright most of the times, it can be a problem if you're using set -e (but you really shouldn't use set -e anyway). If you want to be sure, add:

IFS= read -r -d '' cmd <<EOC || true
    ...blah blah...
EOC


现在,认真对待您的问题.

下面是一个严重的提示,您确实应该考虑:请勿将代码放入字符串中!它坏了!.而是使用函数或数组(仍然很差,但不会损坏).这是使用数组的方式:


Now, seriously, about your problem.

Below is a serious note that you really should take into account: don't put code into strings! it's broken!. Instead, use a function or (still bad, but not broken) an array. Here's how you would use an array:

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"
)

(用爱心观察我花时间键入的引号).然后,您可以安全地运行它(如果您的参数中包含全局字符,引号或空格,则可以安全地运行它):

(observe the quotes that I took time to type, with love). Then you can safely run it (by safely I mean it's all right if you're having glob characters or quotes or spaces in your arguments) as:

"${mycommand[@]}"

(再次观察健康的报价).如果要打印命令,请使用以下命令:

(observe the healthy quotes, again). If you want to print the command, use this:

printf '%s\n' "${mycommand[*]}"

不幸的是,这里不会保留换行符.但实际上,这根本不是问题.如果确实需要,则应通过某种格式程序传递此命令(很可能它不存在,因此您必须自己编写代码).但是将事情摆放正确:您想定义一个命令来执行它(并有选择地格式化它,以供用户显示),而不是相反,要有一个很好的字符串然后您必须(危险地)解析用户的眼睛才能转换为代码.

Unfortunately, the line breaks won't be preserved here. But really, that shouldn't be a problem at all. If really needed, you should pass this command through a formatter of some sort (well, very likely it doesn't exist so you'll have to code it yourself). But put the things in the right order: you want to define a command, to execute it (and, optionally format it, for user display), not the other way round, have a string that's nice to the user's eyes that you then have to parse (dangerously) to transform into code.

这篇关于bash heredoc可以将其结果直接放入变量中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆