Find file then cd to that directory in Linux

The following should be more safe:

cd -- "$(find / -name ls -type f -printf '%h' -quit)"

Advantages:

  • The double dash prevents the interpretation of a directory name starting with a hyphen as an option (find doesn't produce such file names, but it's not harmful and might be required for similar constructs)
  • -name check before -type check because the latter sometimes requires a stat
  • No dirname required because the %h specifier already prints the directory name
  • -quit to stop the search after the first file found, thus no head required which would cause the script to fail on directory names containing newlines

You can use something like:

pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"
pax[/usr/bin]> _

This will locate the first ls regular file then change to that directory.

In terms of what each bit does:

  • The find will start at / and search down, listing out all regular files (-type f) called ls (-name ls). There are other things you can add to find to further restrict the files you get.
  • The piping through head -1 will filter out all but the first.
  • $() is a way to take the output of a command and put it on the command line for another command.
  • dirname can take a full file specification and give you the path bit.
  • cd just changes to that directory.

If you execute each bit in sequence, you can see what happens:

pax[/home/pax]> find / -type f -name ls
/usr/bin/ls

pax[/home/pax]> find / -type f -name ls | head -1
/usr/bin/ls

pax[/home/pax]> dirname "$(find / -type f -name ls | head -1)"
/usr/bin

pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"

pax[/usr/bin]> _