¿Cómo ejecutar dos comandos en sudo?


152

¿Hay alguna forma de ejecutar dos comandos Db2 desde una línea de comandos? (Se llamarán desde un execcomando PHP ).

  1. db2 connect to ttt (tenga en cuenta que necesitamos tener la conexión en vivo para el segundo comando
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

Intenté esto:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

El primer comando finaliza correctamente pero el segundo falla con el mensaje de error SQL1024N A database connection does not exist. SQLSTATE=08003

Tenga en cuenta que necesito ejecutar esto como usuario php. El comando sudo -u db2inst1 idcomo usuario php me da la salida correcta.


deja un comentario por qué quieres cerrar esta pregunta. Gracias.
Radek

1
El voto cerrado es para la migración a serverfault, ya que esta es una pregunta de administración de sistemas, no de programación.
bdonlan

Respuestas:


157

sudo puede ejecutar múltiples comandos a través de un shell, por ejemplo:

$ sudo -s - 'whoami; quién soy'
raíz
raíz

Su comando sería algo como:

sudo -u db2inst1 -s - "db2 se conecta a ttt; db2 ACTUALIZAR CONTACTO CONFIGURAR EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

Si su versión de sudo no funciona con punto y coma con -s (aparentemente, no lo hace si se compila con ciertas opciones), puede usar

sudo - sh -c 'whoami; quién soy'

en cambio, que básicamente hace lo mismo pero te hace nombrar el shell explícitamente.


12
esto no funciona en la última fiesta de Debian estable (squeeze):sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valor

11
@Valor que puede usar sudo -- sh -c 'whoami; whoami;como solución alternativa cuando "sudo -s" no funciona. También actualicé la respuesta.
wjl

66
+1 para la versión editada que muestra el ejemplo "- sh -c". ¡Gracias!
JD.

44
¿Puede explicar por qué necesita "-"?
Vic Seedoubleyew

77
@VicSeedoubleyew El --indica el final de los parámetros para sudo, por lo que todo lo demás es parte del comando; sin él, argumentos como -cpodrían ser interpretados como un argumento para sudo. Esto funciona para la mayoría de los programas de línea de comandos (pero no para todos). Para otro (no sudo) ejemplo, para eliminar un archivo llamado -fno puedes simplemente ejecutarlo rm -f, ¿verdad? Pero puede ejecutar rm -- -fpara eliminar el archivo llamado -f.
wjl

176

Para su comando, también puede consultar el siguiente ejemplo:

sudo sh -c 'whoami; whoami'


14
He encontrado esta una alternativa más confiable.
Nick


42

Si desea manejar cotizaciones:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF

44
Esta es la respuesta más limpia aquí, gracias. Tal vez agregue una nota "No puede ejecutar múltiples comandos desde sudo- siempre necesita engañarlo para que ejecute un shell que puede aceptar múltiples comandos para ejecutar como parámetros"
trs

8

Una alternativa que usa evalpara evitar el uso de una subshell:

sudo -s eval 'whoami; whoami'

Nota: Las otras respuestas que usan sudo -sfallan porque las citas se pasan a bash y se ejecutan como un solo comando, por lo que deben eliminarse las comillas con eval. evalse explica mejor es esta respuesta SO

Citar dentro de los comandos también es más fácil:

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

Y si los comandos deben dejar de ejecutarse si uno falla, use dos signos en lugar de punto y coma:

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

3

La -sopción no funcionó para mí, lo -ihizo.

Aquí hay un ejemplo de cómo podría actualizar el tamaño del registro desde mi 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;'

1

En la terminal, escriba:

$ sudo bash

Luego escribe tantos comandos como quieras. Escriba exitcuando haya terminado.

Si necesita automatizarlo, cree un script.sharchivo y ejecútelo:

$ sudo ./script.sh

1

En un tema ligeramente relacionado, quería hacer el mismo sudo de comandos múltiples a través de SSH, pero ninguno de los anteriores funcionó.

Por ejemplo en Ubuntu,

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

El truco descubierto aquí es comillas dobles del comando.

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

Otras opciones que también funcionan:

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

En principio, se necesitan comillas dobles porque creo que el shell del cliente donde se ejecuta SSH elimina el conjunto de comillas más externo. Mezcle y combine las citas con sus necesidades (por ejemplo, las variables deben pasarse). Sin embargo, YMMV con las comillas, especialmente si los comandos remotos son complejos. En ese caso, una herramienta como Ansible hará una mejor elección.


1

Si conoce la contraseña de root, puede intentar

su -c "<command1> ; <command2>"  

Si no conoce la contraseña de root, use sudo su -c "<command1> ; <command2>" .
Dag Høidahl

0

Las respuestas anteriores no le permitirán citar dentro de las citas. Esta solución:

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

Tanto el comando umask como el comando mkdir se ejecutan con el usuario 'nobody'.


Puede usar comillas simples y dobles y escapar de ellas.
Radek

Ok, entonces, ¿cómo es que ahora importa lo que establezca en umask en este comando, no tiene ningún efecto?
Michael
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.