在shell命令中插入perl变量

在shell命令中插入perl变量,perl,Perl,我想将日期作为用户的输入,并将该输入传递给下面的shell命令 例如 $date = ARGV[0]; `cd xyz $date` 这个变量会在perl中插值吗?这是一个很容易测试的问题: 输入: use v5.16; use strict; use warnings; my $foo = 123; say `echo $foo`; 输出: 123 所以是的 但是要注意在shell中包含特殊含义字符的变量。您有几个问题;首先,cd只接受一个参数。也许您的意思是类似于cd xyz$date

我想将日期作为用户的输入,并将该输入传递给下面的shell命令

例如

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

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

这是一个很容易测试的问题:

输入:

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

123
所以是的


但是要注意在shell中包含特殊含义字符的变量。

您有几个问题;首先,
cd
只接受一个参数。也许您的意思是类似于
cd xyz$date
?其次,backticks启动一个shell,该shell执行您给出的命令,该命令将执行changeditory命令,然后立即退出,没有任何效果。(父perl进程的当前目录保持不变。)您可能正在查找

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

与以往一样有答案

具体来说,插值中是否有“是”?列(这里有一个您不需要担心的限制条件),所以是的,可以安全地假设您的变量将被插值


您可以通过在本地命令行上运行“perldoc perlop”来获取相同的文档,通常是这样。

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

  • 使用
    qx/./
    而不是反勾号
  • 首先在Perl变量中设置正在运行的命令,然后插入该变量
qx/./
很好,因为它使您所做的事情更加明显:

my $variable = qx(ls $directory);
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
使用多种字符:

my $variable = qx(ls $directory);
my $variable = qx/ls $directory/;
my $variable = qx^ls $directory^;
my $variable = qx#ls $directory#;
qx
后面的字符将用作引号。若使用圆括号、方括号或花括号,则可以将它们与开始括号和结束括号成对使用

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

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

my $variable = qx(ls $directory);
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的值。在第二个示例中,我使用单引号,因此Perl不会替换
$HOME
的值。相反,字符串
$HOME`只是我正在使用的命令的一部分。我让壳插值它

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

 $date = `date +%M/%Y/%D`
 chop $date;     #Yeah, I said EARLY Perl programs
因为运行Unix命令比试图用纯Perl的方式运行要简单得多。然而,以Perl(即正确的)方式进行操作意味着您不再依赖于不完全由您控制的操作系统的行为

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

my $command = "ls $HOME";
open my command_fh, "|-", $command or die qq(Couldn't execute "$command");
如果只需要执行命令,请使用以下命令:

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

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

试试看会发生什么!我不能尝试这些命令,否则这里会很混乱,因此为了确认,我想问一下,标量变量是否会在命令中插入“.”。您可能无法尝试这些确切的命令,但您可以简单地尝试hello world类型的命令,而不会造成混乱。@David W.u非常感谢。对于像我这样的新手来说,这是一个非常有用的信息。我建议使用
print
而不是
say
,因此
use v5.16
不是必需的。如果没有
use
语句,PerlV5.16.3将给出一个错误。