Passando vários argumentos para o sudo dentro da função

1
foo (){
            sudo -- sh -c "cd /home/rob; echo \"$@\""
}

Estou tentando fazer uma função bash em .bashrc que será sudo, mude para um diretório específico e execute um comando Python. Para fins de demonstração, alterei isso para fazer eco no exemplo acima.

Mesmo que eu tenha citado $@ para passar todos os argumentos para o meu comando echo, ele só funciona com um:

$ foo 1
1
$ foo 1 2
2": -c: line 0: unexpected EOF while looking for matching '"'
2": -c: line 1: syntax error: unexpected end of file

O que dá? Como posso passar vários argumentos para essa função?

    
por SilverlightFox 23.08.2017 / 18:49

1 resposta

2

Adicione set -v à sua função e você verá o que está acontecendo:

$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; } 
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'

O que está acontecendo? Seu uso de $@ criou duas cadeias que foram citadas como " cd /tmp; echo "1 " e 2" . Você pode usar $* se não quiser essa divisão. Veja a seção da página man bash em Parâmetros Especiais :

@ ... 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.

Portanto, no seu caso, a única string (ou palavra) "xxx $ @ yyy" se expande para 2 strings 'xxx1' e '2yyy'. Você pode testar isso usando set -- 1 2 3 para definir $@ e, em seguida, usar printf ">%s<" "$@" para ver o número de palavras que "$@" se torna (como o printf repetirá o formato de cada argumento):

$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<

Se você quiser passar argumentos para sh -c command um hack é colocá-los após o único comando como argumentos, mas isso pode não funcionar em todos os shells:

f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2

O argumento sh extra é porque o primeiro argumento é tomado pelo shell como o nome do processo.

    
por 23.08.2017 / 19:06