3

Bash version: GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

This works fine:

#!/bin/bash
exec /usr/local/bin/python2.7 /app/add_container_host.py $@

But I need to run it as a certain user, so I've changed it to:

#!/bin/bash
su -c '/usr/local/bin/python2.7 /app/add_container_host.py $@' $USER

and the Python script is no longer getting the arguments.

I've tried changing the single-quote to double quote and that's supplying the $@ to su -c itself, not to the Python script.

Is there a way to pass $@ to the python script while running it as su -c?

5
  • 1
    Try changing those single tick quotes to double quotes. Single's inhibit the variables inside them from being expanded.
    – slm
    Jul 10, 2018 at 4:37
  • @slm i did and su is getting the arguments, instead of the python script. "su: unrecognized option '--rh6'" the --rh6 option should be going to python script, not su
    – ealeon
    Jul 10, 2018 at 4:40
  • What's the call to this script look like?
    – slm
    Jul 10, 2018 at 4:42
  • Show (don't describe) what you did. Jul 10, 2018 at 5:50
  • Yes, there is a way to safely pass $@: su user -c 'command "$@"' -- argv0 "$@". (you should omit the -- on non-linux systems). See the answer here for an explanation.
    – user313992
    Nov 4, 2018 at 19:10

3 Answers 3

4

Your issue is the quotes you're using. You need to use double quotes so that the variables within, $@, can be expanded, otherwise they'll remain literals and never get expanded.

Here's an example

$ cat runme.bash
#!/bin/bash

echo "run with double quotes"
su -c "echo $@" user1

echo "run with single quotes"
su -c 'echo $@' user1

$ ./runme.bash "a b c"
run with double quotes
a b c
run with single quotes

$

You also have to pass the list of arguments in as a quoted list, otherwise the su -c ... command gets confused and starts trying to parse the 2nd argument as the user that you want to su as.

Another example

$ ./runme.bash a b c
run with double quotes
su: user b does not exist
run with single quotes

$

Debugging tip

If you want to see what the script is actually doing you can run it with the -x switch to bash.

bare arguments
$ bash -x ./runme.bash a b c
+ echo 'run with double quotes'
run with double quotes
+ su -c 'echo a' b c user1
su: user b does not exist
+ echo 'run with single quotes'
run with single quotes
+ su -c 'echo $@' user1

$
quoted arguments
$ bash -x ./runme.bash "a b c"
+ echo 'run with double quotes'
run with double quotes
+ su -c 'echo a b c' user1
a b c
+ echo 'run with single quotes'
run with single quotes
+ su -c 'echo $@' user1

$
4
  • 1
    thank you i didnt pass in the arguments as a quoted list so su -c was trying to parse the 2nd one as its own argument
    – ealeon
    Jul 10, 2018 at 4:56
  • 1
    Yeah the passing of args can be pretty tricky, glad this helped.
    – slm
    Jul 10, 2018 at 4:57
  • Huh, I didn't know Linux su was so different from the BSD su. On BSD you would just do su username -c 'command with args using "$@"' su-sh "$@"
    – Kusalananda
    Jul 10, 2018 at 6:15
  • 1
    @Kusalananda - yes it's very peculiar. I don't run into a lot of scenarios where I ever have to personally use it, I mainly know about it b/c of the Q&A I see here 8-). I try to do everything via sudo -u instead.
    – slm
    Jul 10, 2018 at 6:17
3

You might consider passing the shell positional parameters to the su command as arguments, rather than relying on having them correctly expanded in the -c argument string.

For example:

#!/bin/sh

su testuser -c 'for arg; do echo "$0 ($(whoami)): $arg"; done' -- su "$@"

then

$ ./suscript foo "bar baz"
Password: 
su (testuser): foo
su (testuser): bar baz
0

Encapsulating the command inside a here-doc block may help you.

#!/bin/sh

su testuser -s /bin/sh <<EOF
 add_container_host.py "$@"
EOF

You can try like below as well

su testuser -c 'add_container_host.py "$@"' -- argv0 "$@"

Apart from it su-exec is also a nice alternative.

1
  • May I know the reason behind negative impression on this anser ? Does this answer have any flaw ?
    – SkyRar
    Nov 9, 2018 at 21:06

You must log in to answer this question.

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