Escribí el siguiente script bash:
#!/bin/bash
TIMEOUT="5"
SESSIONS="8"
function usage {
echo "Usage: $(basename $0) -l servers.list -c COMMAND"
echo ""
echo "Options:"
echo " -l : Provide list containing hostnames/ips"
echo " -c : Command to run"
echo " -u [optional] : Run commands remotely as supplied user"
echo " -r [optional] : Connect to remote machine as root, run commands as supplied user"
echo ""
echo " **** \"-u\" is mandatory if \"-r\" is used ****"
echo ""
}
while getopts ":l:c:u:r:" opt; do
case $opt in
l)
LIST=$OPTARG
;;
c)
COMMANDS="$OPTARG"
;;
u)
USER=$OPTARG
USERSWITCH="-l $USER"
;;
r)
RUSER=$OPTARG
RUSERSWITCH="-l root"
RUSERCMD="su - $USER -c '$COMMANDS'"
;;
*)
usage
exit 1
;;
esac
done
if [[ -z $LIST ]] || [[ -z $COMMANDS ]]; then
echo "Error - not enough arguments have been supplied"
fi
if [[ -z $USER ]]; then
/usr/bin/pssh -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
echo "user not supplied"
elif [[ ! -z $USER ]] && [[ ! -z $RUSER ]]; then
echo "connecting as root running as user"
/usr/bin/pssh $RUSERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$RUSERCMD"
elif [[ ! -z $USER ]] && [[ -z $RUSER ]]; then
echo "Connecting as supplied user"
/usr/bin/pssh $USERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
fi
Básicamente envuelve el comando "paralelo-ssh" y permite algunas funciones más que se requieren en mi lugar de trabajo, como proporcionar una lista o ejecutar comandos como un usuario específico.
El guión funciona perfectamente.
El único problema que tengo es con el comando proporcionado después del modificador "-c"; debe colocarse dentro ("") o los espacios en el comando harán que la variable obtenga solo la primera palabra en el comando.
¿Cómo debo editar la secuencia de comandos para que pueda obtener lo que esté después de -c incluso si no se ingresa ("")?
2 respuestas
Podrías hacer algo como esto (gracias @JohnKugelman por los útiles consejos):
c)
shift "$((OPTIND-2))"
cmd=$(printf "%q " "$@")
break
OPTIND
: el índice del siguiente argumento a procesar$((OPTIND-2))
: el número de argumentos hasta la opción-c
shift "$((OPTIND-2))"
: cambia todo a la opción-c
printf "%q " "$@"
: imprime los argumentos restantes ($@
- solo el comando porque todo lo demás se ha desplazado)%q
:help printf -> quote the argument in a way that can be reused as shell input
No estoy muy seguro de por qué se enfrenta a este problema, pero usar variables como ${COMMANDS}
siempre es una buena práctica, ya que mantiene todas las variables intactas.
Dado que está utilizando una variable después de -c
, debería utilizar RUSERCMD="su - $USER -c '${COMMANDS}'"
Nuevas preguntas
linux
Las preguntas de Linux deben estar relacionadas con la programación. Use esta etiqueta solo si su pregunta se relaciona con la programación utilizando API de Linux o un comportamiento específico de Linux, no solo porque ejecuta su código en Linux. Si necesita soporte para Linux, puede probar https://unix.stackexchange.com o el sitio específico de Stack Exchange de la distribución de Linux como https://askubuntu.com o https://elementaryos.stackexchange.com/