我正在尝试将一组参数传递给qx
运算符。考虑
my @files=qw(A.txt B.txt);
print qx/ls "@files"/;
这会出错:
ls: cannot access A.txt B.txt: No such file or directory
而明确地替换数组参数:
print qx/ls A.txt B.txt/;
工作正常。如何将perl数组传递给qx
运算符,以使每个数组元素成为shell命令的单独参数?
答案 0 :(得分:3)
删除引号,就像在shell中键入ls "A.txt B.txt"
一样。
print qx/ls @files/;
警告:如果您的数组中名称中包含空格的文件,则此方法无效。你可以单独引用那些,但这听起来不是一个好主意,处理所有特殊字符肯定会在某些时候打破。在这一点上,我建议根本不使用外部程序,而是使用Perl功能。
答案 1 :(得分:3)
在您的情况下,使用
qx/ls @files/;
就够了。
@files
将在qx//
的参数(字符串)中进行插值,不需要将其放在字符串中。
如果@files
的任何元素有空格,则qx/ls @files/
将无效。例如,以下代码
my @files=('A.txt', 'B.txt', 'C .txt');
print qx/ls @files/;
会出现以下错误:
ls: .txt: No such file or directory
ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C: No such file or directory
这可以通过引用@files
的每个元素来解决,实现这一点的方法是
my @files=('A.txt', 'B.txt', 'C .txt');
my $files;
$files .= " \Q$_" for @files;
print qx/ls $files/;
另一种方法是使用map
:
my @files=('A.txt', 'B.txt', 'C .txt');
@files = map { "\Q$_" } @files;
print qx/ls @files/;
上面的代码会出现以下错误(如预期的那样)
ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C .txt: No such file or directory
更新
正如@choroba所指出的, \Q
无法处理文件名中的嵌入换行符。此问题的可能解决方法\'$_\'
无法处理嵌入式单引号。看起来我们需要将它们组合在一起:
my @files=('A.txt', 'B.txt', 'C .txt', "D\t.txt", "E\n.txt", "F'.txt", 'G".txt');
my $files;
$files .= m/\n/ ? " \'$_\'" : " \Q$_" for @files;
print qx/ls $files/;
这将产生以下预期错误
ls: A.txt: No such file or directory
ls: B.txt: No such file or directory
ls: C .txt: No such file or directory
ls: D\t.txt: No such file or directory
ls: E\n.txt: No such file or directory
ls: F'.txt: No such file or directory
ls: G".txt: No such file or directory