转义bash v3中的右括号字符

转义bash v3中的右括号字符,bash,escaping,heredoc,Bash,Escaping,Heredoc,我需要在heredoc中嵌入一段shell脚本,作为创建cloud init脚本的一部分,以提供Ubuntu 14.04 LTE机器。演示该问题的脚本的简化版本如下: #!/bin/bash cloudconfig=$(cat <<EOF if host \$NAMESERVER 1>/dev/null 2>&1; then case \$reason in BOUND|RENEW|REBIND|REBOOT) nsupdate -k /

我需要在heredoc中嵌入一段shell脚本,作为创建cloud init脚本的一部分,以提供Ubuntu 14.04 LTE机器。演示该问题的脚本的简化版本如下:

#!/bin/bash

cloudconfig=$(cat <<EOF
    if host \$NAMESERVER 1>/dev/null 2>&1; then
    case \$reason in
    BOUND|RENEW|REBIND|REBOOT) nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
    server \$NAMESERVER
    update delete \$HOST_NAME A
    update add \$HOST_NAME \$TTL A \$HOST_ADDR
    send
    EOX
    ;;
    esac
    fi
EOF
)

echo "${cloudconfig}"
Little-Net:orchestration minfrin$ bash /tmp/test.sh
could not read key from /var/lib/dhcp/nsupdate.{private,key}: file not found
couldn't get address for '$NAMESERVER': not found
有问题的字符是“REBOOT”右侧的结束括号,显而易见的解决方案是转义该字符:

BOUND|RENEW|REBIND|REBOOT\) nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
BOUND | RENEW | REBIND | REBOOT\)nsupdate-k/var/lib/dhcp/nsupdate.key/dev/null 2>&1;然后
案例$原因
绑定|续订|重新绑定|重新启动\)nsupdate-k/var/lib/dhcp/nsupdate.key>“EOF”将破坏脚本的其余部分


如何转义“)”字符而不使转义字符通过heredoc泄漏?

由于这似乎是bash 3.x解析问题(正如可以看到的,它在bash 4.x中工作),您需要避免解析器混淆。这似乎对我有用:

#!/bin/bash

rp=")"
cloudconfig=$(cat <<EOF
    if host \$NAMESERVER 1>/dev/null 2>&1; then
    case \$reason in
    BOUND|RENEW|REBIND|REBOOT${rp} nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
    server \$NAMESERVER
    update delete \$HOST_NAME A
    update add \$HOST_NAME \$TTL A \$HOST_ADDR
    send
    EOX
    ;;
    esac
    fi
EOF
)

