特定のパッケージがリモートシステムにインストールされているかどうかをbashスクリプトで確認しようとしています。
コンピュータ自体で次の文を実行すると、check.txtファイルの結果は1(インストール済み)であり、これは正しいものです。
dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed" > /home/someuser/check.txt
ただし、SSHセッションで同じコマンドを実行すると、結果は常に0になります。
この問題の理由と解決策を説明できる人はいますか?
ありがとうございます。
#!/bin/bash
ADDRESS=SOMEUSER@$SOMESERVER
function run {
ssh $ADDRESS /bin/bash $@
}
run << SSHCONNECTION
dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed" > /home/someuser/check.txt
SSHCONNECTION
答え1
スクリプトを変更してください:run << \SSHCONNECTION
またはdpkg-query -W -f='\${Status}' nano
。現在、ここで説明されているように、ローカルシェルは拡張しようとしています${Status}
(たとえば、一重引用符で囲んでも同じです)。 (空の文字列に展開できます。)
最初の部分はかなりよく文書化されています。 POSIXシェルコマンド言語仕様、部品2.7.4 ここのドキュメント説明する:
形式は... ︙部分がある場合
[n]<<word
word
参照...文書行はここで拡張してはいけません。
︙
部品がない場合word
これが引用されている場合は、ここにあるドキュメントのすべての行を展開する必要があります。
大きな打撃(1)本質的に同じことを言います。
2番目の部分は明確に文書化されていません。 POSIX仕様の上記の文は続きます。
部品がない場合
word
引用した場合、この文書のすべての行は、パラメータ拡張、コマンド置換、および算術拡張のために拡張する必要があります。この場合、入力の<バックスラッシュ>は二重引用符内の<バックスラッシュ>と同じように動作します(参照二重引用符)。
セクションには次の内容も記載されています。
ここのドキュメントは、次の<newline>で始まり、区切り文字と<newline>のみを含む行があるまで続く限り、単語として扱われるべきです。
対照的に、一部2.3 トークン認識説明する:
いつio_ここトークン(たとえば、a
<<
または<<-
)が文法によって認識されました(参照:シェル構文)、次のNEWLINEタグの直後に続く1つ以上の後続の行は、1つ以上のhereドキュメントの本文を形成し、次の規則に従って解析されます。ここのドキュメント。処理できないときio_ここ、シェルは以下の最初の適用可能な規則を適用して入力をトークンに分割する必要があります。
次に、以下を含む10のルールをリストします。
- 現在の文字が<バックスラッシュ>、一重引用符または二重引用符であり、引用符がない場合は、引用符付きテキストが終わるまで後続の文字の引用符に影響します。
したがって、ここにある文書のテキストがすでに二重引用符で囲まれていて、処理されたかのようにほぼ処理されていることを確認するには、行間を読む必要があるようです。ただパラメータ拡張、コマンド置換、算術拡張(および制限付きバックスラッシュ処理)の場合 まさか引用符を削除するために使用されます。
また、そうしない妥当な理由がなく、自分が何をしているのかを明確に知らない限り、常にシェル変数参照(例:および"$ADDRESS"
)を引用する必要があります。"$@"