我在尝试将这些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中正确设置这些命令吗?
答案 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;