当使用反勾号(在perl中)时,我似乎与大括号扩展有某种不一致。
print `ls -d ~/{a,b}`;
工作正常,但当我尝试
print `ls -d ~/{a}`;
我得到:
ls: cannot access /home/user/{a}: No such file or directory
我试过各种引用、空格和转义,但都没有用。我的问题是,有没有办法强制扩展?我意识到如果我自己把这些东西弄混,我可以一起避免这个问题,但我对这种行为很好奇
我在bash和tcsh下都试过了。当直接在tcsh下使用时,该命令可以工作,但在bash下不能
2条答案
按热度按时间ctehm74n1#
现在,经过你的几次编辑,我明白你可能使用了两个不同的shell。而且,调用shell的是Perl,而不是你。
所以,要涵盖三个要素:
狂欢
在bash中。简单的{a}将不会展开:
ls
将其作为文件进行搜索,但未找到。手册的相关部分是(强调我):
格式正确的大括号扩展必须包含不带引号的左大括号和右大括号,以及至少一个不带引号的逗号或有效的序列表达式。
{a}
缺少必需的逗号。唯一的选择就是
tcsh命令
在
tcsh
中:将展开简单的{a}(如同在csh
shell中):使用
>
作为tcsh提示符的shell指示符:作为一个简单的
{}
也将:{}
、{
和}
。如果
{
或}
作为单词的 part 出现,但没有匹配的大括号,则为错误:man tcsh上对此的唯一描述非常简短(不清楚?):
Perl语言
如果shell命令是called from perl,则在调用shell的情况下(如在Unix系统下),调用的shell是
/bin/sh
。另一个变化是,在大多数linux系统中,
/bin/sh
由bash、tcsh in FreeBSD和ksh or csh in OpenBSD提供服务。很难预测一个名为
/bin/sh
的perl的输出。您可以确保特定shell的名称为:
现在的问题是:
eh57zj3b2#
当您在使用shell命令时遇到问题时,请在Perl(或任何程序)之外尝试使用这些命令,看看它们的作用:
猛击:
切:
因此,您可以看到这两个shell以不同的方式展开globs。
格式正确的大括号扩展必须包含不带引号的左大括号和右大括号,以及至少一个不带引号的逗号或有效的序列表达式。任何格式不正确的大括号扩展都将保持不变。
从tcsh docs是一个有点缺乏,因为它没有提到,你不需要逗号的扩展:
元表示法“a{B,c,d}e”是“abe ace ade”的简写。从左到右的顺序被保留:“/usr/source/s1/{oldls,ls}.c”扩展为“/usr/source/s1/oldls.c/usr/source/s1/ls.c”。匹配结果在较低级别单独排序,以保留以下顺序:.."/{备忘录,* 框}“可能会扩展为..”/备忘录../框../mbox“。(请注意,'memo'没有使用匹配'* box'的结果进行排序。)当此构造展开到不存在的文件时,这不是错误,但可能会从向其传递展开列表的命令中获取错误。此构造可能是嵌套的。作为特殊情况,单词'{',“}”和“{}”不受干扰地传递。
现在,在Perl中,反勾号使用 /bin/sh,它不关心您在哪个shell中启动 perl 进程。
一个字符串,它(可能)被插入,然后作为系统命令与/bin/sh或其等效命令一起执行。
这就是为什么你会看到bash行为。但是,你可以使用任何你喜欢的shell(并且在系统上可用):