だからシェルスクリプトで次のコマンドを実行してみました。
ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \; exit"
実行すると、次のエラーが生成されます。
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
Googleが見つけたものに基づいていくつかのバリエーションを試しましたが、問題は解決しないようです。誰でもこれに何が問題なのか教えてもらえますか?
ちなみに、ターゲットホストに手動でログインし、そこから同じfindコマンドを実行すると正常に動作します。だから私はsshコマンドの二重引用符の中にコマンドを挿入することに関連していると思います。
答え1
文法的な問題が少しありますが、それらの一つ致命的でその他これはある時点であなたを噛むことができます。
ところで、+
代替コマンドで;
この-exec
コマンドを終了できます。これはgzip
一括で実行され、少し高速です。
LOGS_DIR
値がある場合は、/somewhere/with/logs
リモートホストで次のコマンドを実行します。
cd /somewhere/with/logs; echo cd /somewhere/with/logs; find . -name *.log -mmin +1440 -exec gzip {} \; exit
または、対応するセミコロン演算子を改行文字に置き換えます。
cd /somewhere/with/logs
echo cd /somewhere/with/logs
find . -name *.log -mmin +1440 -exec gzip {} \; exit
コマンドの後に間違った内容が表示された場合は、find
どうすればよいかわかりません。これは、ユーザーがそのコンテンツを通過するパスとして意図したと誤って推測する可能性があります。コマンド区切り文字が必要です。その後に別のコマンド区切り記号を入れます(前にスペースがあるかどうか)。exit
-exec … ;
;
\;
2番目の問題は、ワイルドカードパターンが*.log
ディレクトリ内で拡張されることです/somewhere/with/logs
。一致するファイル(つまり形式のファイル/somewhere/with/logs/something.log
)が存在する場合、パターンは一致するファイルに置き換えられます。これは*.log
、リモートシェルにfindが表示できる変更されていない一致がない場合にのみ発生します。これが発生しないように、パターンの周りに引用符を追加してください。
第三の問題はの価値ですLOGS_DIR
。ローカルから文字列に展開され、リモート側でシェルスクリプトとして実行されます。したがって、シェル特殊文字(スペースなど)がある場合は、$
すべてのリモートコマンドを実行できます。ほとんどの文字を引用するための迅速で汚い方法は、変数拡張の周りに一重引用符を付けることです。これは、値に一重引用符が含まれている場合にのみ中断されます。ローカルスクリプトがbashを実行している場合は、単一引用符を4つの文字シーケンスに置き換えて'\''
値を保護できますLOGS_DIR
。
ssh -q "$CUR_HOST" "cd '${LOGS_DIR//\'/\'\\\'\'}'; find . -name '*.log' -mmin +1440 -exec gzip {} +; exit"
答え2
";"を追加するのを忘れました:
ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \;; exit"
欠落しているため、;
findはそれをexit
パスとして解釈します。