SSH find コマンドがローカル変数に格納されているディレクトリを認識しません。

SSH find コマンドがローカル変数に格納されているディレクトリを認識しません。

SSHを介してローカル変数に格納されているディレクトリにアクセスできます$out_dir。しかし、なぜこのfind | headコマンドが機能しないのかわかりません。存在する試み #2、コマンドの最後に2番目のバックスラッシュを追加しましたfind

試行#1エラー: find: `/dir/on/remote/server': No such file or directory

ssh $user@$ip << EOF
    discard=$( find $out_dir -exec basename {} \; | head -n -1 )
    for f in $discard; do
        echo "rm $f"
    done
    logout
EOF

試み #2 エラー: syntax error near unexpected token `|'

ssh $user@$ip << EOF
    discard=$( find $out_dir -exec basename {} \\; | head -n -1 )
    for f in $discard; do
        echo "rm $f"
    done
    logout
EOF

ベストアンサー1

試行#1で「ファイルまたはディレクトリがありません」というメッセージが表示されるのは、<<EOFheredoc(the)のすべての変数とコマンド補間がリモートホストに送信される前にローカルで実行されるためです。

正しく気づいたように$out_dir補間が進んでいます。見たいディレクトリが表示されます。これはSSH呼び出しを行う前にローカルコンピュータで発生します。コマンドの置き換え($())もローカルで発生します(ただしリモートで実行しようとしています)。つまり、全体の検索結果は、リモートコンピュータに送信される前にローカルに処理されます。ここに含まれるすべての内容は$()heredocによって処理されます。したがって、${out_dir}ローカルコンピュータには存在しないようです。 「該当するファイルやディレクトリはありません。」

これをよりよく理解したい場合は、この例を単純化してみましょう。この試み:

$ ssh foo@localhost <<EOF
  echo "using account: $(whoami)"
EOF                            
Pseudo-terminal will not be allocated because stdin is not a terminal.
<truncated>
using account: vagrant

私のローカルアカウントは「vagrant」なので、明らかに$()の内容はローカルで実行されます。正常に機能した場合、アカウントは「foo」になりますssh foo@localhost

";"代わりに「\」をエスケープしたため、試行#2が中断されました。 Findを-exec終了する必要がありますが、今ではありません。代わりに、コマンドは突然、bashコマンドを終了する吊り下げ";"で終了します。 '|'は一部の入力が渡されると予想していますが、何も指定されていません。効果的に以下を生成します。

$ | cat
-bash: syntax error near unexpected token `|'

それでは、考えられる解決策は何ですか?

まあ、find削除することができます:

ssh $user@$ip <<EOF
  find $out_dir -delete
EOF

シンプルでシンプルです。特定のファイルを選択して他のファイルを除外することを心配している場合find

find現在のバージョンでは、いくつかの極端なケースを処理しようとしているので、"修正"提案を提供します。

  • デフォルト名の使用
  • 何かの目的を指します。head -n -1

しかし、私はこれがあなたが期待するように働くとは思わない。

まず、呼び出しはbasenameほとんどのパスを削除し、sshコマンドでディレクトリを変更するために何もしません。 SSH実行は、$ {user}の家に関連するすべてを削除しようとします。 ${out_dir}を指定するときに家以外のディレクトリを使用したいようです!今回もfind削除作業を行ってみましょう。

第二に、私は誤解しているかもしれませんが、ターゲットhead -n -1ファイルのリストから$ {out_dir}を削除したことがあるようです。

$ find junk/
junk/
junk/one
junk/two
junk/three

そうですね。を削除したくありませんjunk/

ただし、次のことを試してください。

$ seq 1 4
1
2
3
4
$ seq 1 4 | head -n -1
1
2
3

最初の行は保持されず、最後の行は維持されます。尾を試してみてください:

$ seq 1 4 | tail -n +2
2
3
4

しかし、もう一度申し上げますが、findそれを取り除くのを手伝います。

ファイルの削除のみが必要な場合は確認してください-type f。ただし、高度なフィルタリング用の除外モードと埋め込みモードもあります。

おすすめ記事