0

https://stackoverflow.com/questions/25802017/bash-shell-search-for-subfolder-in-current-dir-and-cd-into-it

would like to implement this, as I don't want to tabcomplete.

when I type the command:

cd `find . -name test -type d`

I get this error:

find: ./usr/sbin/authserver: Permission denied

I've tried cd'ing with fzf and ranger. but it's all a mess.

Also I thought the reason behind the error turning up is because the folder is hidden but it doesn't work with visible folders either ...

hal3m
  • 13
  • You would get an error from find for any directory that you don't have access to, that's not strange and may be ignored by redirecting the standard error to /dev/null. However, it's not clear what you want to do when there are multiple test directories or when any of the found directories are located under a path containing spaces. If you're using zsh, you also have access to the ** glob and therefore probably don't need to use find at all. – Kusalananda Jan 22 '23 at 16:38
  • Um, sudo cd \find . -name test -type d`` – rando Jan 22 '23 at 16:54
  • I get some wild behaviour then.

    sudoing doesn't work

    – hal3m Jan 22 '23 at 17:05
  • don't know what to do with ** , sorry noob here – hal3m Jan 22 '23 at 17:06
  • 1
    @rando What is that going to achieve? The find process would run and finish running before sudo cd is executed, and sudo cd would definitely not work (requires cd to be an external executable, and would not be able to change the working directory for the user's original shell, only for the sudo shell, which terminates immediately). – Kusalananda Jan 22 '23 at 17:59
  • It's still unclear how you want to handle the cases I mentioned, i.e. 1) multiple directories called test are found, and 2) the pathname to the found directory or directories contain spaces, tabs or newlines. – Kusalananda Jan 22 '23 at 18:00

1 Answers1

0

The error is by find telling you that it's unable to find files in that directory as it doesn't have permission to read or enter it.

That

cd `find . -name test -type d`

syntax is wrong anyway as it's splitting the output of find on any character of $IFS instead of just newline (not to mention that there's nothing stopping file paths from containing newline characters), and may end up passing more than one argument to cd.

In zsh, you'd rather do:

cd ./**/test(/[1])

Which would cd into the first (in alphabetical order) directory under any level of subdirectories whose name is test, ignoring hidden ones.

Glob expansions ignore errors upon crawling the directory tree, though in zsh, you can check for errors using the special $ERRNO variable which holds the error number value from the last failing system call that the shell made.

In any case, doing sudo cd as you mentioned in comment doesn't make sense. cd is a builtin command of the shell to change the working directory of the shell process. sudo is an external command to run a command as a different user (switch user do). Some systems do have a standalone cd utility (it's even required by POSIX), but all it does is change the current directory of its own process and then exits that process, so it won't help you change the current working directory of the current shell process.

zsh has builtin support to change effective user id, but it's still within the limits as set by the system. For instance, a zsh process running as root would be able to change its effective uid to anything and back to root again:

# id -un
root
# EUID=1000
$ id -un
chazelas
$ EUID=0
# id -un
root

But not after you've set $UID or $USERNAME (which also sets uid, gid and additional gids).

It should be possible in theory to change the current working directory of a process to some directory they don't have access to via the help of a setuid helper (such as sudo) using a special file descriptor passing mechanism, but I don't know of any shell with support for that. And in any case, once you've managed to cd there, you wouldn't be able to do anything with the files there, so it wouldn't be of any help:

$ cd /var/spool/cron/crontabs
cd: permission denied: /var/spool/cron/crontabs
$ sudo zsh
/home/chazelas# cd /var/spool/cron/crontabs
/var/spool/cron/crontabs# USERNAME=chazelas
/var/spool/cron/crontabs$

I now have an unprivileged shell with /var/spool/cron/crontabs, a restricted directory as its current working directory.

/var/spool/cron/crontabs$ pwd
/var/spool/cron/crontabs
/var/spool/cron/crontabs$ ls
ls: cannot open directory '.': Permission denied

If you need to do things in a shell from within a restricted directory, you'll likely want to start a shell as a user with access to that directory. For example:

sudo sh -c 'cd /restricted/dir && do-something-there'

Some implementations of the env command can also chdir() to some directory before executing a command there which would save having to invoke a shell:

sudo env -C /restricted/dir do-something-there

(above assuming the default target user for sudo (generally root) has access to /restricted/dir, use the -u option to specify the user).