ayuda a migrar comandos de Unix a un script de Perl

Recibo algunos errores de compilación de Perl al intentar convertir estos comandos de Unix a Perl. El uso de comillas simples y dobles me desconcierta (ver a continuación: my $curlcmd).

Este es el trabajando comandos de Unix ejecutados en orden:

export CERT=`/dev/bin/util --show dev.testaccnt | awk '{print $2}'`

/usr/bin/curl -c /home/foobar/cookee.txt --certify /dev/key.crt \
     --header "FooBar-Util:'${CERT}'" \
     https://devhost.foobar.com:4443/fs/workflow/data/source/productname?val=Summ

Quiero hacer lo mismo dentro Perl:

#Build cmd in perl
my $cookie='/home/foobar/cookee.txt';
my $certkey='/dev/key.crt';
my $fsProxyHostPort='devhost.foobar.com:4443';
my $fsPath='workflow/data/source/productname';
my $fsProxyOperation='Summ';
my $fsProxyURL="https://$fsProxyHostPort/fs/$fsPath?val=$fsProxyOperation";

#Get cert
my $cert=qx(/dev/bin/pass-util --show foobar.dev.testaccnt | awk '{print \$2}');

Aquí es donde tengo problemas para ejecutarlo:

my $curlcmd = qx(/usr/bin/curl -c $cookie --certify $certkey --header "FooBar-Util:'${" . $cert . "}'". $fsProxyURL);

¿Alguien puede mostrarme cómo configurar estos comandos en Perl correctamente?

preguntado el 27 de agosto de 11 a las 15:08

Es extremadamente convencional tener ejecutables o archivos de datos bajo /dev; ese directorio es para dispositivos (como /dev/null, /dev/tty) y normalmente los usuarios no deberían modificarlo, ni tampoco crearía subdirectorios ni pondría comandos en él. Su nombre no es una abreviatura de development. -

tienes razón. por el simple hecho de publicar mi ejemplo, debería haber usado /devel. -

3 Respuestas

¿Es a propósito que tiene dos definiciones diferentes de $cert?

Tu traducción de --header "FooBar-Util:'${CERT}'" es malo. los ${...} le dice al caparazón que inserte el CERT variable, pero como ya está haciendo esta inserción desde Perl, no es necesaria y solo confundirá.

También te falta un espacio antes del $fsProxyURL.

Como aparentemente no está usando la salida capturada de curl para nada, le sugiero que use el system en su lugar, para evitar el uso de un análisis de línea de comandos de shell intermedio:

system "/usr/bin/curl","-c",$cookie,"--certify",$certTheFirst,
       "--header","FooBar-Util:'$certTheSecond'", $fsProxyURL;

Finalmente, no es muy peligroso usar un awk subsidiario para dividir el valor pass-util en campos cuando Perl hace ese tipo de cosas perfectamente bien. Una vez que resuelva el error inmediato, sugiero

my @passwordline = split / /, qx(/dev/bin/util --show dev.testaccnt);
my $certTheSecond = $passwordline[1];

Respondido 27 ago 11, 19:08

perdón por la confusion. hice las ediciones. uno debería ser $certkey y $cert sería el comando para usar la utilidad cert. Gracias. - jdamae

En el script de shell, tiene (en parte):

--header "FooBar-Util:'${CERT}'"

Esto genera algo como:

--header FooBar-Util:'data-from-certificate'

donde el curl El comando llega a ver esas comillas simples. Para obtener el mismo resultado en Perl, necesitará:

my $header = "FooBar-Util:'$cert'";
my $out = qx(/usr/bin/curl -c $cookie --certify $certkey --header $header $fsProxyURL);

Cambios:

  • Perdido el ${ ... } notación.
  • Perdió las operaciones de concatenación.

