En la documentación de Perl, perlrun (1) sugiere iniciar scripts de Perl utilizando un shell bilingüe / encabezado de Perl:
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;
Que ${1+"$@"}
significa Intenté usar en su "$@"
lugar (usando Bash como / bin / sh), y parece funcionar igual de bien.
Editar
Dos respuestas a continuación dicen que se supone que debe ser ${1:+"$@"}
. Soy consciente de la ${parameter:+word}
sintaxis ("Usar valor alternativo") documentada en bash (1). Sin embargo, no estoy convencido, porque
Ambos
${1+"$@"}
y"$@"
funcionan bien, incluso cuando no hay parámetros. Si creo simple.sh como#!/bin/sh eval 'exec /usr/bin/perl -x -S -- $0 "$@"' if 0; #!perl use Data::Dumper; print Dumper(\@ARGV);
y question.sh como
#!/bin/sh eval 'exec /usr/bin/perl -x -S -- $0 ${1+"$@"}' if 0; #!perl use Data::Dumper; print Dumper(\@ARGV);
Puedo hacer que ambos trabajen de manera idéntica:
$ ./question.sh $VAR1 = []; $ ./question.sh a $VAR1 = [ 'a' ]; $ ./question.sh a 'b c' $VAR1 = [ 'a', 'b c' ]; $ ./question.sh "" $VAR1 = [ '' ]; $ ./simple.sh $VAR1 = []; $ ./simple.sh a $VAR1 = [ 'a' ]; $ ./simple.sh a 'b c' $VAR1 = [ 'a', 'b c' ]; $ ./simple.sh "" $VAR1 = [ '' ];
También utilizan otras fuentes en Internet
${1+"$@"}
, incluido un hacker que parece saber lo que está haciendo.
¿Quizás ${parameter+word}
es una sintaxis alternativa (o obsoleta) no documentada ${parameter:+word}
? ¿Alguien podría confirmar esa hipótesis?
Respuestas:
Eso es por compatibilidad con el shell Bourne. El shell Bourne era un antiguo shell que se lanzó por primera vez con la versión 7 de Unix en 1979 y aún era común hasta mediados de los 90 como
/bin/sh
en la mayoría de los Unices comerciales.Es el antepasado de la mayoría de las conchas tipo Bourne
ksh
,bash
ozsh
.Tenía algunas características incómodas, muchas de las cuales se han reparado
ksh
y las otras shells y la nueva especificación estándar desh
, una de las cuales es esta:Con el shell Bourne (al menos aquellas variantes donde no se ha solucionado): se
"$@"
expande a un argumento vacío si la lista de parámetros posicionales está vacía ($# == 0
) en lugar de ningún argumento.${var+something}
se expande a "algo" a menos$var
que no esté configurado. Está claramente documentado en todos los shells, pero es difícil de encontrar en labash
documentación, ya que debe prestar atención a esta oración:Por lo tanto, se
${1+"$@"}
expande"$@"
solo si$1
se establece ($# > 0
), lo que evita esa limitación del shell Bourne.Tenga en cuenta que el shell Bourne es el único shell con ese problema. Los
sh
s modernos (que sesh
ajustan a la especificación POSIX desh
(que no es el shell Bourne)) no tienen ese problema. Por lo tanto, solo necesita eso si necesita que su código funcione en sistemas muy antiguos donde/bin/sh
podría haber un shell Bourne en lugar de un shell estándar (tenga en cuenta que POSIX no especifica la ubicación del estándarsh
, por ejemplo, en Solaris antes de Solaris 11,/bin/sh
todavía era un shell Bourne (aunque no tenía ese problema en particular) mientras que el normal / estándarsh
estaba en otra ubicación (/usr/xpg4/bin/sh
)).Sin embargo, hay un problema en esa
perlrun
página perldoc que$0
no se cita.Consulte http://www.in-ulm.de/~mascheck/various/bourne_args/ para obtener más información.
fuente
Hay una diferencia entre:
y
En uno, está pasando un argumento que es una cadena vacía. En el segundo, se pasan cero argumentos.
Por tanto, "$ @" será igual a la misma cosa:
""
. Pero usar${1:+"$@"}
sería""
para el primero y no se aprobaron argumentos para el segundo, que era la intención.Esto se vuelve importante si está haciendo algo en el siguiente script, llamado sshwrapper, al que llama con un comando opcional o sin argumentos para obtener un shell interactivo.
Esto intentaría ejecutar "" en el host remoto (que simplemente regresa), no sería un shell interactivo.
Comenzaría un shell interactivo en el host remoto porque el ejecutivo interpretaría correctamente la variable como nada, no como una cadena vacía.
Lea sobre el uso de "$ {parámetro: + palabra}" ("Usar valor alternativo") y cadenas de expansión variables similares en las páginas del manual de bash.
fuente
sh
implementación compatible con POSIX (ver otra respuesta).${1:+"$@"}
se expandiría a ningún argumento si$1
estuviera vacío. Que desea${1+"$@"}
. Básicamente lo tienes invertido.Resumí la respuesta de Stéphane Chazelas:
así que si usa el segundo con el parámetro "", eso significa que $ 1 es nulo, pero no prueba si es nulo o no, solo ve que ya se ha configurado, sin embargo, está vacío o no, por lo que expandirá $ @ , pero usa $ {1: + "$ @"} 'con "", ya no se expandirá
$@
.fuente