Tengo un montón de scripts de shell que manipulan los argumentos de la línea de comandos y hacen algunas cosas antes de invocar otro binario al final. ¿Hay alguna razón para no siempre exec el binario al final? Parece que esto sería más simple y más eficiente, pero nunca lo veo hecho.

3
Antimony 29 ago. 2016 a las 23:44

2 respuestas

La mejor respuesta

Si marca /usr/bin, probablemente encontrará muchos scripts de shell que terminan con un comando exec. A modo de ejemplo, aquí está /usr/bin/ps2pdf (debian):

#!/bin/sh
# Convert PostScript to PDF.

# Currently, we produce PDF 1.4 by default, but this is not guaranteed
# not to change in the future.
version=14

ps2pdf="`dirname \"$0\"`/ps2pdf$version"
if test ! -x "$ps2pdf"; then
____ps2pdf="ps2pdf$version"
fi
exec "$ps2pdf" "$@"

Se usa exec porque elimina la necesidad de mantener activo el proceso de shell después de que ya no sea necesario.

Mi directorio /usr/bin tiene más de 150 scripts de shell que usan exec. Entonces, el uso de exec es común.

Una razón para no usar exec sería si hubiera que procesar algo después que el binario terminó de ejecutarse.

4
John1024 29 ago. 2016 a las 20:56

No estoy de acuerdo con su evaluación de que esta no es una práctica común. Dicho esto, no es siempre lo correcto.

El escenario más común en el que finalizo un script con la ejecución de otro comando, pero no puedo usar exec de manera razonable, es si necesito que se ejecute un gancho de limpieza después del comando en el acabados finales. Por ejemplo:

#!/bin/sh

# create a temporary directory
tempdir=$(mktemp -t -d myprog.XXXXXX)
cleanup() { rm -rf "$tempdir"; }
trap cleanup 0

# use that temporary directory for our program
exec myprog --workdir="$tempdir" "$@"

... ¡en realidad no limpiará tempdir después de la ejecución! Cambiar ese exec myprog a simplemente myprog tiene algunas desventajas: uso continuo de la memoria del shell, una entrada adicional en la tabla de procesos, las señales se envían potencialmente al shell en lugar del programa que se está ejecutando. pero también asegura que el shell todavía esté en la salida de myprog para ejecutar las trampas necesarias.

4
Charles Duffy 29 ago. 2016 a las 22:01