このコマンドを実行すると、機能します。
$ 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
に置き換えるとnotが機能します。
$ find . -inum 888696 -exec cd '{}' \;
find: ‘cd’: No such file or directory
私はcd
がbash
組み込みであることを知っているので、これを試してnotのいずれかを実行します:
$ find . -inum 888696 -exec builtin cd '{}' \;
find: ‘builtin’: No such file or directory
cd
をfind -exec
コマンドと共に使用するにはどうすればよいですか?
find -exec
でcd
を使用しようとしているのは、ディレクトリ名が????
のように端末に表示される奇妙な名前であるためです。
-exec
オプションをfind
に追加すると、コマンドラインオプションやその他の引数を使用して、外部ユーティリティが実行されます。
Unixはcd
を外部ユーティリティとして提供せず、シェル組み込みとしてのみ提供するため、find
はそれを実行できません。少なくともmacOSとSolarisdoはcd
を外部ユーティリティとして提供します。
このようにcd
を実行しても、find
で検出されたパス名がcd
。インタラクティブシェル(またはfind
を呼び出すもの)の作業ディレクトリは、いずれにしても変更されません。
関連:
ディレクトリの名前がおかしい、または入力が非常に難しいという問題があり、そのディレクトリに変更したい場合は、ディレクトリへのシンボリックリンクを作成し、そのリンクを使用してcd
を作成することを検討してください。 :
find . -inum 888696 -exec ln -s {} thedir ';'
これにより、問題のあるディレクトリを指すthedir
という名前のシンボリックリンクが作成されます。次に、作業ディレクトリを変更できます
cd thedir
(リンクが現在のディレクトリに存在する場合)。これにより、ディレクトリの変更を回避できます。別のアイデアは、find
を使用して同様の方法でディレクトリの名前を変更することですが、別のプログラムがディレクトリにその特定の名前を付けることを期待している場合は、お勧めできません。
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 {} \;
Execではありませんが、これで十分な場合があります。
cd "$(find . -inum 888696 -type d)"
確かに「-type d」。なんだかよくわかりません。
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
このメッセージが表示された場合、お使いのOSプラットフォームにバグがあります。 POSIX標準では、cd
という名前のコマンドをファイルシステムで使用できるようにして、exec()
。
今あなたにとって悪いニュース:
お使いのOSプラットフォームにバグがない場合でも、警告は表示されませんでしたが、別のプログラムが現在の作業ディレクトリを変更してすぐに終了した場合に役立つわけではないため、期待した結果が得られませんでした。
cd
によって実行されるコマンドで効果的なfind
を使用したい場合は、次のようにします。
find . -type d -exec sh -c 'cd "$1"; some other command' dummy {} \;