Run "cd" command as superuser in Linux

9

2

Is there a way to run the cd command with superuser privileges to gain access to directories that are owned by root? When I run sudo cd <path>, I get sudo: cd: command not found.

thecomputerguru

Posted 2019-10-20T15:16:43.557

Reputation: 329

2You can run only external commands with sudo, so you need to invoke bash to perform the cd command, using sudo bash -c cd .... – AFH – 2019-10-20T15:24:34.887

1

I know, that's what I read on this superuser post https://superuser.com/questions/241129/why-wont-sudo-cd-work.

– thecomputerguru – 2019-10-20T15:51:48.760

My question is how can I use the cd command with superuser privileges, since sudo doesn't work. – thecomputerguru – 2019-10-20T15:53:34.183

Sorry, misread your question: I was thinking of the mkdir command. Silly mistake. – AFH – 2019-10-20T17:01:51.130

2

FWIW POSIX says that cd ought to be available as an external command. Questionable value? Sure, but that's the spec.

– kojiro – 2019-10-21T00:09:14.377

The easy way is to log in as root, assuming you're typing the cd command directly, rather than in a macro. (You don't say exactly how you're using it.) – jamesqf – 2019-10-21T03:22:36.100

You can become root with sudo -i. – kevinSpaceyIsKeyserSöze – 2019-10-21T10:08:58.740

Assume you could do sudo cd /foo/bar. It might happen that after that you cannot even cd .. – Hagen von Eitzen – 2019-10-21T14:47:13.510

If you want to play around with the situation you can change as a normal user in a directory and after that use a different root shell to remove the x permission. (A variation of this is chroot with forgetting to cd first) – eckes – 2019-10-22T02:00:55.373

Just about everybody learning to use the CLI (command line interface) makes this mistake sooner or later. It's a natural thing to want to do from a human perspective, but it doesn't make any sense from the shell's perspective. – Joe – 2019-10-22T06:25:27.233

Answers

22

The other answer isn't wrong.

Possibly a better answer is:

The sudo tool is intended to take actions as a superuser, and you're describing something that is more of a state change that would precede actions such as 'ls' or 'vi' or others to make them simpler.

I suggest, e.g. if you wanted to edit a file in /root/private/:

sudo ls /root
sudo ls /root/private
sudoedit /root/private/<name from previous ls command>

This is definitely more typing, and a little harder than just changing directories. However, it is far more audit-able, and much more in-line with the principles behind sudo than running some variant of 'sudo bash.'

If you are working in a secure environment, your IA team will thank you. If you find yourself wondering: "What change did I make the other day?," then you will thank you, because you won't have to wonder what file or files you edited.

All of this said, enabling and executing some form of 'sudo bash' is definitely easier. If you were looking for easier, why are you using 'sudo' in the first place instead of just logging in as root?

Slartibartfast

Posted 2019-10-20T15:16:43.557

Reputation: 6 899

Sounds like you're talking about relying on each admin's .bash_history instead of using something more reliable like etckeeper? – user1686 – 2019-10-21T08:17:26.217

5The hideously annoying thing in this is that tab-completion of the filename in the last command doesn't work if the non-root user doesn't have read access to the directory. So you have to copy paste or hand-type. I wonder if anyone would have created a sudo-using completion script for Bash. – ilkkachu – 2019-10-21T11:05:54.910

1@ilkkachu: At that point I usually just sudo -s to start a root shell on personal-use systems (so auditing isn't a huge deal). I don't want automatically-generated commands running under sudo. (Cluttering logs at best, at worst exposing some hackily-written completion code to malicious filenames with spaces and worse in them.) – Peter Cordes – 2019-10-21T23:29:02.640

@grawity: I was referring to the system security logs, where sudo typically logs commands issued, including time, user, current working directory, etc. – Slartibartfast – 2019-10-22T03:15:19.507

@PeterCordes, yep. I'd be tempted to just chmod +r or raise the question if a custom should be made where some staff group has read permissions to root owned directories, because tab-completion is useful. Yes, the completion code would need to be carefully written (and I think I've seen some not work with funny filenames), but I don't think the clutter should be an issue since you can just grep out any ls commands which don't do anything, and which people will need to run under sudo anyway if they don't have read permissions as their regular UID. – ilkkachu – 2019-10-22T07:19:51.447

