Cuando se utiliza sh
con su -c
opción, el argumento después de la -c
se toma como la cadena de comando a ejecutar. Por lo tanto, cuando se ejecuta
sh -c /usr/sbin/installer -pkg 'path_to_stackexchange.pkg' -target '/'
sh
ejecutará el comando "/usr/sbin/installer
". Es no pasar el resto de sus argumentos, porque no son parte de la cadena de comando. Si desea incluir argumentos, tendría que hacer algo como esto:
sh -c "/usr/sbin/installer -pkg 'path_to_stackexchange.pkg' -target '/'"
Las comillas dobles hacer que un solo argumento a sh
, por lo que se va a ejecutar la totalidad de la cosa y de paso -pkg
etc como argumentos a la installer
comando.
(Por CIERTO, en la shell, comillas no nido. La anidación de las cadenas entre comillas dentro de las cadenas entre comillas, como en el de comillas simples argumentos en el interior de la doble citado argumento, no es realmente una cosa. En este caso se hace el trabajo, porque el interior de una cadena entre comillas dobles, comillas simples son sólo personajes regulares. En las situaciones más complicadas, las cosas pueden ser extraño y confuso.)
Así que lo que pasa a los otros argumentos después de que el comando? Así, la cadena de comando (el argumento después de la -c
) funciona un poco como una miniatura de la secuencia de comandos de shell, y los que se pasaron a la mini-script como argumentos. Pero no pasa a los comandos en el mini-script, a menos que el mini-script explícitamente pasa:
sh -c '/usr/sbin/installer "$@"' installer-thingie -pkg 'path_to_stackexchange.pkg' -target '/'
Aquí, en el interior de la mini-script, el "$@"
expande a los argumentos de la mini-script (es decir, -pkg
, path_to_stackexchange.pkg
, etc.), pasando así a la installer
comando.
Pero lo que installer-thingie
argumento? Ese es el nombre de la mini-script se ejecuta bajo, por lo que voy a mostrar como $0
dentro de la mini-script. Básicamente, funciona como un marcador de posición, y usted puede poner casi cualquier cosa allí. "sh" es una opción común.
Como para los pros y los contras de la utilización de sh -c
a ejecutar los comandos: a menos que haya alguna razón por la que usted realmente necesita para ejecutar otro shell, ejecute el comando directamente. Se ejecuta con sh -c
es más complicado y confuso, y (como lo he experimentado) fácil equivocarse.
Como @DavidAnderson señalado, el uso de sh -c
también es menos eficiente, ya que crea un adicional de proceso de shell. Si usted mira el árbol de procesos para la ejecución de installer
directamente (y suponiendo que el shell interactivo es zsh), se parece a esto:
zsh───installer
Pero con sh -c
, es como este:
zsh───sh───installer
...se corrió un sh
proceso bajo su shell interactiva y, a continuación, que corrió installer
como un subproceso.
Por otro lado, si usted prefiere confundir la complejidad y la ineficiencia, no hay ninguna razón para detenerse en una innecesaria shell; ¿por qué no añadir otra sh -c
a ejecutar el sh -c
comando?
sh -c "sh -c \"/usr/sbin/installer -pkg 'path_to_stackexchange.pkg' -target '/'\""
o incluso
sh -c "sh -c \"sh -c \\\"/usr/sbin/installer -pkg 'path_to_stackexchange.pkg' -target '/'\\\"\""
(¿he mencionado que la anidación de las comillas puede complicarse?)