在shell命令中插入perl变量

时间:2013-05-23 13:39:41

标签: perl

我想把日期作为User&的输入。将该输入传递给下面的shell命令。

例如

$date = ARGV[0];
`cd xyz $date`

这个变量会在perl中插值吗?

4 个答案:

答案 0 :(得分:10)

你有几个问题;首先,cd只接受一个参数。也许你的意思是cd xyz$date?其次,反引号启动一个执行命令的shell,它将执行change directory命令,然后立即退出,不起作用。 (父perl进程的当前目录保持不变。)您可能正在寻找chdir

但是,插值将起作用;要在反引号中禁用插值,您可以转义特殊字符(echo xyz \$date)或将qx与单引号分隔符(qx'echo xyz $date')一起使用。

答案 1 :(得分:8)

这很容易测试:

输入:

use v5.16;
use strict;
use warnings;
my $foo = 123;
say `echo $foo`;

输出:

123

是的。

请注意包含在shell中具有特殊含义的字符的变量。

答案 2 :(得分:6)

Perldoc答案一如既往。

具体来说,http://perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators在插值中有“是”吗?列(附带条件,你不必担心这里),所以是的,假设你的变量将被插值是安全的。

您可以通过在本地命令行运行'perldoc perlop'来获取相同的文档。

答案 3 :(得分:5)

是的,它会插入变量。但是,我强烈推荐两件事:

  • 使用qx/../代替后退。
  • 设置您在Perl变量中首先运行的命令,然后插入该变量。

qx/../很不错,因为它让您更清楚自己所做的事情:

my $variable = qx(ls $directory);

您可以为qx使用各种各样的字符:

my $variable = qx(ls $directory);
my $variable = qx/ls $directory/;
my $variable = qx^ls $directory^;
my $variable = qx#ls $directory#;

qx之后的字符将用作引号。如果使用括号,方括号或花括号,则可以将它们与开头和结束一对使用。

这意味着您可以避免命令中的特定字符可能会混淆事物的问题。

另一件事是将您的命令构建到Perl变量中,然后在尝试进行插值时执行它。这使您可以更好地控制自己正在做的事情:

my $HOME;
my $command;

$HOME = "bin";
$command = "ls $HOME";
print qx($command); #Lists the directory bin

$command = 'ls $HOME';
print qx($command); #List user's home directory

在这两个例子中,我都在qx($command)。但是,在第一个示例中,我允许Perl替换$HOME. In the second example, I use single quotes, so Perl doesn't substitute the value of $ HOME . Instead, the string $ HOME的值只是我使用的命令的一部分。我让shell插入它。

我通常对使用qx/.../的任何程序持怀疑态度。在大多数情况下,它用于运行可以在Perl中完成的命令。例如,在早期的Perl程序中,您可以看到以下内容:

 $date = `date +%M/%Y/%D`
 chop $date;     #Yeah, I said EARLY Perl programs

因为运行Unix命令而不是尝试以纯Perl方式执行它更容易。但是,使用Perl(即正确的)方式意味着您不再依赖于操作系统的行为,而这种行为并非完全由您控制。

如果您需要在Perl脚本中使用该命令的输出,则应使用open执行命令,并将该命令的输出视为文件。

my $command = "ls $HOME";
open my command_fh, "|-", $command or die qq(Couldn't execute "$command");

如果您只需要执行命令,请使用system命令:

my $command = "xyz $date";
my $error = system $command;
if ( $error ) {
    #Something terrible happened...
}

请注意,如果只向system命令发送单个标量参数, 它包含可能的shell元字符,它将通过命令执行命令OS shell。如果您发送system命令要执行的列表, ,则没有shell元字符,Perl将调用命令执行程序直接执行命令而不执行任何shell插值:

my @command = qw(ls $HOME);
system @command;   #Will print out "No such directory '$HOME'