7

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

例如

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

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

4

4 回答 4

10

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

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

于 2013-05-23T13:54:25.397 回答
9

这很容易测试:

输入:

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

输出:

123

所以是的。

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

于 2013-05-23T13:42:57.633 回答
6

Perldoc一如既往地有答案。

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

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

于 2013-05-23T14:06:24.577 回答
6

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

  • 使用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` 只是我正在使用的命令的一部分。我让外壳对其进行插值。

我通常对任何使用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'
于 2013-05-23T14:51:16.333 回答