【问题标题】:Why are curly braces not interpreted by surrounding backticks in Perl?为什么 Perl 中的大括号不被周围的反引号解释?
【发布时间】:2014-02-09 02:48:21
【问题描述】:
my @cmd=`ls {??_in,??}.pl`;
print @cmd;

如果运行那个程序会报错

    `ls: cannot access {??_in,??}.pl: No such file or directory`

现在它已经在终端上运行了

cmd>ls {??,??_in}.pl

cmd>aa_in.pl aa.pl ls.pl

所以它在命令行中产生输出,为什么在 perl 中不考虑那个花括号。

【问题讨论】:

  • 花括号由 shell 解释,而不是由 ls 命令解释。您可以尝试通过 shell 调用命令,例如 bash -c 'ls {??,??_in}.pl'
  • perl 只需 execs 您在没有 shell 的情况下给出的命令。另一方面,执行 globbing 的是 shell。
  • perl 是否使用与您相同的 shell?也许是 Bash 与 csh?
  • @Bill Ruppert,Perl 始终使用 /bin/sh,Windows 除外
  • @devnull:shell 确实 在此处输入图片(隐式通过/bin/sh -c),因为命令字符串包含(未引用的)Perl 文档松散地称为 shell 的实例元字符;在这种情况下,?{} - 请参阅 perldoc -f system。它在这里不起作用的最可能原因是 OP 的 sh 不识别大括号扩展(这是 Bash/Ksh/Zsh 扩展),因此该模式不匹配任何内容并被视为文字,正如解释在dataless' answer.

标签: perl bash


【解决方案1】:

您可以使用Perl's glob built-in 来获取该文件列表,而不是对ls 进行系统调用。

use Data::Dump;
dd [ glob '{??_in,??}.pl' ];

将打印与该模式匹配的文件列表。 glob 将负责填写通配符并查找文件。


还请注意,您正在将反引号的返回值分配给标量变量$cmd,但您正在尝试打印数组@cmd。这些是不同的变量。如果您打开了use strict(您应该这样做!),它也会导致错误全局符号“@cmd”需要明确的包名称...

【讨论】:

  • 为什么?这样做有什么好处?
  • 我需要为什么不工作,为什么它认为给定的表达式作为文件名..如果使用系统函数,它也会说同样的错误。不使用 {} 它工作正常......
  • 请参阅 user000001devnull 的 cmets stackoverflow.com/questions/21645261/…stackoverflow.com/questions/21645261/…。他们解释了为什么它不起作用。我的解决方案可以使用纯 Perl,无需进行系统调用。
【解决方案2】:

我认为这取决于调用哪个 shell。您正在使用 bash 特定的大括号扩展,POSIX shell 不支持。

在我的系统上,我得到以下结果:

$ perl -e '`sh -c "ls src/{*.pl,*.h}"` and print "success\n"'
ls: cannot access src/{*.pl,*.h}: No such file or directory

$ perl -e '`bash -c "ls src/{*.pl,*.h}"` and print "success\n"'
success

所以,我的结论是 perl 正在调用 'sh'。您可以像我的示例中那样使用“bash -c”来解决它。

【讨论】:

  • 或者直接使用glob "{??,??_in}.pl"。少有人听到,适用于所有系统。
  • 确实有很多更好的方法可以解决这个问题。然而,他的困惑与被调用的 shell 有关,这就是我的答案。
  • 当然。但在解释完问题后提及更好的方法总是好的。
猜你喜欢
  • 2015-09-21
  • 2016-06-04
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多