$ find -exec cd =>エラー:=> find: 'cd':そのようなファイルまたはディレクトリはありません


8

このコマンドを実行すると、機能します。

$ find . -inum 888696 -exec ls '{}' \;
Conversation.pst  Outlook Data File  Outlook Data File.sbd  Trash      Unsent Messages
Inbox.pst     Outlook Data File.msf  Sent.pst       Trash.msf  Unsent Messages.msf

ただし、それを置き換えるlsと機能cdしませ

$ find . -inum 888696 -exec cd '{}' \;
find: cd’: No such file or directory

cdbash組み込みであることを知っているので、これも機能しない次のことを試しました:

$ find . -inum 888696 -exec builtin cd '{}' \;
find: builtin’: No such file or directory

コマンドcdと一緒に使用するにはどうすればよいfind -execですか?


更新

私が使用しようとしている理由cdには、find -execディレクトリ名がどのようなものとしての私の端末上でのショーアップ奇妙1であるということです????


1
ところで、LC_ALL=C printf '%q\n' *現在のディレクトリにあるすべてのファイルのASCII名を1行ずつ(改行をに変更する$'\n'など)印刷できます。
Charles Duffy

回答:


15

-execオプションはするfind可能性がいくつかのコマンドラインオプションと他の引数を指定して、外部ユーティリティを実行します。

あなたのUnixはcd外部ユーティリティとしてではなく、シェル組み込みとしてのみ提供しているためfind、実行に失敗します。少なくともmacOSとSolaris cd外部ユーティリティとして提供しています。

cdによって検出されたパス名が、ユーザーがアクセスできるfindディレクトリであるかどうかをテストする方法を除いて、この方法で実行してもほとんどまたはまったく役に立ちませんcd。対話型シェル(またはを呼び出すものfind)の作業ディレクトリは、とにかく変更されません。

関連:


ディレクトリの名前がおかしい、または入力するのが非常に難しいという問題があり、そのディレクトリに変更したい場合は、ディレクトリへのシンボリックリンクを作成し、cdそのリンクを使用してディレクトリに移動することを検討してください。

find . -inum 888696 -exec ln -s {} thedir ';'

これによりthedir、問題のあるディレクトリを指すという名前のシンボリックリンクが作成されます。次に、作業ディレクトリを変更することができます

cd thedir

(リンクが現在のディレクトリに存在する場合)。これにより、ディレクトリの変更を回避できます。もう1つのアイデアは、と同様の方法でディレクトリの名前を変更するfindことですが、別のプログラムがディレクトリにその特定の名前を付けることを期待している場合は、お勧めできません。


私がcd一緒に使用したい理由find -execは、ディレクトリ名が私の端末に正しく表示されないいくつかの奇妙な文字であるということです。
user3405291 2018年

@ user3405291コマンドを実行したときに何が起こると予想されるかは、質問からは明らかではありません。対話型シェルでディレクトリを変更する予定ですか?
クサラナンダ

はい、不正な名前のcdディレクトリに移動したいだけで、通常の方法ではアクセスできません。cd
user3405291 2018年

@ user3405291更新を参照してください。
クサラナンダ

面白いのは、通常のビルトインがexec()にアクセスできる必要がある/bin/cdPOSIX(pubs.opengroup.org/onlinepubs/9699919799/utilities/…)の結果です。もちろん、/bin/cdおそらく人々が望むことをしないでしょう:-)
スティーブン・ハリス

7

find-execコマンド自体を実行します。シェルは含まれません。それがあったとしても、ディレクトリの変更は、シェルが終了するまで、直後にのみ持続しcdます。

ファイル名を現在のシェルにcd渡してそこに入れる必要があります。ファイル名の悪さによっては、コマンド置換を使用できます。

cd "$(find . -inum 888696)"

ファイル名が改行で終わっている場合、コマンド置換は末尾の改行を食べるため、これは機能しません。その場合、改行を保護し、find印刷時に追加されたものを取り除く必要があります。

