2

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

4
  • 2
    Why do you need the -i? Why can't you just run sudo ./myscript? Mar 30, 2021 at 7:13
  • sudo and sudo -i have different env, and it needs the env of sudo -i
    – yoon
    Mar 30, 2021 at 7: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, 2021 at 7: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, 2021 at 9:30

2 Answers 2

8

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.

11
  • @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, 2021 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, 2021 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, 2021 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, 2021 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, 2021 at 11:36
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .