#!/bin/bash
params=$(cat /var/tmp/patterns.txt)
remoteLog="/home/remotefile.txt"
nodes=("192.168.1.2" "192.168.1.3")
for node in "${nodes[@]}";do
ssh ${node} << 'EOF'
grep -i "${params}" "$remotelog" >/var/tmp/output.txt
EOF
done
cat /var/tmp/patterns.txt
abc
efg
ijk
我正在尝试登录到远程服务器并 grep 查找驻留在本地计算机上的patterns.txt 文件中指定的字符串。当我运行该脚本时,它会登录到远程计算机,但不会对驻留在本地计算机上的patterns.txt 文件中指定的模式进行 grep。
如果我在远程服务器上创建patterns.txt 文件,该脚本可以正常工作,但当该文件驻留在我运行脚本的本地计算机上时,脚本就不能正常工作。
答案1
您的此处文档是用<<'EOF'
.由于您引用了初始分隔符,因此将引用整个此处文档。这反过来意味着 shell 不会在其中执行扩展,这意味着本地 shell 不会触及这两个变量,而是由远程 shell 扩展,这很可能会将它们扩展为空字符串。
另一个问题是您使用$params
的方式grep
。它将用作单个正则表达式,而不是每行单独的正则表达式(我认为这就是您的意图)。
反而:
for node in "${nodes[@]}"; do
ssh "$node" "cat -- '$remotelog'" |
grep -f "$params" |
ssh "$node" 'cat >/var/tmp/output.txt'
done
这对grep
从每个主机获取的数据执行本地操作。该操作通过选项grep
使用文件中的正则表达式,然后将结果输出回远程主机上的文件。$params
-f
另一种方法是将模式传输到每台主机并远程执行操作:
for node in "${nodes[@]}"; do
scp "$params" "$node:/var/tmp/patterns.txt" &&
ssh "$node" <<EOF
grep -f /var/tmp/patterns.txt '$remotelog' >/var/tmp/output.txt
rm -f /var/tmp/patterns.txt
EOF
done