105

I tried to use sudo cd name_of_dir but am getting the error message:

sudo: cd: command not found

Is there any other way to enter a directory owned by another user which has 700 permission?

Zanna
  • 70,465
Bakhtiyor
  • 12,254
  • 2
    please add an ls -l of the directory itself. – Rinzwind Aug 19 '11 at 11:12
  • 8
    And please explain why you keep leaving negative comments against the valid answers here. If you think there is (or should be) a better way, please let us know what it might be. – Oli Aug 19 '11 at 12:29
  • 1
    sudo chmod 0755 name_of_dir; do you business; cd ../; sudo chmod 0700 name_of_dir Seems to be the only answer you'll be happy with. – Marco Ceppi Aug 19 '11 at 13:31
  • @Oli. I was just giving my PERSONAL opinion. If I knew other way of doing that I wouldn't ask it here. I am looking for it. As I see it is almost impossible, BUT there is nothing impossible at all. – Bakhtiyor Aug 19 '11 at 14:44
  • 1
    please add an ls -l of the directory itself... – Rinzwind Aug 19 '11 at 16:28
  • 3
    The answers given here are correct, but you are voting them down and saying they are wrong. Don't just dismiss what is being said because of something else you have seen. – Richard Holloway Aug 19 '11 at 16:33
  • 3
    That is funny... he wants sudo cd to work, but he votes down solutions using sudo or su. He says he doesnt want to work as root, but he still wants to access a directly he doesnt own. Sounds like a troll to me... – MestreLion Aug 19 '11 at 23:49

8 Answers8

133

sudo cd won't work because the cd command is built into the shell. So you are saying become root and then run this command. You become root and then the command after sudo is searched for but there is no cd command to find.

The method to use is to switch to the user that owns the directory. Permission 700 is meant as "owner can read, write and execute".

So if root owns the directory sudo -i, password and then cd {dir} is the only correct method. If someone else owns the directory you can still use the 1st method but can also change to that user with su {username} and then use cd as that user.

Rinzwind
  • 299,756
  • Side question: will root be able to enter a 700 dir even if he is not the owner? – MestreLion Aug 19 '11 at 23:38
  • 3
    yes MestreLion,700 will not stop root from enterting. Permissions '000' will stop the user from entering himself (yes, a user can create a dir he himself can not enter...) but still root can enter that one. – Rinzwind Aug 20 '11 at 06:28
  • 1
    echo is a shell build-in command, why I can run "sudo echo" but not "sudo cd"? – shoujs Aug 31 '16 at 02:09
  • Sorry, same rules apply to sudo echo: you need something like echo 'deb {text}' | sudo tee --append {file} to use echo with sudo and to change a file. – Rinzwind Aug 31 '16 at 06:45
  • 1
    Why isn't cd built into the commands available to sudo, though? – Aaron Franke Nov 23 '16 at 06:55
  • @shoujs sudo echo runs /bin/echo instead of the echo shell builtin. (Rinzwind's comment is correct, though, as applied to the common situation of echo with output redirection. sudo echo text... >> file isn't what you want since the shell, which is running as you, does the redirection. echo text... | sudo tee -a file is a common workaround.) – Eliah Kagan Dec 11 '17 at 00:36
  • Note that sudo -i is equivalent to sudo su - in that it runs a login shell as the superuser. – thomasrutter Dec 12 '17 at 13:15
  • Also, the equivalent of sudo -i when the "target user" is not root is sudo -iu username. – fkraiem Dec 14 '17 at 05:48
  • So this is a limitation (if you can call it that) of the sudo command right? Because it simply looks for executables in the /bin et al. directories? I wonder why there isn't something like suba for running bash internals. – Usagi Jul 03 '18 at 17:21
55

sudo -i

to open "root console" and then

cd /path/to/directory

(cd is a shell builtin command, so it can't be the sudo target)

21

To open a root directory we may run a root shell, e.g.:

sudo su
# cd /root
Takkat
  • 142,284
  • 3
    I wouldn't like to work as a root. NEVER!!! And also experts recommend never login as a root. -1 – Bakhtiyor Aug 19 '11 at 11:10
  • 8
    Well that's exactly why you don't want permissions to open root's directories, isn't it? – Takkat Aug 19 '11 at 11:12
  • 11
    There is nothing wrong going into root mode. Experts will always recommend going into root when it is -needed-. – Rinzwind Aug 19 '11 at 11:15
  • 1
    Experts? Never seen expert recommending such stupid thing... Only thing that is not recommended is login to graphical interface as root (and this is also impossible in Ubuntu). – Vojtech Trefny Aug 19 '11 at 11:16
  • 2
    If you're working with things owned by root, sometimes sudo suing (or another method) is the only practical or even possible method. "Experts" only tell you to not use root as a habit - it's fine when you actually need it. And @Vojtech, nothing's impossible... – Oli Aug 19 '11 at 12:21
  • 1
    Never do a GUI login as root, or allow root to remotely login (as its the easiest login name to guess for brute-force attacks), but its perfectly fine to use sudo su - to root when you need to do plenty of things as root. Its no more dangerous than typing sudo before each and every command. You probably should remember to be careful just like with normal sudo, and maybe particularly careful to remember to log out; but really there's no extra danger. – dr jimbob Aug 19 '11 at 21:00
  • 3
    @Bakhtiyor: working the whole time as root is indeed not recommended. But issuing it for a single (or a few) commands is acceptable. Specially if you're trying to enter a directory that you your user has no permission to. So you need to be either the owner or the root. – MestreLion Aug 19 '11 at 23:52
  • sudo will also log what commands are run through it and who uses them. If you use "sudo su", you don't get this feature. (this isn't saying that "sudo su" is bad. If you need it, use it. And I sometimes use it when I keep pre-pending every command with sudo). – Jonathan Sternberg Aug 20 '11 at 14:06
