通配符作为 shell 参数
Wildcards as shell parameters
我知道正则表达式和通配符的一般工作原理,但我不太明白为什么可以将它们用作参数。
ls /[!\(][!\(][!\(]/
命令产生以下输出
...
com.apple.launchd.AIPZ6SAfpO
com.apple.launchd.HarlOx3LWS
com.apple.launchd.VmTi5KDz1h
powerlog
/usr/:
X11 include libexec sbin standalone
bin lib local share
/var/:
agentx empty log netboot rwho
at folders ma networkd spool
audit install mail root tmp
backups jabberd msgs rpc vm
db lib mysql run yp
根据我的理解,这应该匹配每三个字符的文件夹名称,不包含斜杠 /[!\(][!\(][!\(]/
但是为什么我可以用它作为参数呢?
您不能使用正则表达式作为参数(或者更确切地说,shell 将字符串放在参数中时不会将其视为正则表达式)。 unquoted glob /[!\(][!\(][!\(]/
匹配,顺序为:
- 一个斜杠。
- 三个不是起始括号的字符。
- 一个斜杠。
换句话说,三个字母的根目录在任何地方都不包含 (
。
shell 将 glob 扩展为零(例如,在 Bash 的 nullglob 的情况下)或更多可以传递给 execve
,在这个命令中:
$ strace -fe execve echo *
execve("/usr/bin/echo", ["echo", "directory1", "directory2"], 0x7ffcff705ce8 /* 44 vars */) = 0
因为 shell 就是这样工作的。任何包含(未加引号的)glob characters/expressions 的参数都将扩展为文件名。这就是 rm *.txt
中发生的事情(因为 *
是一个 glob 字符),这就是 ls /[!\(][!\(][!\(]/
中发生的事情(因为 [abc]
是一个 glob 表达式)。
不过,它们不是正则表达式。参见例如https://mywiki.wooledge.org/glob 语法。
不,你不知道.... shell 模式在 glob(3)
中描述,而正则表达式(更详细的概念)在 regex(3)
中描述 两个不同的库用于类似目的。 sh(1)
在替换参数时根本不使用正则表达式。它仅使用 glob(3)
库。
我知道正则表达式和通配符的一般工作原理,但我不太明白为什么可以将它们用作参数。
ls /[!\(][!\(][!\(]/
命令产生以下输出
...
com.apple.launchd.AIPZ6SAfpO
com.apple.launchd.HarlOx3LWS
com.apple.launchd.VmTi5KDz1h
powerlog
/usr/:
X11 include libexec sbin standalone
bin lib local share
/var/:
agentx empty log netboot rwho
at folders ma networkd spool
audit install mail root tmp
backups jabberd msgs rpc vm
db lib mysql run yp
根据我的理解,这应该匹配每三个字符的文件夹名称,不包含斜杠 /[!\(][!\(][!\(]/
但是为什么我可以用它作为参数呢?
您不能使用正则表达式作为参数(或者更确切地说,shell 将字符串放在参数中时不会将其视为正则表达式)。 unquoted glob /[!\(][!\(][!\(]/
匹配,顺序为:
- 一个斜杠。
- 三个不是起始括号的字符。
- 一个斜杠。
换句话说,三个字母的根目录在任何地方都不包含 (
。
shell 将 glob 扩展为零(例如,在 Bash 的 nullglob 的情况下)或更多可以传递给 execve
,在这个命令中:
$ strace -fe execve echo *
execve("/usr/bin/echo", ["echo", "directory1", "directory2"], 0x7ffcff705ce8 /* 44 vars */) = 0
因为 shell 就是这样工作的。任何包含(未加引号的)glob characters/expressions 的参数都将扩展为文件名。这就是 rm *.txt
中发生的事情(因为 *
是一个 glob 字符),这就是 ls /[!\(][!\(][!\(]/
中发生的事情(因为 [abc]
是一个 glob 表达式)。
不过,它们不是正则表达式。参见例如https://mywiki.wooledge.org/glob 语法。
不,你不知道.... shell 模式在 glob(3)
中描述,而正则表达式(更详细的概念)在 regex(3)
中描述 两个不同的库用于类似目的。 sh(1)
在替换参数时根本不使用正则表达式。它仅使用 glob(3)
库。