Lui*_*uis 2 shell perl wildcards
有一个文件夹,里面有一堆文件和一个 perl 脚本,使用 ls 和通配符列出它们,例如:
#!/usr/bin/perl
system("ls -U -1 dir/*");
Run Code Online (Sandbox Code Playgroud)
我注意到,如果我从 bash 终端运行完全相同的命令,我会得到相同的结果,但它们的顺序不同。
为什么会这样?通配符在两种情况下的处理方式是否不同?
例子:
mkdir dir
touch dir/a_0 dir/a1_0
Run Code Online (Sandbox Code Playgroud)
终端输出:
dir/a_0
dir/a1_0
Run Code Online (Sandbox Code Playgroud)
perl 输出:
dir/a1_0
dir/a_0
Run Code Online (Sandbox Code Playgroud)
Perl 的system("cmd")
函数通常会派生一个进程,并在子进程中运行系统的 shell(通常/bin/sh
),并将 用作参数["sh", "-c", "cmd"]
,以sh
解析和执行该 shell 命令行。
作为一种优化,它有时可能不需要 shell 调用,如果cmd
不包含空格和制表符以外的任何 shell 元字符(如引用字符或通配符或诸如;
, &&
... 之类的东西),但这里我们有 shell 元字符- 字符,因为我们有一个*
.
因此,这ls -U -1 dir/*
将由系统的外壳程序解释。
它是扩展dir/*
到传递给 的匹配文件列表的外壳ls
,因此它的完成方式取决于外壳。
在终端中,您通常运行登录 shell,通常不是/bin/sh
. 此外(如peterph所指出的),由于它以交互方式运行,该 shell 通常会读取配置文件,例如~/.zshrc
(如果 shell 是zsh
),其中某些设置可能会影响 globbing 的完成方式。
例如:
我的壳是zsh
的,我已经得到了setopt dotglob
我的~/.zshrc
,所以:
$ echo *
.a d é f
Run Code Online (Sandbox Code Playgroud)
无需阅读~/.zshrc
:
$ zsh -c 'echo *'
d é f
$ LC_ALL=C zsh -c 'echo *'
d f é
Run Code Online (Sandbox Code Playgroud)
您会注意到zsh
在对列表进行排序时尊重语言环境。
$ sh -c 'echo *'
d f é
Run Code Online (Sandbox Code Playgroud)
sh
(在我的情况下是 Debian ash
)不尊重语言环境并且像在 C 语言环境中一样排序。
如果你想要perl
的system()
解释与特定的shell的命令行,你可以写:
system("zsh", "-c", "cmd");
Run Code Online (Sandbox Code Playgroud)
当传递更多的参数时,perl
'ssystem()
永远不会隐式调用 shell,所以在上面,它会派生一个进程,在其中运行/bin/zsh
它["zsh", "-c", "cmd"]
作为参数。
归档时间: |
|
查看次数: |
147 次 |
最近记录: |