为什么 chmod -R +x *.sh 不起作用?
Why doesn't chmod -R +x *.sh work?
因此,"chmod -R +x *.sh" 在 bash 中不起作用。可以找到替代方案 here。我的问题是:为什么它不起作用? chmod 缺少此功能是因为没有人费心去实现它,还是对此有更深层次的 bash/gnulib 哲学?
*
未被 chmod
处理;这是一个 shell 功能,称为 globbing。 shell 将 *.sh
扩展为当前目录中以 .sh
结尾的所有名称的列表,并将它们作为单独的参数传递给 chmod
。 shell 不知道该命令有任何递归目录搜索方面,并且 chmod
永远不知道命令行中有 *
。
当你运行命令时,它首先被你的shell预处理然后执行。在预处理阶段,星号 *
被扩展为匹配项(在本例中为当前目录中的 shell 文件)。然后,-R
被忽略,因为没有可以递归的输入目录。
chmod
不缺这个功能。它甚至没有得到您原来在命令中有星号的信息。
这是因为在 bash
中,通配符模式是由 shell 而不是程序扩展的。这与 Windows 不同,后者将模式传递给程序本身。让我们考虑这个样本目录结构:
curdir
|_ 1.sh
|_ 2.sh
|_ subdir
|_ 3.sh
|_ 4.sh
假设您要从 curdir
目录中 运行 命令 chmod -R +x *.sh
。 shell 看到 *.sh
是通配符模式并将其扩展为 1.sh 2.sh
因为这些是与该模式匹配的文件名。最后执行的命令变为chmod -R +x 1.sh 2.sh
。如您所见,参数的 none 是一个目录,因此 -R
开关无效。
有 shell 支持更复杂的模式。例如,如果您使用 zsh
,则可以 运行 以下命令:
chmod +x **/*.sh # Note that -R is not required
zsh
understands **
模式表示递归搜索子目录。因此,这种情况下的最终命令将是:
chmod +x 1.sh 2.sh subdir/3.sh subdir/4.sh
因此,"chmod -R +x *.sh" 在 bash 中不起作用。可以找到替代方案 here。我的问题是:为什么它不起作用? chmod 缺少此功能是因为没有人费心去实现它,还是对此有更深层次的 bash/gnulib 哲学?
*
未被 chmod
处理;这是一个 shell 功能,称为 globbing。 shell 将 *.sh
扩展为当前目录中以 .sh
结尾的所有名称的列表,并将它们作为单独的参数传递给 chmod
。 shell 不知道该命令有任何递归目录搜索方面,并且 chmod
永远不知道命令行中有 *
。
当你运行命令时,它首先被你的shell预处理然后执行。在预处理阶段,星号 *
被扩展为匹配项(在本例中为当前目录中的 shell 文件)。然后,-R
被忽略,因为没有可以递归的输入目录。
chmod
不缺这个功能。它甚至没有得到您原来在命令中有星号的信息。
这是因为在 bash
中,通配符模式是由 shell 而不是程序扩展的。这与 Windows 不同,后者将模式传递给程序本身。让我们考虑这个样本目录结构:
curdir
|_ 1.sh
|_ 2.sh
|_ subdir
|_ 3.sh
|_ 4.sh
假设您要从 curdir
目录中 运行 命令 chmod -R +x *.sh
。 shell 看到 *.sh
是通配符模式并将其扩展为 1.sh 2.sh
因为这些是与该模式匹配的文件名。最后执行的命令变为chmod -R +x 1.sh 2.sh
。如您所见,参数的 none 是一个目录,因此 -R
开关无效。
有 shell 支持更复杂的模式。例如,如果您使用 zsh
,则可以 运行 以下命令:
chmod +x **/*.sh # Note that -R is not required
zsh
understands **
模式表示递归搜索子目录。因此,这种情况下的最终命令将是:
chmod +x 1.sh 2.sh subdir/3.sh subdir/4.sh