3

sudo -i COMMAND runs COMMAND in the $HOME of root.

This causes an error when I try to run a script of current directory:

$ sudo -i ./myscript.sh
-bash: ./myscript.sh: No such file or directory

cannot find /home/user/myscript.sh because sudo -i command moves current directory to /root in my case.

How can I make sudo -i command keep the current directory?

sudo and sudo -i have different env, and it needs the env of sudo -i

A.L
  • 1,586
yoon
  • 183
  • 2
    Why do you need the -i? Why can't you just run sudo ./myscript? – user1794469 Mar 30 '21 at 07:13
  • sudo and sudo -i have different env, and it needs the env of sudo -i – yoon Mar 30 '21 at 07:17
  • 1
    Please [edit] your question and explain what you need. Using sudo -i like that doesn't make much sense, so we need to understand why you think that is the solution. Can't you just run sudo -i /home/user/myscript.sh? More importantly, why would you need root's login environment? – terdon Mar 30 '21 at 07:59
  • 1
    @yoon, I edited to add that comment in to the question, since it seems rather an important point as to why you're doing this. In general, you can [edit] to add clarifications to the question itself. (Information in comments can be missed easily.) – ilkkachu Mar 30 '21 at 09:30

2 Answers2

9

You can't; changing the directory is part of what sudo -i does. But you can just go back to where you were and then run the command:

sudo -i sh -c "cd '$PWD'; ./myscript.sh"

That will fail if $PWD contains single quotes. (On the other hand, if you know $PWD doesn't contain whitespace, or anything special to the shell, you could nix the single quotes too.)

A safer way would be something like below:

sudo -i sh -c 'cd "${1}"; ./myscript.sh' sh "$PWD"

(A plain "$1" doesn't work as you'd expect, because sudo -i runs the user's login shell in between, leading to another round of expansions. It tries to escape the command to prevent those expansions, but fails for $1 (and $foo etc.). See "sh -c" does not expand positional parameters, if I run it from "sudo --login". Is there a way around this? for the gory details.)


In any case, if that script is a tool commonly run by root, it would make sense to put it in some directory that's both in PATH for root, and only writable by root. In general, it's best to avoid any chance of non-root users messing up with what root runs, though if it's e.g. in your regular account's home directory, the possible issues are likely minimal.

ilkkachu
  • 138,973
  • @fra-san, aargh, that's even worse than I thought (I can't remember if I've seen that Q&A before, I must have repressed the memory.) Thanks for the link! – ilkkachu Mar 30 '21 at 10:11
  • Thanks, this was what I needed. One more thing please. I want alias sudo='sudo -i', however, this occurs the above issue. So I tried with alias sudo="sudo -i sh -c 'cd ${1}' sh '$PWD'", but this doesn't work. Any recommendation for this? – yoon Mar 30 '21 at 10:59
  • @yoon, it doesn't work directly like that. You could fix that inner sh to run the rest of the arguments as a command, but, what with the way sudo -i works differently from sudo without -i, the extra in-between shell and quoting to try to undo what that shell does (without exactly succeeding)... I wouldn't go there. – ilkkachu Mar 30 '21 at 11:23
  • @yoon, instead, it might be a better idea to have ./myscript.sh and whatever others you use like that, to set up their environment as needed, without having to deal with sudo -i – ilkkachu Mar 30 '21 at 11:24
  • It's the best for me to set an alias because I use sudo not only for script file but also for directly typed(interactive?) commands. I think alias sudo="sudo -i sh -c 'cd ${1}' sh '$PWD'; sh " works as I expect. – yoon Mar 30 '21 at 11:36
  • Ah, no,,, Running scripts works well, but $ sudo printenv PATH prints /usr/bin/printenv: /usr/bin/printenv: cannot execute binary file. I need more works,, – yoon Mar 30 '21 at 11:39
  • @yoon are you just looking for sudo -s? Please ask a new question and explain what you are trying to do and exactly what your requirements are. That alias is needlessly complicated (and wrong, you can't sh '$PWD') but if you explain what you need, I am sure we can give you a good solution. – terdon Mar 30 '21 at 17:36
  • I've also checked with sudo -s but it doesn't seem to work as I expected. Okay, I just opened a new question. Thanks. https://unix.stackexchange.com/questions/642814/sudo-s-env-vs-sudo-i-env – yoon Mar 30 '21 at 18:10
  • @terdon, well, sudo -i runs a login shell, so (assuming Bash) it reads e.g. the target's .profile etc. A non-login shell would read .bashrc. And a noninteractive shell (like with sudo -s somecmd) would read neither. Other than that, you're not wrong, there would probably be a better way to set up the environment for the script (or scripts). – ilkkachu Mar 30 '21 at 18:17
  • @yoon, but yeah, is there something in particular you need from the login environment? Some environment variables or such? – ilkkachu Mar 30 '21 at 18:17
  • Yes, I'm running a hadoop cluster, and certain commands should be run with customized PATH variable, not the defaults. – yoon Mar 30 '21 at 19:02
3

To avoid having sudo -i change your home directory, don't use the -i flag,

sudo ./myscript.sh

The documentation for sudo (see man sudo) states of the -i flag (with my emphasis)

-i, --login Run the shell specified by the target user's password database entry as a login shell. This means that login-specific resource files such as .profile, .bash_profile or .login will be read by the shell. [...] sudo attempts to change to that user's home directory before running the shell. The command is run with an environment similar to the one a user would receive at log in.

Your question's just been edited to say you need your root profile to the run the script. Without knowing what environment it is that you need the closest I can offer is this

sudo -i "${PWD:-$(pwd)}/myscript.sh"

If you know the actual location of myscript.sh (for example, it's in your home directory) you would be better providing that directly,

sudo -i "$HOME/myscript.sh"

There may be better options but you would need to provide details of the environment you need set up

Chris Davies
  • 116,213
  • 16
  • 160
  • 287