我想将日期作为用户的输入并将该输入传递给下面的 shell 命令。
例如
$date = ARGV[0];
`cd xyz $date`
这个变量会在 perl 中插值吗?
你有几个问题;首先,cd
只接受一个参数。也许你的意思是这样的cd xyz$date
?其次,反引号启动一个执行您给出的命令的shell,它将执行更改目录命令,然后立即退出,没有任何效果。(父 perl 进程的当前目录保持不变。)您可能正在寻找chdir
.
但是,是的,插值会起作用;要禁用反引号中的插值,您可以转义特殊字符 ( echo xyz \$date
) 或将 qx 与单引号分隔符 ( qx'echo xyz $date'
) 一起使用。
这很容易测试:
输入:
use v5.16;
use strict;
use warnings;
my $foo = 123;
say `echo $foo`;
输出:
123
所以是的。
但请注意在 shell 中包含具有特殊含义的字符的变量。
是的,它会插入变量。但是,我强烈推荐两件事:
qx/../
而不是反引号。这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` 只是我正在使用的命令的一部分。我让外壳对其进行插值。
我通常对任何使用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");
如果只需要执行命令,使用系统命令:
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'