randy newfield
randy newfield

Reputation: 1221

How to run multiline bash commands as sudo

I am trying to launch an application that needs many switches in order to operate so I have multi lined them using the \ operator. Now I need to run this application as well as some exports to be ran as another user.

What I am currently attempting to do is

sudo -u user bash <<EOF
export AUDIO_DRV=alsa
export ...
exec application --switch1 \
    --switch2 \
    --switch3 \
    --switch4 \
    ... \
    "$@"
EOF

I would run sudo myscript.sh so that root may setup a few things before it drops privileges to run the main application. The problem is that the multi line switches are not all being passed to the application causing unexpected results.

Is there any way to make this work as clean as this would of been or am I stuck appending all the switches to one line in order for it to work?

Upvotes: 2

Views: 7749

Answers (3)

Denio Mariz
Denio Mariz

Reputation: 1195

You can write the command in a file and execute them as a script using sudo. The script does not need to contain the multi line escape "\" -- you can write the entire command in just one line if you want.

Also, you can build a function and execute the function using sudo.

MyFuncion(){
    application --switch1 --switch2 --switch3 --switch4 "$@"
    cmd 2
    # etc
}
sudo MyFunction

Upvotes: 1

that other guy
that other guy

Reputation: 123460

Self-contained examples are a great way to see what goes wrong and why.

Here's a self-contained example that demonstrates that your use of multiline arguments is fine:

touch myfile.txt
bash << eof
find . \
  -name '*.txt' \
  -type f
eof

Here's another self-contained example that demonstrates that your use of "$@" is wrong:

touch foo bar
set -- foo bar
bash << eof
  ls "$@"
eof

Expected result is bar foo (because ls lists two files), but actual result is ls: cannot access foo bar: No such file or directory (because ls tries to list one).

This is because the $@ is expanded before being passed to bash, so instead of the magic quoting behavior of "$@" you just get $@ replaced by the concatenation of the variables between literal double quotes.

You should instead pass the parameters to bash and have bash expand them:

touch foo bar
set -- foo bar
bash -s -- "$@" << eof
  ls "\$@"
eof

Upvotes: 3

Anar Alishov
Anar Alishov

Reputation: 26

I think here is answer for that: how to run two commands in sudo?

in general its:

sudo -s — 'whoami; whoami'

 sudo -u user -s -- ' \
    whoami; \
    whoami; \
    "$@"
'

Upvotes: 0

Related Questions