An alias for sudoedit is sudo -e, it saves 1 keypress – Ferrybig – 2019-10-22T07:42:34.203

@ferrybig: Fair point, but it means I move my fingers two rows below, and two rows above home row, whereas 'edit' (not to mention 'sudoedit') is a word that I touch-type without thinking. I might save one keypress and increase time and typos significantly. – Slartibartfast – 2019-10-23T01:39:43.823

23

As you noted, cd is a shell built-in command, and there's a reason for that: the "current directory" is a per-process parameter which can be only changed by the process itself.

Your shell's working directory cannot be changed by any child process – so even if you manage to run cd in a privileged subshell, it'll only change the working directory of that temporary subshell, and it does not matter what method of raising privileges you use.

So for sudo cd to work, sudo itself would have to be a shell built-in, and it would need some way to raise privileges of an already-running process. Currently no such mechanism exists on Linux (nor most other operating systems).


One way to achieve what you want is to run an interactive shell with root privileges (any method works), and just use the regular cd in it:

[user@host /]$ sudo bash
[root@host /]# cd /root/secret

If you want to do it all in one command, it would have to look like this – first change the working directory, then start an interactive shell:

sudo bash -c "cd /root/secret && bash"
su -c "cd /root/secret && zsh"

Note: The outer command doesn't have to be a shell, it just needs to be something that changes its working directory and executes a new command. Recent Linux systems have one or two helpers which could be used:

sudo nsenter --wd="/root/secret" bash       # util-linux v2.23 (debian jessie)
sudo env --chdir="/root/secret" bash        # coreutils v8.28 (debian buster)

The advantage of this method is that it doesn't require nested quoting; you can run a multi-word command without having troubles with whitespace or special characters.

Finally, some programs have a built-in option to change their working directory:

sudo make -C /etc
sudo git -C /root/secret log

user1686

Posted 2019-10-20T15:16:43.557

Reputation: 283 655

1sudo -s starts an interactive $SHELL in the current directory; it's (AFAIK) the canonical way to do sudo bash – Peter Cordes – 2019-10-22T07:23:58.113

0

The fastest way to do what I needed to do was this:

sudo -s

As described in this answer.

orangecaterpillar

Posted 2019-10-20T15:16:43.557

Reputation: 9

-3

Sure, just do this:

sudo $SHELL -c "cd <path>"

The key is the -c option that runs the commands that are quoted after that -c.

JakeGould

Posted 2019-10-20T15:16:43.557

Reputation: 38 217

2When I tried running that, nothing happened. Is there a way to do it in a current bash shell session? – thecomputerguru – 2019-10-20T15:45:44.520

3When I run that command, it runs in a subshell then exits immediately. – thecomputerguru – 2019-10-20T15:58:48.117

3This proposal is of course useless unless you extend it to make it do something useful while there, before simply exiting. Even though that particular issue inherits from the question itself, simply ignoring it makes this a misleading post that will waste reader's time, rather than a useful answer. – Chris Stratton – 2019-10-21T00:51:48.677

1

@ChrisStratton The question is then an “XY Problem” scenario. And perhaps I should have asked for clarification. But many times people — including me — will as a specific question here without really explaining the full need for that issue to be solved. For all I know, the sudo cd [path] could be sudo cd [path] && [do something] && [and do something else]. So ultimately your attitude speaks for itself and is unnecessarily chastising.

– JakeGould – 2019-10-21T01:27:45.497

4@JakeGould no, it could not - because your new example does not work either, for the same reason that the subsequent commands still do not run as root. To demonstrated your misunderstanding try: sudo whoami && whoami – Chris Stratton – 2019-10-21T02:27:50.317

1While the question certainly is an "XY Problem", this answer should at least point out that the command it contains does nothing, and demonstrate how to turn it into something that does something - crucially, including the correct placement of quotes. – IMSoP – 2019-10-21T09:23:36.647