When I run this command it works:

$ 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

However, When replacing ls with cd it does not work:

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

I know cd is a bash built-in, so I tried this which does not work either:

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

How can I use cd along with find -exec command?


The reason I'm trying to use cd with find -exec is that the directory name is a strange one which shows up on my terminal as something like ????.

  • 1
    BTW, you can LC_ALL=C printf '%q\n' * to print ASCII names for all files in your current directory, one to a line (changing newlines to $'\n' or similar). Commented Jun 5, 2018 at 19:53

5 Answers 5


The -exec option to find executes an external utility, possibly with some command line option and other arguments.

Your Unix does not provide cd as an external utility, only as a shell built-in, so find fails to execute it. At least macOS and Solaris do provide cd as an external utility.

There would be little or no use for executing cd in this way, except as a way of testing whether the pathname found by find is a directory into which you would be able to cd. The working directory in your interactive shell (or whatever is calling find) would not change anyway.


If you're having issues with a directory's name being strange or extremely difficult to type, and you want to change into that directory, then consider creating a symbolic link to the directory and then cd into it using that link instead:

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

This would create a symbolic link named thedir that would point to the problematic directory. You may then change working directory with

cd thedir

(if the link exists in the current directory). This avoids modifying the directory in any way. Another idea would be to rename the directory in a similar way with find, but that would not be advisable if another program expects the directory to have that particular name.

  • The reason I intent to use cd with find -exec is that the directory names are in some strange characters which don't show up correctly on my terminal.
    – Megidd
    Commented Jun 5, 2018 at 11:29
  • @user3405291 It is not clear from the question what you expect to happen when you run the command. Do you expect to change directory in the interactive shell?
    – Kusalananda
    Commented Jun 5, 2018 at 11:30
  • Yes, I just want to cd into a directory which has a bad name, and I cannot cd into it in a normal way.
    – Megidd
    Commented Jun 5, 2018 at 11:32
  • @user3405291 See update.
    – Kusalananda
    Commented Jun 5, 2018 at 11:36
  • What's funny is that /bin/cd is a result of POSIX (pubs.opengroup.org/onlinepubs/9699919799/utilities/…) where the normal builtins have to be accessible to exec(). Of course, /bin/cd likely doesn't do what people want :-) Commented Jun 5, 2018 at 11:37

find runs the -exec command itself, it doesn't involve a shell. Even if it did, the change of directory would only persist until that shell exited, immediately after the cd.

You'll need to get the filename out to the current shell to cd into it. Depending on how bad your filenames are, you could use command substitution:

cd "$(find . -inum 888696)"

That won't work if the filename ends in a newline, as command substitution eats trailing newlines. In that case you'd need to protect the newline and get rid of the one find adds when printing:

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

Or, with GNU find, have it not print the trailing newline (but still protect any in the filename):

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

Also using the -quit predicate (also a GNU extension), to stop looking after the first match as an optimisation.

Alternatively, you could start a new shell from within find, but it's a bit ugly:

find . -inum 888696 -exec bash -c 'cd "$1" && exec bash' sh {} \;
  • Tried your trick with the "echo x", on directories ending with newline, carriage return and both, without success. Commented Jun 5, 2018 at 12:13
  • @GerardH.Pille, oh, sorry, I forgot the newline find itself adds when printing. Edited.
    – ilkkachu
    Commented Jun 5, 2018 at 12:22
  • If you replace the printf by a print0, you can do ' cd "$dir" '. Commented Jun 5, 2018 at 12:51
  • @GerardH.Pille, perhaps. But Bash ignores any nul bytes in input from a command substitution, and removes the trailing newline only after that. So dir=$(find -print0) will still trash the trailing newline of the filename...
    – ilkkachu
    Commented Jun 5, 2018 at 13:00

Not with exec, but this may be good enough for you:

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

The "-type d", just to be sure. Of what, I don't really know.

  • This fails if the directory's name ends with a newline.
    – Kusalananda
    Commented Jun 5, 2018 at 11:39
  • Sure, but directories rarely do. If I try to create one on a linux ext4, I get "protocol error". Don't you think this is a waste of time? Commented Jun 5, 2018 at 11:43
  • 2
    Well, names rarely have unprintable characters, but this one obviously do.
    – Kusalananda
    Commented Jun 5, 2018 at 11:48
  • What filesystems allow newlines in directory names? Commented Jun 5, 2018 at 11:52
  • 1
    @GerardH.Pille, how did you test that? mkdir $'foo\n' works perfectly here; I've yet to see a native UNIX filesystem where it wasn't supported. Commented Jun 5, 2018 at 17:25

Use a NUL-delimited stream to read output from find that works in all cases -- including names that end in newlines. Also, you can use printf '%q' to generate a readable representation of a filename.

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

If you get this message, then your OS platform is buggy. The POSIX standard requires that a command named cd must be available in the file system so it may be called via exec().

Now the bad news for you:

Even if your OS platform was not buggy, you just did not see a warning, but you did not get your expected results, since it does not help you if a separate program changes its current working directory and immediately dies after that.

If you like to have an effective cd in a command executed by find, you may do something like:

find . -type d -exec sh -c 'cd "$1"; some other command' dummy {} \;
  • 2
    That is only a bug if that platform claims POSIX conformance. Having a standalone cd utility is not very useful, so it makes sense to ignore that requirement otherwise without it affecting the usability of the platform. Note that leaving a parameter expansion unquoted has a very special meaning in sh, not something you'd want to do. It's better to avoid dummy values for that inline script's $0 as that's used in error messages for instance (like when that cd would fail). Commented Jun 5, 2018 at 12:34
  • Did you mean cd "$1"? If the name is hard to type, it may well also contain shell metacharacters... Commented Jun 6, 2018 at 11:21
  • correct this was a typo
    – schily
    Commented Jun 6, 2018 at 11:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .