foo (){            sudo -- sh -c cd /home/rob; echo \$@\}I'm trying to make a bash function in .bashrc that will sudo, change to a particular directory and then run a Python command. For demo purposes I have changed this to echo in the above example.Even though I have quoted $@ to pass all arguments to my echo command, it only works with one:$ foo 11$ foo 1 22: -c: line 0: unexpected EOF while looking for matching `'2: -c: line 1: syntax error: unexpected end of fileWhat gives? How can I pass multiple arguments to this function?
Passing multiple arguments to sudo within function
bash;shell;function
Add set -v to your function and you will see what is happening:$ f (){ set -v; sudo -- sh -c cd /tmp; echo \$@\; } $ f 1 2+ sudo -- sh -c 'cd /tmp; echo 1' '2'What is happening?  Your use of $@ has created two strings that have been single quoted to cd /tmp; echo 1 and 2.  You can use $* if you dont want this splitting. See the bash man page section on Special Parameters:@ ... When the expansion occurs within double quotes, each parameter   expands to a separate word. ... If ... within a word, the expansion of the   first parameter is joined with the beginning part of the original word,   and the expansion of the last parameter is joined with the last part of   the original word.So in your case the single string (or word) xxx$@yyy expands to 2 strings 'xxx1' and '2yyy'. You can test this using set -- 1 2 3 to set $@ and then use printf >%s< $@ to see the number of words that $@ becomes (as the printf will repeat the format for each argument):$ set -- 1 2 3$ printf >%s<  x$@y>x1< >2< >3y<$ printf >%s<  x$*y>x1 2 3y<If you want to pass arguments to sh -c command one hack is to place them after the single command as arguments, but this may not work on all shells:f (){ set -v; sudo -- sh -c 'cd /tmp; echo $@' sh $@; }f 1 2+ sudo -- sh -c 'cd /tmp; echo $@' sh 1 2The extra sh argument is because the first arg is taken by the shell as the name of the process.