11

As others pointed out -- it's shell built-in:

~ % which cd
cd: shell built-in command

So, why don't you sudo the shell itself?

~ % sudo $SHELL -c "cd name_of_dir"
  • 5
    +1 for the sudo bash -c idea... and a suggestion: avoid using which. Its merely a script, and it wont handle all possibilities (binary, builtin, aliases, etc). Use type instead. Much safer, powerful and portable. And type -p for the path of an executable. – MestreLion Aug 19 '11 at 23:44
  • 1
    Well, depends ;-) type [ -wfpams ] name ... Equivalent to whence -v., which [ -wpams ] name ... Equivalent to whence -c. (man zshbuiltins) – Daniel Bauke Aug 20 '11 at 14:08
  • 1
    It does not depend. whenceis zsh-only... it does not work in bash, it is not even installed by default in ubuntu. While type is POSIX, meaning it will work in any modern shell... bash, csh, ksh.. and even zsh. – MestreLion Aug 21 '11 at 16:35
  • Sure, it is and that's why I upvoted your comment just when it appeared, but what I ment was that in zsh actually it's not a script and gives similar results as type as both are aliases to the same command. – Daniel Bauke Aug 21 '11 at 20:26
  • Oh, I understand now. Well, but thats in zsh. In bash, which is the default (and usually only) terminal shell in Ubuntu, which is not a builtin... so type(or type -p) is preferred. – MestreLion Aug 23 '11 at 04:34
  • This do not work, because the cd remain in effect only until the end of the script (consisting only of the cd command). – enzotib Aug 23 '11 at 23:09
  • enzotib: The question was how to enter a directory and my response answers it. Nothing prevents you to use sudo $SHELL -c 'cd name_of_dir && ls *.txt ; for x in *.txt ; do rm "$x" && echo "just erased $x" ; done' – Daniel Bauke Aug 24 '11 at 04:23
7

You can also elevate yourself to root user by:

sudo -s

Then you can cd to any directory which doesn't allow normal user in like:

cd /root

Or

cd /var/lib/

Then after you're done in there type:

exit

To logout of the root user privileges.

For elevating yourself as root, you can also combine the two commands by && operator as below, this operator also maintains their execution sequence, if current command executes successfully and only then the next command is allowed to execute:

sudo -s && cd /var/lib

Or

sudo -s && cd /root
Vicky Dev
  • 433
3

If you really want to make sudo cd directory work, you can define a bash shell function called sudo that runs a new root shell when run that way, and just runs the regular sudo command otherwise.

