bash: executando su -c breaks $ @

2

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

Isso funciona bem:

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

Mas eu preciso executá-lo como um determinado usuário, então mudei para:

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

e o script Python não está mais recebendo os argumentos.

Eu tentei alterar o aspas simples para aspas duplas e isso está fornecendo o $@ para su -c em si, não para o script Python.

Existe uma maneira de passar $@ para o script python enquanto o executa como su -c ?

    
por ealeon 10.07.2018 / 06:32

3 respostas

4

Seu problema são as citações que você está usando. Você precisa usar aspas duplas para que as variáveis dentro, $@ , possam ser expandidas, caso contrário elas permanecerão literais e nunca serão expandidas.

Veja um exemplo

$ 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

$

Você também tem que passar a lista de argumentos como uma lista citada, caso contrário, o comando su -c ... fica confuso e começa a tentar analisar o segundo argumento como o usuário que você deseja su as.

Outro exemplo

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

$

Dica de depuração

Se você quiser ver o que o script realmente está fazendo, pode executá-lo com a opção -x para bash .

argumentos nus
$ 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

$
argumentos citados
$ 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

$
    
por 10.07.2018 / 06:46
2

Você pode considerar passar os parâmetros posicionais do shell para o comando su como argumentos, em vez de confiar em tê-los corretamente expandidos na sequência de caracteres -c .

Por exemplo:

#!/bin/sh

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

então

$ ./suscript foo "bar baz"
Password: 
su (testuser): foo
su (testuser): bar baz
    
por 10.07.2018 / 14:27
-1

Encapsular o comando dentro de um bloco do here-doc pode ajudá-lo.

#!/bin/sh

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

Você pode experimentar como abaixo também

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

Além disso, su-exec também é uma boa alternativa.

    
por 04.11.2018 / 19:11