SSHを介してサーバーに接続し、今日のファイルを見つけて、そのファイル内でgrepを試しています。しかし、エラーが発生しますfind: missing argument to `-exec'
。
私がここで何を見逃しているのでしょうか?
ssh server.name find /dir1/subdir/filelist* -maxdepth 1 type f -mtime 0 -exec grep 'pattern' {} \;
答え1
コードに問題があります。
ローカルシェルは、
/dir1/subdir/filelist*
1つ以上の一致するパスに拡張できます。これらの経路は、遠隔側に存在しても存在しなくてもよい。ssh
取得した複数のパラメータに基づいてシェルコードをローカルでビルドします(リモート側で実行)。主張は次のとおりです。find
/dir1/subdir/filelist*
(ローカル一致がない場合)-maxdepth
1
-type
type
(タイプミスをしたと思います)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