SSH経由で複雑なコマンドを実行するUnix / Linux

SSH経由で複雑なコマンドを実行するUnix / Linux

SSHを介してサーバーに接続し、今日のファイルを見つけて、そのファイル内でgrepを試しています。しかし、エラーが発生しますfind: missing argument to `-exec'

私がここで何を見逃しているのでしょうか?

ssh server.name find /dir1/subdir/filelist* -maxdepth 1 type f -mtime 0 -exec grep 'pattern' {} \;

答え1

コードに問題があります。

  1. ローカルシェルは、/dir1/subdir/filelist*1つ以上の一致するパスに拡張できます。これらの経路は、遠隔側に存在しても存在しなくてもよい。

  2. ssh取得した複数のパラメータに基づいてシェルコードをローカルでビルドします(リモート側で実行)。主張は次のとおりです。

    • find
    • /dir1/subdir/filelist*(ローカル一致がない場合)
    • -maxdepth
    • 1
    • -typetype(タイプミスをしたと思います)
    • f
    • -mtime
    • 0
    • -exec
    • grep
    • pattern(ローカルシェルに引用符がないため)
    • {}
    • ;(ローカルシェルはバックスラッシュを使用しているため)

    ビルドするシェルコマンドは次のとおりです。

    find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep pattern {} ;
    

    find(リモート)シェルはこれを;コマンドターミネータとして解釈して;到達できないため、有効なコマンドではありませんfind。また、patternリモートシェルのコンテキストではは引用されません。

私はこれがまさにリモート側のシェルで実行したいコマンドだと思います。

find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;

バラよりSSH経由で複雑なコマンドラインを実行する方法そして私の答え。ここではすべての内容を繰り返すことはありません。最も重要なもの:

リモートシェルの取得を制御するには、$command_line_built_by_ssh以前に発生した解析と解釈を理解、予測、調整する必要があります。ローカルコマンドを発行する必要があるため後ろにsshローカルシェルを実行してそれを消化すると、リモート側で実行したい内容が正確になります。$command_line…

ssh基本的な解決策は、正確な(リモート)コマンドを単一の引数としてローカルに渡すことです。あなたの場合、ローカルコマンドは次のとおりです。

ssh server.name 'find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep '\''pattern'\'' {} \;'

関連する質問への回答で、いくつかのより多くのアイデアを議論します。

答え2

これはsshコマンドで複数のコマンドを実行するのではなく、より複雑なfindコマンドを実行することです。

これには2つの主な問題があります。

  • コマンドの作成方法に応じて、glob パターンがクライアントで評価されます。
  • ;コマンドに到達できなかったため、エラーメッセージが表示されますfind。デフォルトでは、sshパラメータを接続してsh -cサーバーに渡します。あなたはそのようなものが必要です\\\;

サーバーにstdinが必要ない限り、最も簡単な解決策はstdinのコマンドをシェルに送信することです。これにより、引用符は必要ありません。

ssh server.name /bin/sh <<'EOF'
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;
EOF

関連情報