想像する:
リモートホストに接続し、ログファイルから特定のキーワードを検索するスクリプトがあります。 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'
シェルが$
ローカルで解釈されないようにするには、引用符を使用する必要があります。リモートコマンドを実行する前に、シェルでgrepを実行してください。
比較する:
ssh username@remotehost << 'EOF'
echo "THIS IS $(hostname)"
EOF
そして
ssh username@remotehost << EOF
echo "THIS IS $(hostname)"
EOF
答え2
問題は、シェルにリモートシステムではなくローカルで文書のコマンド置換を拡張させることによって発生します。これは、ここにある文書が参照されていないために行われます。同じ理由で、$NF
シェル変数として空の文字列に展開されます(対応するシェル変数に以前の値がない場合)。${getValue}
シェルは$NF
プログラムが使用されていることを認識しませんawk
。
リモートホストで複雑なコマンドを実行する代わりに、次のようにデータをインポートし、そのデータssh
に対してssh
ローカルでコマンドを実行します。
ssh username@remotehost cat /user/log/file.log |
awk -F ' ' '/keyword/ { print $NF }'
また、コマンドが部分文字列を含む行にスペースで区切られた最後のフィールドを印刷するように、再帰grep
(?!)を組み合わせawk
てパイプラインを少し単純化しました。awk
keyword
またecho
、その変数の内容だけを出力したい場合は、出力を変数に割り当てることは意味がありません(場合によっては、印刷する前に提供されたデータをさらに変更できます)。tee -a
あまりないような通話も削除しました。
答え3
約1週間前、私はラッパースクリプトの概念を使って私が望むことを達成しました。同じ問題が発生する可能性がある新規ユーザーのためにこのリンクを投稿してください。
もちろんこれは新しい概念ではなく、他の多くの人と同様に、ここに質問を投稿する前にも知っていました。私はこれをスクリプトを通して本当に達成したいのですが、リモートホストのssh以降の変数拡張は同じスクリプトのすべてを処理しません。したがって、それほど努力する価値はありません。
ラッパースクリプトを作成し、その中にあるデフォルトスクリプトを呼び出します。ラッパーで ssh コマンドを実行し、基本スクリプトを引数として渡します。それは次のとおりです。
ssh username@host < main_script.sh
複数のホストがある場合は、「host」変数からホストサーバーの値を読み取り、for / whileループにsshを入れます。
while read -r host
do
servers=${host}
ssh username@${host} < main_script.sh
done < ${servers}
ご提案いただいた皆様に感謝します! !