echo "${cloudconfig}"
#/bin/bash
rp=“)”
cloudconfig=$(类别&1;然后
案例\$中的原因

绑定|续订|重新绑定|重新启动${rp}nsupdate-k/var/lib/dhcp/nsupdate.key因为这似乎是一个bash 3.x解析问题(正如可以看到的那样,它在bash 4.x中工作),您需要避免解析器混淆。这对我来说似乎很有效:

#!/bin/bash

rp=")"
cloudconfig=$(cat <<EOF
    if host \$NAMESERVER 1>/dev/null 2>&1; then
    case \$reason in
    BOUND|RENEW|REBIND|REBOOT${rp} nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
    server \$NAMESERVER
    update delete \$HOST_NAME A
    update add \$HOST_NAME \$TTL A \$HOST_ADDR
    send
    EOX
    ;;
    esac
    fi
EOF
)

echo "${cloudconfig}"
!/bin/bash
rp=“)”
cloudconfig=$(类别&1;然后
案例\$中的原因

绑定|续订|重新绑定|重新启动${rp}nsupdate-k/var/lib/dhcp/nsupdate.key因为这似乎是一个bash 3.x解析问题(正如可以看到的那样,它在bash 4.x中工作),您需要避免解析器混淆。这对我来说似乎很有效:

#!/bin/bash

rp=")"
cloudconfig=$(cat <<EOF
    if host \$NAMESERVER 1>/dev/null 2>&1; then
    case \$reason in
    BOUND|RENEW|REBIND|REBOOT${rp} nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
    server \$NAMESERVER
    update delete \$HOST_NAME A
    update add \$HOST_NAME \$TTL A \$HOST_ADDR
    send
    EOX
    ;;
    esac
    fi
EOF
)

echo "${cloudconfig}"
!/bin/bash
rp=“)”
cloudconfig=$(类别&1;然后
案例\$中的原因

绑定|续订|重新绑定|重新启动${rp}nsupdate-k/var/lib/dhcp/nsupdate.key因为这似乎是一个bash 3.x解析问题(正如可以看到的那样,它在bash 4.x中工作),您需要避免解析器混淆。这对我来说似乎很有效:

#!/bin/bash

rp=")"
cloudconfig=$(cat <<EOF
    if host \$NAMESERVER 1>/dev/null 2>&1; then
    case \$reason in
    BOUND|RENEW|REBIND|REBOOT${rp} nsupdate -k /var/lib/dhcp/nsupdate.key << EOX
    server \$NAMESERVER
    update delete \$HOST_NAME A
    update add \$HOST_NAME \$TTL A \$HOST_ADDR
    send
    EOX
    ;;
    esac
    fi
EOF
)

echo "${cloudconfig}"
!/bin/bash
rp=“)”
cloudconfig=$(类别&1;然后
案例\$中的原因

绑定|续订|重新绑定|重新启动${rp}nsupdate-k/var/lib/dhcp/nsupdate.key由于您在here文档中没有任何实际要扩展的参数,我只想引用整个内容(这为您节省了大量明确的反斜杠):

如果需要允许某些参数展开,仍可以使用多行字符串并进行一些修改。每当需要插值时,请关闭单引号并立即打开双引号。展开完成后,请关闭双引号并重新打开单引号

cloudconfig='
    if [[ $SOMEVARIABLE =='"$value"' ]]; then
    ...
'

由于在here文档中没有任何实际要展开的参数,因此我只引用整个内容(这为您节省了大量明确的反斜杠):

如果需要允许某些参数展开,仍可以使用多行字符串并进行一些修改。每当需要插值时,请关闭单引号并立即打开双引号。展开完成后,请关闭双引号并重新打开单引号

cloudconfig='
    if [[ $SOMEVARIABLE =='"$value"' ]]; then
    ...
'

由于在here文档中没有任何实际要展开的参数,因此我只引用整个内容(这为您节省了大量明确的反斜杠):

如果需要允许某些参数展开,仍可以使用多行字符串并进行一些修改。每当需要插值时,请关闭单引号并立即打开双引号。展开完成后,请关闭双引号并重新打开单引号

cloudconfig='
    if [[ $SOMEVARIABLE =='"$value"' ]]; then
    ...
'

由于在here文档中没有任何实际要展开的参数,因此我只引用整个内容(这为您节省了大量明确的反斜杠):

如果需要允许某些参数展开,仍可以使用多行字符串并进行一些修改。每当需要插值时,请关闭单引号并立即打开双引号。展开完成后,请关闭双引号并重新打开单引号

cloudconfig='
    if [[ $SOMEVARIABLE =='"$value"' ]]; then
    ...
'

我通过在
herdoc
中手动转义parenths来解决这个问题,然后使用
sed
语句来删除反斜杠

long_string=$(cat << 'HEREDOC'
This is a string with \( escaped \) parenthesis.
HEREDOC
)

long_string=$(echo $long_string | sed -e 's:\\(:(:g' -e 's:\\):):g')

long\u string=$(cat我通过在
herdoc
中手动转义parenths来解决它,然后使用
sed
语句来删除反斜杠

long_string=$(cat << 'HEREDOC'
This is a string with \( escaped \) parenthesis.
HEREDOC
)

long_string=$(echo $long_string | sed -e 's:\\(:(:g' -e 's:\\):):g')

long\u string=$(cat我通过在
herdoc
中手动转义parenths来解决它,然后使用
sed
语句来删除反斜杠

long_string=$(cat << 'HEREDOC'
This is a string with \( escaped \) parenthesis.
HEREDOC
)

long_string=$(echo $long_string | sed -e 's:\\(:(:g' -e 's:\\):):g')

long\u string=$(cat我通过在
herdoc
中手动转义parenths来解决它,然后使用
sed
语句来删除反斜杠

long_string=$(cat << 'HEREDOC'
This is a string with \( escaped \) parenthesis.
HEREDOC
)

long_string=$(echo $long_string | sed -e 's:\\(:(:g' -e 's:\\):):g')

long\u string=$(猫的问题显然不是“重新启动”右边的右括号。注意,如果你认为
是问题所在,请创建一个最基本的示例,只显示这个问题,不要在这里发布整个混乱。让我补充一下,在这种情况下,它会向你显示
不是问题。@hek2mgl
绝对不是问题。/var/lib/dhcp/nsupdate.key显然不存在或看不见,正如错误明确指出的那样,不知道OP为什么会认为它是括号。@OP为什么要在catNo中执行此操作,
是问题。shell将其视为关闭
$(…)
并尝试在本地运行
nsupdate
命令,这是不正确的。@EtanReisner如果您错了,请重试it@hek2mgl是的。失败了。这似乎是bash版本的问题。它对bash 3起作用,但对我来说失败了。问题显然不是“重新启动”右侧的右括号。注意,如果您认为
是问题所在,请创建一个最基本的示例,仅显示该问题,不要在这里发布您的全部信息。让我补充一点,在这种情况下,它会向您显示
不是问题。@hek2mgl
绝对不是问题所在/var/lib/dhcp/nsupdate.key obvio