ローカルコンピュータからアプリケーションログを収集し、リモートコンピュータからアプリケーションログを収集するスクリプトを作成しました。
oldlogsdate
収集したいログの日付を読み取る変数があります。
たとえば、入力するとApr 23
空白が 1 つだけなので正常に動作しますが、入力すると (その間にApr 4
2 つの空白がある場合)、1 つの空白が削除されます。Apr
4
注:これはoldlogsdate
ユーザーのリモートコンピュータにも設定され、.bash_profile
入力された日付はコマンドを使用して変更されますsed
。
printf "\n";read -p "Which Date Logs you want to collect = " oldlogsdate
ssh -qt [email protected] "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile"
oldlogsdate="Apr 7"
これを使用する理由Apr 23
はApr 4
コマンドの一部ですls
。
読み取りコマンドで二重スペースを保持する方法はありますか、それとも他のより良い方法がありますか?
答え1
ssh
相手に送信するコマンドの一部であるコマンドラインに注意してください。sed
ssh ... "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile"
^^^^^^^^^..................................................^^^^^^^^^^^^^^^^^^
以下は、で示される2つの引用文字列です^
。途中に残っているのは次のとおりです。いいえ変数拡張を含む参照$oldlogsdate
。記載されていないので適用対象となります。噴射、とはApr 7
2つの単語にApr
なります7
。また見なさい:いつ二重引用符が必要ですか?
これでssh
それらを再貼り付けることができるほどスマートになりましたが、今は元のスペースサイズが消えてスペースが1つだけ追加されます。
これは、シェルが空白の元の量を忘れて、echo
単語を単一の空白にまとめる方法と多少似ています。
$ echo hello world
hello world
ただし、SSHを使用すると、SSHは解釈のためにコマンドラインをリモート側のシェルに渡し、そのシェル内の単語間の余分なスペースも失われるため、一重引用符は役に立ちません。
だからこれはまだ動作しません:
$ ssh localhost echo "hello world"
hello world
(ローカルシェルは引用符を削除してsumをssh
取得し、上記のように動作するリモートシェルに渡します。)echo
hello world
echo hello world
文字列をそのままにするには、実際に両端を引用する必要があります。
$ ssh localhost 'echo "hello world"'
hello world
printf ":%s\n" hello world
実際、breakという単語の位置をより正確に表示するには、背中を使用する方が良いですが、結果は似ています。
二重引用符が最も外側になるように引用符を切り替えて、ローカルシェルで変数を拡張し、リモートシェルに一重引用符を残して拡張を最小化します。もう一方の端に送る二重引用符をバックスラッシュでエスケープする必要があります。
$ greeting="hello world"
$ ssh localhost "echo '$greeting'"
hello world
変数自体に一重引用符が含まれていない場合は機能します。その場合、状況はさらに悪化します。以下を参照してください。他のスクリプトの内容として使用するために変数をエスケープする
私の考えでは、コマンドライン@サシャの答えあなたの場合には効果があるようです。
たとえば、次の質問も参照してください。ssh $host $FOO および ssh $host "sudo su user -c $FOO" タイプ構成で参照されます。 当面の問題はもっとしかし、その答えは「より単純な」場合にも当てはまるようです。
答え2
読み取りコマンドは二重スペースを削除し、1つだけを保持します。
しかし、実際にはそうではありません。コマンドread
自体は内部スペースを変更せずに残します(ただし、スペースにIFS
設定しない限り、前後にスペースを切り取ります。バックスラッシュを使用しないと、バックスラッシュも混乱します-r
)。
read myVar <<<'Apr 4'
echo "$myVar" # will output: Apr 4
つまり、変数の周りに二重引用符がないため、スペースは失われます。
myVar2='Apr 4'
echo $myVar2 # will mangle spaces, please always use "$myVar2" instead
変数を誤って参照すると、スクリプトが予期せず動作するだけでなく、潜在的なセキュリティリスクが発生する可能性があります。
少しより正確なコマンドは
ssh -qt [email protected] "sed -i 's/oldlogsdate=.*/oldlogsdate=\"$oldlogsdate\"/' ~/.bash_profile"
$oldlogsdate
しかし、普遍的ではなく、値に空白だけでなく、アポストロフィ、スラッシュ、バックスラッシュ、ドル記号、感嘆符も含めることができることを考慮していないため、安全ではありません。