como executar dois comandos no sudo?

152

Existe alguma maneira de executar dois comandos Db2 em uma linha de comando? (Eles serão chamados a partir de um execcomando PHP .)

  1. db2 connect to ttt (observe que precisamos manter a conexão ativa para o segundo comando
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'

Eu tentei isso:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'

O primeiro comando termina corretamente, mas o segundo falha com a mensagem de erro SQL1024N A database connection does not exist. SQLSTATE=08003

Note que eu preciso executar isso como usuário php. O comando sudo -u db2inst1 idcomo usuário php me fornece a saída correta.

Radek
fonte
por favor, deixe um comentário por que você deseja encerrar esta pergunta. Obrigado.
Radek
1
A votação fechada é para a migração para a falha do servidor, pois essa é uma questão de administração de sistemas, não de programação.
bdonlan

Respostas:

157

O sudo pode executar vários comandos via shell, por exemplo:

$ sudo -s - 'whoami; Quem sou eu'
raiz
raiz

Seu comando seria algo como:

sudo -u db2inst1 -s - "o db2 se conecta ao ttt; db2 UPDATE CONTACT SET SET EMAIL_ADDRESS = '[email protected]'"

Se a sua versão sudo não funcionar com ponto-e-vírgula com -s (aparentemente, não se for compilada com certas opções), você poderá usar

sudo - sh -c 'whoami; Quem sou eu'

em vez disso, que basicamente faz a mesma coisa, mas faz você nomear o shell explicitamente.

wjl
fonte
12
isto não funciona no último debian stable (squeeze) bash:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valor
11
@ Valor você pode usar sudo -- sh -c 'whoami; whoami;como solução alternativa quando "sudo -s" estiver quebrado. Atualizei a resposta também.
Wjl 03/11/12
6
+1 para a versão editada que mostra o exemplo "- sh -c". Obrigado!
JD.
4
Você pode explicar por que precisa de "-"?
Vic Seedoubleyew
7
@VicSeedoubleyew O --indica o final dos parâmetros para sudo, então todo o resto faz parte do comando; sem ele, argumentos como -cpoderiam ser interpretados como argumentos para sudo. Isso funciona para a maioria dos programas de linha de comando (mas não todos). Por outro (não sudo) exemplo, para remover um arquivo chamado -fvocê não pode simplesmente correr rm -f, certo ?! Mas você pode executar rm -- -fpara excluir o arquivo chamado -f.
wjl 15/05
176

Para seu comando, você também pode consultar o seguinte exemplo:

sudo sh -c 'whoami; whoami'

Jason
fonte
14
Eu achei essa uma alternativa mais confiável.
Nick
44

Eu costumo fazer:

sudo bash -c 'whoami; whoami'
Samer Atiani
fonte
42

Se você gostaria de lidar com aspas:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF
Nebojša
fonte
4
Esta é a resposta mais limpa aqui, obrigado. Talvez adicione uma nota "Você não pode executar vários comandos a partir de sudo- você sempre precisa enganá-lo para executar um shell que possa aceitar vários comandos para executar como parâmetros"
trs
8

Uma alternativa evalpara evitar o uso de um subshell:

sudo -s eval 'whoami; whoami'

Nota: As outras respostas que usam sudo -sfail falham porque as aspas estão sendo passadas para o bash e executadas como um único comando, portanto, é necessário retirar as aspas com eval. evalé melhor explicado é esta resposta SO

Citar dentro dos comandos também é mais fácil:

$ sudo -s eval 'whoami; whoami; echo "end;"'
root
root
end;

E se os comandos precisarem parar de executar, se ocorrer uma falha, use duplo e comercial em vez de ponto e vírgula:

$ sudo -s eval 'whoami && whoamit && echo "end;"'
root
/bin/bash: whoamit: command not found
Cas
fonte
3

A -sopção não funcionou para mim, -ifuncionou.

Aqui está um exemplo de como eu poderia atualizar o tamanho do log do meu bash:

sudo -u [user] -i -- sh -c 'db2 connect to [database name];db2 update db cfg for [database name] using logsecond 20;db2 update db cfg for [database name] using logprimary 20;'
user2597485
fonte
1

No terminal, digite:

$ sudo bash

Em seguida, escreva quantos comandos quiser. Digite exitquando terminar.

Se você precisar automatizá-lo, crie um script.sharquivo e execute-o:

$ sudo ./script.sh
Moshe Simantov
fonte
1

Em um tópico um pouco relacionado, eu queria fazer o mesmo sudo com vários comandos via SSH, mas nenhuma das opções acima funcionou.

Por exemplo, no Ubuntu,

$ ssh host.name sudo sh -c "whoami; whoami"
[sudo] password for ubuntu:
root
ubuntu

O truque descoberto aqui é aspas duplas no comando.

$ ssh host.name sudo sh -c '"whoami; whoami"'
[sudo] password for ubuntu:
root
root

Outras opções que também funcionam:

ssh host.name sudo sh -c "\"whoami; whoami\""
ssh host.name 'sudo sh -c "whoami; whoami"'

Em princípio, as aspas duplas são necessárias porque acho que o shell do cliente em que o SSH é executado retira o conjunto de aspas mais externo. Misture e combine as aspas com as suas necessidades (por exemplo, variáveis ​​precisam ser passadas). No entanto, YMMV com as aspas, especialmente se os comandos remotos forem complexos. Nesse caso, uma ferramenta como Ansible fará uma escolha melhor.

Eugene Chow
fonte
1

Se você conhece a senha root, pode tentar

su -c "<command1> ; <command2>"  
estilhaços
fonte
Se você não souber a senha root, use sudo su -c "<command1> ; <command2>" .
Dag Høidahl 22/04
0

As respostas acima não permitirão que você cite as aspas. Esta solução irá:

sudo -su nobody umask 0000 \; mkdir -p "$targetdir"

O comando umask e o comando mkdir são executados com o usuário 'nobody'.

Arberg
fonte
Você pode usar aspas simples e duplas e escapar delas.
Radek
Ok, então como é que agora importa o que eu defina o umask neste comando, não tem efeito?
Michael