web-dev-qa-db-ja.com

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

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

$ 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

ただし、lscdに置き換えるとnotが機能します。

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

私はcdbash組み込みであることを知っているので、これを試してnotのいずれかを実行します:

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

cdfind -execコマンドと共に使用するにはどうすればよいですか?


更新

find -execcdを使用しようとしているのは、ディレクトリ名が????のように端末に表示される奇妙な名前であるためです。

8
user3405291

-execオプションをfindに追加すると、コマンドラインオプションやその他の引数を使用して、外部ユーティリティが実行されます。

Unixはcdを外部ユーティリティとして提供せず、シェル組み込みとしてのみ提供するため、findはそれを実行できません。少なくともmacOSとSolarisdocdを外部ユーティリティとして提供します。

このようにcdを実行しても、findで検出されたパス名がcd。インタラクティブシェル(またはfindを呼び出すもの)の作業ディレクトリは、いずれにしても変更されません。

関連:


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

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

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

cd thedir

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

15
Kusalananda

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 {} \;
7
ilkkachu

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

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

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

5
Gerard H. Pille

NUL区切りのストリームを使用して、findから出力を読み取ります。これは、改行で終わる名前を含むallの場合に機能します。また、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
4
Charles Duffy

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

今あなたにとって悪いニュース:

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

cdによって実行されるコマンドで効果的なfindを使用したい場合は、次のようにします。

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