4

I'm trying to write a wrapper around su to make it more like sudo, so that su_wrapper foo bar baz == su -c "foo bar baz".

However, I'm not sure how to approach this problem. I came up with this:

su_wrapper ()
{
  su -c "$@"
}

However, in the above, only a single argument can be there; this fails with multiple arguments (as su sees them as its own arguments).

There's also another problem: since the argument is passed through the shell, I think I must explicitly specify the shell to avoid other problems. Perhaps what I want to do could be expressed in pseudo-bash(!) as su -c 'bash -c "$@"'.

So, how could I make it accept multiple arguments?

  • your motivation being?... – shx2 Jun 21 '14 at 10:35
  • @shx2, I'm really tired of having to quote things when using su, and I'm not allowed to use sudo on these boxes. –  Jun 21 '14 at 10:36
  • 1
    (for the record, it isn't clear to me why people voted to close. this is about general computing. `su` and `sudo` are tools used by programmers.) – shx2 Jun 21 '14 at 10:37

2 Answers2

2

Use printf "%q" to escape the parameters so they can be used as string input to your function:

su_wrapper() {
    su -s /bin/bash -c "$(printf "%q " "$@")"
}

Unlike $*, this works even when the parameters contain special characters and whitespace.

that other guy
  • 116,971
  • 11
  • 170
  • 194
1

You need $* and not $@:

su_wrapper() {
    local IFS=' '
    su -c "$*"
}

See the Special Parameters section in the Bash Reference Manual for the difference between $* and $@.

I added local IFS=' ' just in case IFS is set to something else (after reading what $* does, it should be clear why you want to make sure that IFS is set to a space).

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104