#!/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