ssh 到远程主机后,EOF 内使用的 grep 给出输出“没有这样的文件或目录”

ssh 到远程主机后,EOF 内使用的 grep 给出输出“没有这样的文件或目录”

设想:

我有一个脚本用于连接到远程主机并从日志文件中 grep 特定关键字。如果不使用 EOF,ssh 就会被冻结,但是当使用 heredoc (EOF) 时,这个问题就消失了。我的所有命令都必须在 ssh 到远程主机后执行,因此它们位于 EOF 块内。

grep 命令给我的输出为:“没有这样的文件或目录”,而我在终端上执行了相同的命令,它给出了所需的输出。

下面是有问题的 grep 代码:

ssh -q -T username@remotehost <<-EOF 2>&1 | tee -a
getValue=$(grep -R 'keyword' /user/log/file.log | awk -F ' ' '{print$NF}') )
echo "${getValue}"
EOF

Output: grep: /user/log/file.log : No such file or directory

当我打印远程主机并进一步交叉检查日志路径和 file.log 时,SSH 工作正常。从设置的角度来看,一切都已就位。通过互联网进行了一些研发,但到目前为止没有任何帮助。

答案1

您需要引用您'EOF'以防止您的外壳程序$在本地解释,即。尝试在远程命令之前在 shell 中运行 grep 。

比较:

ssh username@remotehost << 'EOF'
echo "THIS IS $(hostname)"
EOF

ssh username@remotehost << EOF
echo "THIS IS $(hostname)"
EOF

答案2

您的问题来自于让 shell 在本地而不是远程系统上扩展此处文档中的命令替换。这样做是因为此处的文档没有被引用。出于同样的原因,它还会将$NF和作为 shell 变量扩展为空字符串(除非这些 shell 变量之前有值)。 ${getValue}shell 不会注意到程序$NF中使用了awk

不必尝试通过在远程主机上运行复杂的命令ssh,只需使用ssh来获取数据,然后在该数据上本地运行命令:

ssh username@remotehost cat /user/log/file.log |
awk -F ' ' '/keyword/ { print $NF }'

我也稍微简化了您的管道,将递归 (?!)grep与结合awk起来,以便awk命令打印包含 substring 的行上的最后一个空格分隔的字段keyword

另请注意,如果您只想输出该变量的内容(echo在某些情况下可能会另外修改在打印之前给出的数据),则将输出分配给变量是没有意义的。我还删除了tee -a似乎没有多大作用的电话。

答案3

大约一周前,我使用包装脚本概念实现了所需的目标。只是为任何可能遇到同样问题的新用户发布此链接。

当然,这不是一个新概念,和许多其他概念一样,我在在这里发布我的问题之前也知道它。我真的想通过一个脚本来实现这一点,但不知何故,ssh 到远程主机后的变量扩展不能处理同一脚本中的所有内容。所以花那么多精力是不值得的。

创建一个包装脚本并在其中调用主脚本。在包装器中执行 ssh 命令,并将主脚本作为参数传递。就像是:

ssh username@host < main_script.sh

如果您有多个主机,请在读取变量“host”中的主机服务器值后将 ssh 置于 for/while 循环中。

while read -r host
do
servers=${host}

ssh username@${host} < main_script.sh

done < ${servers}

感谢大家提出建议!!

相关内容