BASH - EOF标签内的回声是如何工作的

时间:2017-03-16 19:14:05

标签: bash

我想执行以下操作:

PASSWORD="mypassword"
RUNCOMMAND=$(cat <<EOF
echo $PASSWORD | sudo -S sudo echo "this is it babe"
EOF
)

但是我得到以下结果而不是this is it babe

mypassword | sudo -S sudo echo "this is it babe"

我尝试使用cat <<\EOFcat <<'EOF'仍然没有运气。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您将heredocpipeline混淆。

具有可变扩展的heredoc:

cat <<EOF
some text, possibly with variables: ${HOME} / $(whoami)
EOF
some text, possibly with variables: /home/attie / attie

没有变量扩展的heredoc:

cat <<"EOF"
some text, possibly with variables: ${HOME} / $(whoami)
EOF
some text, possibly with variables: ${HOME} / $(whoami)

具有可变扩展的管道(请注意引号"):

echo "some text, possibly with variables: ${HOME} / $(whoami)" | cat
some text, possibly with variables: /home/attie / attie
没有变量扩展的

管道(注意引号'):

echo 'some text, possibly with variables: ${HOME} / $(whoami)' | cat
some text, possibly with variables: ${HOME} / $(whoami)

${...}扩展了一个环境变量

$(...)运行命令,并替换其stdout

看起来你也试图将密码输入sudo - 这不起作用,因为sudo将重新启动终端以获取密码,然后将stdin传递给最终申请。

答案 1 :(得分:1)

你是从错误的前提开始的,eval $RUNCOMMAND是你应该做的事情。它不是;变量用于数据,函数用于代码。

run_command () {
    docker_run_options=(
       --restart=always
       --name "${USER_NAME}_$(date +%Y%m%d-%H%M%S)"
       -d
       -e "VIRTUAL_HOST=$USER_VIRTUAL_HOST"
       -e "VIRTUAL_PORT=$USER_VIRTUAL_PORT"
       -e "PORT=$USER_VIRTUAL_PORT"
       -p "$USER_VIRTUAL_PORT:$USER_VIRTUAL_PORT"
    )

    echo "$1" | sudo -S sudo docker run "${docker_run_options[@]}" "$USER_IMAGE"
}

fun_run_command () {
    run_command "PASSWORD"
}

答案 2 :(得分:-1)

最终解决方案相当简单:

PASSWORD="mypassword"
RUNCOMMAND=$(cat <<EOF
echo $PASSWORD | sudo -S sudo echo "this is it babe"
EOF
)

并通过eval执行:

eval $RUNCOMMAND

对不起因为这个明显的问题家伙偷了你的时间:)

上面的用例是在执行它之前echo给定命令。

像这样:

fun_run_command(){
# execute the final command
echo `eval $RUNCOMMAND`
}

fun_echo_command(){
# echo the command which will be launched (fun_run_command())
echo ${RUNCOMMAND//$PASSWORD/PASSWORD}
}

RUNCOMMAND=$(cat <<EOF
echo $PASSWORD | sudo -S sudo docker run --restart=always \
--name ${USER_NAME}_`date +%Y%m%d-%H%M%S` \
-d \
-e "VIRTUAL_HOST=$USER_VIRTUAL_HOST" \
-e "VIRTUAL_PORT=$USER_VIRTUAL_PORT" \
-e "PORT=$USER_VIRTUAL_PORT" \
-p $USER_VIRTUAL_PORT:$USER_VIRTUAL_PORT \
$USER_IMAGE
EOF
)

正如你所看到的,我发布的命令很长, 因此,重新检查脚本执行的内容总是有意义的。

将相同的命令复制并粘贴到多个函数时容易出错。