帮助将unix命令移植到perl脚本

时间:2011-08-27 15:05:53

标签: perl

我在尝试将这些unix命令转换为perl时遇到一些perl编译错误。 使用单引号和双引号会让我失望(见下文:my $curlcmd)。

以下是按顺序执行的工作 unix命令:

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

我想在 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}');

这是我执行它时遇到的问题:

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

有人可以告诉我如何在Perl中正确设置这些命令吗?

3 个答案:

答案 0 :(得分:1)

您是否有两个不同的$cert定义?

您对--header "FooBar-Util:'${CERT}'"的翻译很糟糕。 ${...}告诉shell插入CERT变量,但由于你已经从Perl中进行了这个插入,所以不需要它,只会混淆。

您还错过$fsProxyURL之前的空格。

由于您显然没有使用curl捕获的输出,我建议您使用system函数,以避免使用中间shell命令行解析:

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

最后,当Perl完美地完成这类工作时,使用辅助awk将pass-util值拆分为字段并不是很有意义。一旦你解决了即时错误,我建议

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

答案 1 :(得分:1)

在shell脚本中,你有(部分):

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

这会生成如下内容:

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

curl命令可以看到那些单引号。要在Perl中获得相同的结果,您需要:

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

的变化:

  • 丢失了${ ... }符号。
  • 丢失了连接操作。

如果您在查看发送到命令的参数列表时遇到问题,我建议使用类似于shell echo命令的程序,但是它会在每条参数列中列出每个参数,而不是作为空格列出 - 在一行上分隔的参数集。我将此版本al称为“参数列表”。如果通过在整个命令行前加al来测试命令(例如,shell版本),则可以看到curl将看到的参数。然后,您可以在Perl中执行相同操作,将shell中查看的curl参数与Perl提供的参数进行比较。然后你可以更容易地解决问题。

使用al进行调试:

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

如果您想在Perl中编写al

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

验证答案中的冒险

幸运的是,我通常会检查我写的答案 - 上面写的内容大部分都是准确的,除了一个细节; Perl设法在命令上调用shell,并且这样做,shell清除单引号:

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"; }

这会产生:

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

请注意`FooBar行的差异!

此时,你开始想知道解决这个问题最不干净的方法是什么。如果您想使用qx//运算符,那么您可能会这样做:

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

这会产生变体输出(system然后qx//):

FooBar-Util:\'certificate-info\'

FooBar-Util:'certificate-info'

因此,qx//表示法现在为执行的命令提供单引号,就像在shell脚本中一样。这符合目标,所以我建议你对它“好”;我只是不确定我是否真的在我自己的代码中采用它,但我手边没有更清晰的机制。我希望能够使用system加上'参数数组'机制,同时仍然捕获输出,但我还没有检查是否有一种明智的(意思是相对简单的)方法。< / p>

另一个传递评论;如果你的任何参数包含空格,你必须非常小心地通过shell传递什么。拥有al命令确实可以获得回报。您无法确定echo输出中哪些空格是一个参数的一部分,哪些是echo提供的分隔符。

答案 2 :(得分:0)

这个" . $cert . "似乎是其他一些代码的遗留物,其中使用了黑色引号,而不是qx。删除黑色引号和连接(.)可在我的计算机上运行。

因此,要执行命令,请执行:

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

根据您的评论,如果您只想打印命令,可以执行以下操作:

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