As presented in other answers, most users will not want to bother doing that, but will instead want to:

  1. Run sudo -s, or sudo -i if you want a login shell (remember that one effect of sudo -i is to start you out in root's home directory), or sudo bash if you want to force bash or be able to pass options to the shell.
  2. Run cd directory in the new shell.
  3. Perform whatever (other) actions need to be taken as root in the new shell.
  4. Once done, run exit to leave the new shell. It's important not to forget this, because you don't want to perform more actions as root than you intend!

So, if you want to, then you can write a shell function (or a script) that performs the first two of those actions when sudo is followed by cd, and just runs sudo normally otherwise. Please do not use this as an alternative to learning why sudo cd does not otherwise succeed, because if you don't understand what is going on, then you will likely be very confused by being in a new shell (and you may not understand any error messages that occur).

Here's one way to write such a shell function, which also reminds you that you're in a new shell and that you should exit out of it when you are finished. (That reminder is likely to be useful for users of any skill level, because one is not generally accustomed to being in a new shell when one runs sudo without -s, -i, or the name of an actual shell as an argument.)

# Make sudo treat "sudo cd [DIRECTORY]" as a special case and start a shell.
sudo() {
    if [ "$#" -eq 2 ] && [ "$1" = 'cd' ]; then
        sudo bash -c '
                if cd -- "$2"; then # When cd fails, its own message is enough.
                    printf "%s: Running %s shell in %s\n" "$0" "$USER" "$2" >&2
                    printf "%s: Type \"exit\" once you are done!\n" "$0" >&2
                    exec bash # Replace this bash shell with an interactive one.
                fi
            ' bash _ "$2" # Use $2 as the dir in the intermediate shell, too.
    else
        command sudo "$@"
    fi
}

You could put this in your ~/.bashrc, though this is a weird enough way to use sudo that you may only want to enable it occasionally. In that case, it's better to put it in its own file. If you create a file called sudo.bash in your home directory with those contents, then you can make the sudo function available--so that it will run instead of the regular sudo command--by running . ~/sudo.bash. That takes effect in the current shell and its child shells, but not others. For the same reason that files like .bashrc are not executable, don't mark sudo.bash executable with chmod. This is really a library, rather than a standalone shell script. If you did run it as a shell script, it would define the function... but only in the shell that ran the script, not for you as the caller. (Of course, you can write a script for this, that just doesn't happen to be the approach I've taken here.)

To check and see if sudo is currently defined as a shell function, and to see its current definition if it is one, run type sudo. To disable (i.e., undefine) the function once it's defined, run unset -f sudo. To manually run the regular sudo command directly even if the shell function is defined, run command sudo. Note, however, that you don't have to do that, because this sudo function actually does that itself whenever there are more or fewer than two arguments passed to it or the first argument passed to it is anything but cd. That's why you can still use it in the normal ways people use sudo.

Note also that the shell function shown above does still let you pass other arguments to sudo, but that will prevent it from treating cd specially. Running sudo -u user cd directory in particular is not supported, though you could extend the shell function to support that case. Nor is sudo -i cd directory. The shell that it creates is similar to what you get with sudo -s. The code does not actually run sudo -s, but uses sudo bash, so the -c option works properly. It actually runs bash twice when you pass cd and a directory argument to it (and zero times otherwise). When you run sudo cd directory, first it forks off a separate bash shell from the one you're running the sudo function in and changes directory. If that succeeds, it replaces that bash shell with a new, interactive one that you can use.

Here's an example of how that shell function automatically "does the right thing." Notice that sudo ls -A /root behaves normally. Only when I then attempt to cd to a directory with sudo is a new shell created, and I am reminded explicitly of what is going on.

ek@Io:~$ sudo ls -A /root
[sudo] password for ek:
.aptitude      .bashrc  .config  .emacs.d  .nano     .rpmdb
.bash_history  .cache   .dbus    .local    .profile
ek@Io:~$ sudo -k  # invalidates my current timestamp... like I left for a while
ek@Io:~$ sudo cd /root/.local
[sudo] password for ek:
bash: Running root shell in /root/.local
bash: Type "exit" once you are done!
root@Io:/root/.local#
root@Io:/root/.local#
root@Io:/root/.local# exit
exit
ek@Io:~$

If you try to sudo cd to a directory that you can't change to even as root, then you will just get an error message:

ek@Io:~$ sudo cd /nonexistent
[sudo] password for ek:
bash: line 1: cd: /nonexistent: No such file or directory
ek@Io:~$ sudo -k
ek@Io:~$ sudo cd /etc/crontab
[sudo] password for ek:
bash: line 1: cd: /etc/crontab: Not a directory
ek@Io:~$

I have used sudo -k in between invocations in the above examples to show that it authenticates you as root before attempting to change directory. But you don't actually have to run sudo -k yourself. Because the shell function is just a thin wrapper for the real sudo command, caching of your credentials and other common sudo behaviors still work normally.

Though it works well and is kind of neat, I admit that shadowing the real sudo command with a function of the same name is super weird. Most users will probably just want to perform the steps sudo -s, cd directory themselves. But in case anybody wants this--and also to demonstrate that it's possible--there it is.

Zanna
  • 70,465
Eliah Kagan
  • 117,780
0

@Daniel Bauke's solution works when what you're trying to sudo is a compound command, such as cd /some/path && ./executableScript.sh which may be what you need if executableScript.sh needs to be executed from within its directory, and it requires sudo both to enter the directory and to run the script (and you want to do this in a non-interactive/session kind of way.

To reiterate, Daniel Bauke's solution is:

sudo $SHELL -c "cd /some/path && ./executableScript.sh"
0

As far as the to su or not to su debate, I think it's silly. su is against the religion of Ubuntu and it's not something to do carelessly. It's amazing what an rm -rf * can do if you're root. But, if you're comfortable with the command line interface (CLI) and have system level tasks to do, there's no reason not to use su. I've used several distros where no one even mentioned using sudo. It's just a matter of what kind of work you're doing and which method you're most comfortable with. I use both.

Joe
  • 1,884
  • 1
    "In the versions of bash and sudo I have with kubuntu lucid, sudo cd now works – without any workarounds." Short of something like that, which I'm pretty sure has never been in Ubuntu by default, I don't see how. (Also, I've used 10.04; it didn't do that.) It's been years since you posted this, but do you remember the details? Does sudo cd still work for you? What's the output of type -a sudo in a shell where it works? I understand you may not know--and the second part of your answer remains relevant--but if you do, you can [edit] about it. – Eliah Kagan Dec 11 '17 at 00:10
  • @EliahKagan It definitely does not work for me now in 16.10 and I don't remember what I did then. It's against my religion to modify existing base commands, so it's unlikely I did that. In any case, even if it did work, everybody would just call it a bad habit because it wouldn't work generally. – Joe Dec 14 '17 at 05:06