リモートサーバーで文字列の Grep 検索が結果を返さない

リモートサーバーで文字列の Grep 検索が結果を返さない
#!/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

リモートサーバーにログインし、ローカルコンピュータにあるPatterns.txtファイルで指定された文字列をgrepしようとしています。スクリプトを実行すると、リモートシステムにログインしますが、ローカルシステム上のPatterns.txtファイルで指定されたパターンを取得しません。

リモートサーバーにPatterns.txtファイルを作成すると、スクリプトは正常に機能しますが、スクリプトを実行しているローカルコンピューターにファイルがある場合は機能しません。

答え1

ここにある文書はで参照されます<<'EOF'。最初の区切り文字を引用したので、ここにある文書全体を引用します。これは、シェルが内部で拡張を実行しないことを意味します。これは、これら2つの変数がローカルシェルに触れることなくリモートシェルによって拡張され、空の文字列に拡張される可能性が高いことを意味します。

もう一つの問題はそれを使用する$params方法ですgrep。 1行に別々の正規表現ではなく単一の正規表現として機能します(私の考えでは、これはあなたの意図だと思います)。

代わりに:

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 

関連情報