En situaciones en las que tiene problemas para ver la lista de argumentos enviada a un comando, le recomiendo usar un programa análogo al shell echo comando, pero que enumera cada argumento en su propia línea, en lugar de como un conjunto de argumentos separados por espacios en una sola línea. Yo llamo mi versión de esto al para 'lista de argumentos'. Si prueba sus comandos (por ejemplo, la versión de shell) prefijando toda la línea de comandos con al, puedes ver los argumentos que curl vería. Luego puede hacer lo mismo en Perl para comparar los argumentos curl ve en el caparazón con los que le dio Perl. Luego, puede solucionar los problemas, normalmente con mucha más facilidad.

Para depurar con al:

my @lines = qx(al /usr/bin/curl -c $cookie --certify $certkey --header $header $fsProxyURL);
foreach my $line (@lines) { print "$line"; }

Si quieres escribir al en Perl:

#!/usr/bin/env perl
foreach my $arg (@ARGV) { print "$arg\n"; }

Aventuras para validar una respuesta

Afortunadamente, normalmente verifico lo que escribo como respuestas, y lo que está escrito arriba es en su mayoría exacto, excepto por un detalle; Perl logra invocar el shell en el comando y, al hacerlo, el shell limpia las comillas simples:

my $cert = 'certificate-info';
my $fsProxyURL = 'https://www.example.com/fsProxy';
my $cookie = 'cookie';
my $certkey = 'cert-key';
my $header = "FooBar-Util:'$cert'";
#my @out = qx(al /usr/bin/curl -c $cookie --certify $certkey --header $header $fsProxyURL);
my @cmdargs = ( 'al', '/usr/bin/curl', '-c', $cookie, '--certify', $certkey, '--header', $header, $fsProxyURL);
print "System:\n";
system @cmdargs;
print "\nQX command:\n";
my @lines = qx(@cmdargs);
foreach my $line (@lines) { print "$line"; }

Esto produce:

System:
/usr/bin/curl
-c
cookie
--certify
cert-key
--header
FooBar-Util:'certificate-info'
https://www.example.com/fsProxy

QX command:
/usr/bin/curl
-c
cookie
--certify
cert-key
--header
FooBar-Util:certificate-info
https://www.example.com/fsProxy

Note la diferencia en las líneas `FooBar!

En este punto, comienza a preguntarse cuál es la forma menos impura de solucionar esto. Si desea utilizar el qx// operador, entonces probablemente lo haga:

my $header = "FooBar-Util:\\'$cert\\'";

Esto produce las salidas variantes (system luego qx//):

FooBar-Util:\'certificate-info\'

FooBar-Util:'certificate-info'

Por lo tanto, la qx// La notación ahora da las comillas simples al comando ejecutado, al igual que en el script de shell. Esto cumple con el objetivo, por lo que voy a sugerir que está "bien" para usted; Simplemente no estoy seguro de que realmente lo adopte en mi propio código, pero no tengo un mecanismo más limpio a mano. Me gustaría poder usar el system más el mecanismo de 'matriz de argumentos', mientras todavía captura la salida, pero no he comprobado si hay una forma sensata (es decir, relativamente fácil) de hacerlo.

Otro comentario de pasada; si alguno de sus argumentos contenía espacios, tendría que tener mucho cuidado con lo que pasa a través del shell. Tener el al comando disponible realmente vale la pena entonces. No puede identificar en qué espacios echo la salida son partes de un argumento y que son separadores proporcionados por echo.

Respondido 27 ago 11, 20:08

Este patrón de " . $cert . " parece ser un remanente de algún otro código, donde se usaron comillas negras y no qx. Eliminar las comillas negras y las concatenaciones (.) funciona en mi máquina.

Entonces, para ejecutar el comando, haga:

my $curlcmd = qx(/usr/bin/curl -c $cookie --certify $certkey --header "FooBar-Util:'${ $cert }'". $fsProxyURL);

Siguiendo su comentario, si solo desea imprimir el comando, puede hacer:

my $curlcmd = qq(/usr/bin/curl -c $cookie --certify $certkey --header "FooBar-Util:'${ $cert  }'". $fsProxyURL);
print $curlcmd;

Respondido 27 ago 11, 19:08

Gracias. si quisiera imprimir esto para ver la salida primero. ¿Puedo hacer una impresión sin ejecutarla? - jdamae

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.