dir=$(find . -inum 888696; echo x)
cd "${dir%?x}"

または、GNU findを使用して、末尾の改行を出力しないようにします(ただし、ファイル名のすべてを保護します)。

dir=$(find . -inum 888696 -printf "%px" -quit)
cd "${dir%x}"

また、-quit述語(これもGNU拡張機能)を使用して、最適化として最初の一致の処理を停止します。

または、から新しいシェルを起動することもできますがfind、少し見苦しいです。

find . -inum 888696 -exec bash -c 'cd "$1" && exec bash' sh {} \;

改行、改行、およびその両方で終わるディレクトリで、「エコーx」を使用してトリックを試みましたが、成功しませんでした。
Gerard H. Pille

@ GerardH.Pilleああ、すみません、find印刷時に改行自体が追加するのを忘れていました。編集。
ilkkachu 2018年

printfをprint0に置き換えると、 'cd "$ dir"'を実行できます。
Gerard H. Pille

@ GerardH.Pille、たぶん。しかし、Bashはコマンド置換からの入力のnulバイトを無視し、その後に続く末尾の改行を削除します。したがってdir=$(find -print0)、ファイル名の末尾の改行は
引き続き破棄され

5

execではありませんが、これで十分な場合があります。

cd "$(find . -inum 888696 -type d)"

確かに、「-type d」。なんだかよくわかりません。


ディレクトリの名前が改行で終わっている場合、これは失敗します。
クサラナンダ

もちろん、ディレクトリはめったにありません。Linux ext4で作成しようとすると、「プロトコルエラー」が発生します。これは時間の無駄だと思いませんか?
Gerard H. Pille

2
まあ、名前に印刷できない文字が含まれることはめったにありませんが、これは明らかにそうです。
クサラナンダ

ディレクトリ名の改行を許可するファイルシステムは何ですか?
Gerard H. Pille

1
@ GerardH.Pille、どうやってそれをテストしたの?mkdir $'foo\n'ここで完全に機能します。サポートされていないネイティブUNIXファイルシステムはまだ見たことがありません
Charles Duffy

4

NUL区切りのストリームを使用して、改行で終わる名前を含めfindすべてのケースで機能する出力を読み取ります。また、を使用printf '%q'して、ファイル名の読み取り可能な表現を生成できます。

inum=888696
if IFS= read -r -d '' filename < <(find . -inum "$inum" -print0); then
  LC_ALL=C printf 'Located filename: %q\n' "$filename" >&2
  cd -- "$filename"
else
  echo "No file located for inode $inum" >&2
fi

3

このメッセージが表示された場合、OSプラットフォームにバグがあります。POSIX標準では、という名前のコマンドcdがファイルシステムで使用できる必要があるため、を介して呼び出すことができますexec()

今あなたのための悪いニュース:

お使いのOSプラットフォームにバグがない場合でも、警告は表示されませんでしたが、別のプログラムが現在の作業ディレクトリを変更し、その後すぐに終了した場合に役立つわけではないため、期待した結果が得られませんでした。

cdによって実行されるコマンドを有効にしたい場合find持たせたい場合は、次のようにすることができます。

find . -type d -exec sh -c 'cd "$1"; some other command' dummy {} \;

2
これは、そのプラットフォームがPOSIXへの準拠を主張している場合のバグにすぎません。スタンドアロンのcdユーティリティを使用することはあまり有用ではないため、プラットフォームのユーザビリティに影響を与えることなく、そうでなければ要件を無視することは理にかなっています。パラメータ展開を引用符で囲まないままにしておくと、で特別な意味がありsh、やりたいことではないことに注意してください。インラインスクリプトのダミー値は$0、エラーメッセージなどで使用されるため(たとえば、cd失敗する場合など)、ダミー値を使用しないことをお勧めします。
ステファンChazelas

もしかしてcd "$1"?名前を入力することは困難である場合は、それもまた、シェルのメタキャラクタを含むことができ...
トビースパイツ

これはタイプミスでした
schily
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.