2016-04-30 14 views
3

のエスケープが正しく引用されたとエスケープになりますは、次のコマンドを引用し、sshコマンドライン

$ echo -e ssh -q rmthost 'bash -c "ps -ef|grep '\'''\\\<'defunct'\\\>''\''|grep -v grep|awk '\'''{print \$1}''\'' "' 
ssh -q sbpsvrwm757 bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}' " 

のが、実行されると、結果が期待されているものではありません。

$ ssh -q rmthost 'bash -c "ps -ef|grep '\'''\\\<'defunct'\\\>''\''|grep -v grep|awk '\'''{print \$1}''\'' "' 
    root16986 16982 0  - ?   0:01 <defunct> 

awkコマンドのdidn右の列を抽出するようだ。

は今、私はSiguzaによって提供されたリンクをたどっと思い付いた:

$ echo ssh -q rmthost "'"bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'"'" 
ssh -q rmthost 'bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}'"' 

完璧すぎて脱出し、まだ動作しません見えること:

$ ssh -q rmthost "'"bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'"'" 
Missing } 

または、

$ echo ssh -q rmthost bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"' 
ssh -q rmthost bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}'" 
$ ssh -q rmthost bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"' 
    root 16986 16982 0  - ?   0:01 <defunct> 

または

$ echo ssh -q rmthost "bash -c \"ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print \$1}'\"" 
ssh -q rmthost bash -c "ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print $1}'" 
$ ssh -q rmthost "bash -c \"ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print \$1}'\"" 
    root 16986 16982 0  - ?   0:01 <defunct> 

理由は何ですか?

> /var/tmp/1.ouy 2> & 1のように、bashスタイルの出力リダイレクトを有効にするにはbash -cが必要です。

あなたのご協力をお待ちしております。

+0

ありがとうございました。私はそのルールに従っていますが、それでも動作させることはできません。上記の更新を参照してください – AlexL

+0

'ssh rmthost" ps -ef | grep \ "\ \" | grep -v grep | awk '{print \ $ 1}' "'に何が間違っていますか? sshに引数を二重引用符で囲むことで、すべての厄介なことを避けることができます。 –

+0

また、 'bash -c'はここでは冗長です。 sshはコマンド文字列をシェル自体に送り、エスケープするレベル全体を保存します。 –

答えて

0

正直言って、あなたが書いたコードは読めません。それはあまりにも難読化されていると私はそれを把握するために30分持っていない。そのためには、良いコードではない可能性が高いです。

このような引用符は、デコードの複数のレイヤーを理解しようとすると非常に混乱します。だからあなたの引用符を修正しようとするのではなく、私は同じ結果を持つきれいなコードを証明しようとします。

ssh rmthost "bash -c \"ps -ef | grep '<defunct>' | grep -v grep | awk '{print \\\$2}'\"" 

# The remote system will execute this: 
bash -c "ps -ef | grep '<defunct>' | grep -v grep | awk '{print \$2}'" 

# Which in tells bash to execute this: 

ps -ef | grep '<defunct>' | grep -v grep | awk '{print $2}' 

しかし、なぜ一部のexessive grepのパイプを削除しようとしません。 awkはあなたのためのフィルタリングを行うことができます。私は<defunct>が行末に現れると仮定しています。そうなら、あなたは、単に使用することができます。

ssh rmthost "bash -c \"ps -ef | awk '/<defunct>\\\$/ {print \\\$2}'\"" 

# the remote system executes this: 
bash -c "ps -ef | awk '/<defunct>\$/ {print \$2}'" 

# bash executes this: 
ps -ef | awk '/<defunct>$/ {print $2}' 

またはより良いまだ、ゾンビプロセスのためのZされるps -elで第二のカラムを使用します。ここでは

ssh rmthost "bash -c \"ps -el | awk '/^. Z/{print \\\$4}'\"" 

# the remote system executes this 
bash -c "ps -el | awk '/^. Z/{print \$4}'" 

# bash executes this: 
ps -el | awk '/^. Z/{print $4}' 
+0

です。最初のコマンドでは" Variable syntax "エラーが表示され、1行目では" awk:syntax error " awk:1行目付近に不正な文があります。 "です。 – AlexL

+0

それは非常に奇妙です、私のシステムで正常に動作します。私は平らな例で編集しました。私はリモートシステムにログオンし、最初に動作することを確認することをお勧めします。これは非常に単純な 'awk'構文なので、何もawkで間違っているとは思われませんが、引用符を平滑化して何かが起こっているように思えます。 –

0

は一緒に遊んによって作業のソリューションです引用:

ssh -q rmthost "bash -c 'ps -ef|grep ''''\<'defunct'\>''''|grep -v grep|awk "'"{print \$2}"'" '" 

しかし、私自身はメカニズムをよく理解していません:-)。一重引用符と二重引用符を入れ替えても機能しません。

+0

あなたの '匹敵しない'エラーを再現することができません。私は今、解決策を持っているようです。 –

関連する問題