bash - programacion - scripts linux ejercicios resueltos
Obtener el código de salida para el comando en bash/ksh (5)
A continuación está el código fijo:
#!/bin/ksh
safeRunCommand() {
typeset cmnd="$*"
typeset ret_code
echo cmnd=$cmnd
eval $cmnd
ret_code=$?
if [ $ret_code != 0 ]; then
printf "Error : [%d] when executing command: ''$cmnd''" $ret_code
exit $ret_code
fi
}
command="ls -l | grep p"
safeRunCommand "$command"
Ahora, si miras este código, algunas cosas que cambié son:
- el uso de
typeset
no es necesario, pero es una buena práctica.cmnd
yret_code
local ensafeRunCommand
- no es necesario usar
ret_code
pero es una buena práctica almacenar código de retorno en alguna variable (y almacenarlo lo antes posible) para que pueda usarlo más tarde como lo hice enprintf "Error : [%d] when executing command: ''$command''" $ret_code
- pasa el comando con comillas que rodean el comando como
safeRunCommand "$command"
. Si no lo hace, entoncescmnd
obtendrá solo el valorls
y nols -l
. Y es aún más importante si su comando contiene tuberías. - puede usar
typeset cmnd="$*"
lugar detypeset cmnd="$1"
si desea mantener los espacios. Puede probar con ambos dependiendo de cuán complejo sea su argumento de comando. - eval se usa para evaluar para que el comando que contiene tuberías pueda funcionar bien
NOTA: recuerde que algunos comandos dan 1 como código de retorno aunque no haya un error como grep
. Si grep
encontró algo, devolverá 0 else 1.
Yo había probado con KSH / BASH. Y funcionó bien. Avísame si te enfrentas a problemas al ejecutar esto.
Quiero escribir un código como este:
command="some command"
safeRunCommand $command
safeRunCommand() {
cmnd=$1
$($cmnd)
if [ $? != 0 ]; then
printf "Error when executing command: ''$command''"
exit $ERROR_CODE
fi
}
Pero este código no funciona como yo quiero. Donde cometí un error?
Debería ser $cmd
lugar de $($cmd)
. Funciona bien con eso en mi caja.
Editar: Su script funciona solo para comandos de una sola palabra, como ls. No funcionará para "ls cpp". Para que esto funcione, reemplace cmd="$1"; $cmd
cmd="$1"; $cmd
con "$@"
. Y no ejecute su script como command="some cmd"; safeRun command
command="some cmd"; safeRun command
, ejecútelo como safeRun some cmd
.
Además, cuando deba depurar sus scripts bash, ejecute con el indicador ''-x''. [bash -x s.sh].
Hay varias cosas mal con su script.
Las funciones (subrutinas) deben declararse antes de intentar llamarlas. Probablemente desee regresar () pero no salir () de su subrutina para permitir que el bloque de llamadas pruebe el éxito o el fracaso de un comando en particular. Aparte de eso, no captura ''ERROR_CODE'' de modo que siempre sea cero (indefinido).
También es una buena práctica rodear tus referencias variables con llaves. Tu código puede verse así:
#!/bin/sh
command="/bin/date -u" #...Example Only
safeRunCommand() {
cmnd="$@" #...insure whitespace passed and preserved
$cmnd
ERROR_CODE=$? #...so we have it for the command we want
if [ ${ERROR_CODE} != 0 ]; then
printf "Error when executing command: ''${command}''/n"
exit ${ERROR_CODE} #...consider ''return()'' here
fi
}
safeRunCommand $command
command="cp"
safeRunCommand $command
La idea normal sería ejecutar el comando y luego usar $?
para obtener el código de salida. Sin embargo, algunas veces tienes múltiples casos en los que necesitas obtener el código de salida. Por ejemplo, es posible que deba ocultar su resultado pero aún así devolver el código de salida, o imprimir tanto el código de salida como el resultado.
ec() { [[ "$1" == "-h" ]] && { shift && eval $* > /dev/null 2>&1; ec=$?; echo $ec; } || eval $*; ec=$?; }
Esto le dará la opción de suprimir la salida del comando para el que desea el código de salida. Cuando la salida se suprime para el comando, la función devolverá directamente el código de salida.
Personalmente me gusta poner esta función en mi archivo .bashrc
A continuación, le mostramos algunas formas en que puede usar esto:
# In this example, the output for the command will be
# normally displayed, and the exit code will be stored
# in the variable $ec.
$ ec echo test
test
$ echo $ec
0
# In this example, the exit code is output
# and the output of the command passed
# to the `ec` function is suppressed.
$ echo "Exit Code: $(ec -h echo test)"
Exit Code: 0
# In this example, the output of the command
# passed to the `ec` function is suppressed
# and the exit code is stored in `$ec`
$ ec -h echo test
$ echo $ec
0
Solución a su código usando esta función
#!/bin/bash
if [[ "$(ec -h ''ls -l | grep p'')" != "0" ]]; then
echo "Error when executing command: ''grep p'' [$ec]"
exit $ec;
fi
También debe tener en cuenta que el código de salida que verá será para el comando
grep
que se está ejecutando, ya que es el último comando que se está ejecutando. No es ells
.
Tratar
safeRunCommand() {
"$@"
if [ $? != 0 ]; then
printf "Error when executing command: ''$1''"
exit $ERROR_CODE
fi
}