【问题标题】:No such file or directory in Heredoc, BashHeredoc,Bash中没有这样的文件或目录
【发布时间】:2017-05-19 02:56:46
【问题描述】:

我对 Bash 的 Heredoc 构造行为深感困惑。

这是我正在做的事情:

#!/bin/bash
user="some_user"
server="some_server"
address="$user"@"$server"

printf -v user_q '%q' "$user"

function run {
    ssh "$address" /bin/bash "$@"
}

run << SSHCONNECTION1
    sudo dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed" > /home/$user_q/check.txt

    softwareInstalled=$(cat /home/$user_q/check.txt)

SSHCONNECTION1

我得到的是

cat: /home/some_user/check.txt: 没有这样的文件或目录

这很奇怪,因为如果我要使用 SSH 连接并检查以下路径,则该文件存在。

我做错了什么?文件不可执行,只是一个文本文件。 谢谢。

【问题讨论】:

  • $(cat ...) 命令在本地运行。
  • 顺便说一句,请注意我在您之前的问题中链接到的替代答案(使用 printf '%q ' "$@" 生成一个 argv 列表,在命令行上将其传递给您的远程 shell,然后引用它的项目$1$2 等;这是它避免的场景之一。
  • ...尽管需要注意的是远程 /bin/sh 需要能够解析 printf '%q' 生成的内容,如果它不是 bash 或 ksh 并且您有不寻常的字符,这可能是一个问题在你的论点中。
  • 另外,softwareInstalled 只存在于远程服务器上;定义它没有什么意义,然后在远程脚本中什么也不做。
  • @chepner 我没有显示整个脚本,该变量稍后使用。谢谢

标签: bash heredoc


【解决方案1】:

如果您希望cat 在heredoc 评估期间远程运行,而不是本地运行,请转义$(...) 中的$

softwareInstalled=\$(cat /home/$user_q/check.txt)

当然,这只有在远程脚本的其他部分引用"$softwareInstalled" 时才有意义(或者,因为它位于未引用的heredoc 中,所以"\$softwareInstalled")。

【讨论】:

  • $softwareInstalled 稍后使用。谢谢,但是为什么 cat 是在本地执行的呢?我以为执行是逐行顺序执行的?
  • @Alex, $(cat ...) 在本地执行,原因与$user_q 包含您的本地变量相同:在生成与heredoc 对应的文本时执行扩展。如果您不希望这种情况发生,您可以引用您的印记 (&lt;&lt;'SSHCONNECTION1'),但其他变量也不会被替换。
  • 顺便说一句,(虽然您现在可能已经弄清楚了)——请确保heredoc中脚本的后面部分使用\$softwareInstalled,因此它是远程的而不是本地的评估。我也编辑了答案以指定这一点。
猜你喜欢
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
  • 2020-07-16
相关资源
最近更新 更多