2008-12-16 17 views
14

Actualmente uso esta función para ajustar los comandos de ejecución y registrar su ejecución, y el código de retorno, y salir en caso de un código de retorno distinto de cero .¿Cuál es la mejor manera de escribir una función de envoltura que ejecuta comandos y registra su código de salida

Sin embargo, esto es problemático ya que aparentemente hace una doble interpolación, haciendo que los comandos con comillas simples o dobles rompan la secuencia de comandos.

¿Se puede recomendar una mejor manera?

Aquí está la función:

do_cmd() 
{ 
    eval $* 
    if [[ $? -eq 0 ]] 
    then 
     echo "Successfully ran [ $1 ]" 
    else 
     echo "Error: Command [ $1 ] returned $?" 
     exit $? 
    fi 
} 

Respuesta

19
"[email protected]" 

De http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters:

@

Se expande a los parámetros posicionales, empezando por uno. Cuando la expansión se produce entre comillas dobles, cada parámetro se expande a una palabra separada . Es decir, "$ @" es equivalente a "$ 1" "$ 2" .... Si se produce la expansión de doble cita dentro de una palabra, la expansión del primer parámetro se une con la parte inicial de la palabra original , y la expansión del último parámetro se une con la última parte de la palabra original . Cuando no hay parámetros posicionales, "$ @" y $ @ se expanden a nada (es decir, se eliminan).

Esto significa que los espacios en los argumentos se vuelven a citar correctamente.

do_cmd() 
{ 
    "[email protected]" 
    ret=$? 
    if [[ $ret -eq 0 ]] 
    then 
     echo "Successfully ran [ [email protected] ]" 
    else 
     echo "Error: Command [ [email protected] ] returned $ret" 
     exit $ret 
    fi 
} 
+0

nice. vencerme a tiempo: p –

+0

Por supuesto, 'cmd; si [[$? -eq 0]]; entonces stuff' es más idiomáticamente escrito 'if cmd; luego cosas'. – tripleee

+1

Pero el código debería usar $ ret más tarde, por lo que guardarlo es más claro en mi humilde opinión. –

5

adicional a "[email protected]" lo que dice Douglas, me gustaría utilizar

return $? 

Y no exit. Saldría de su caparazón en lugar de regresar de la función. Si, en caso de que desea salir de su concha si algo salió mal, puede hacer que en la persona que llama:

do_cmd false i will fail executing || exit 
# commands in a row. exit as soon as the first fails 
do_cmd one && do_cmd && two && do_cmd three || exit 

(De esa manera, puede controlar los errores y luego salir con gracia).

Cuestiones relacionadas