【问题标题】:Why doesn't chmod -R +x *.sh work?为什么 chmod -R +x *.sh 不起作用?
【发布时间】:2016-01-04 05:01:05
【问题描述】:

因此,“chmod -R +x *.sh”在 bash 中不起作用。可以找到替代方案here。我的问题是:为什么它不起作用? chmod 是否只是因为没有人费心去实现它而缺少这个功能,还是有一些更深层次的 bash/gnulib 哲学?

【问题讨论】:

  • 我想你想要的是find . -name '*.sh' -exec chmod +x {} +
  • 使用 find-exec 代替
  • 为什么你认为它“不起作用”?它对所有名称以“.sh”结尾的文件以及所有子目录中名称以“.sh”结尾的文件设置可执行位。工作得很好。

标签: bash chmod


【解决方案1】:

这是因为在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。如您所见,所有参数都不是目录,因此-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

【讨论】:

    【解决方案2】:

    * 不被chmod 处理;这是一个称为globbing 的shell 功能。 shell 将*.sh 扩展为当前目录中以.sh 结尾的所有名称的列表,并将它们作为单独的参数传递给chmod。 shell 不知道该命令有任何递归目录搜索方面,chmod 也不知道命令行中有一个 *

    【讨论】:

      【解决方案3】:

      当您运行该命令时,它首先由您的 shell 预处理,然后执行。在预处理阶段,星号 * 被扩展为匹配项(在本例中为当前目录中的 shell 文件)。然后,-R 被忽略,因为没有可以递归的输入目录。

      chmod 不缺这个功能。它甚至没有得到您最初在命令中使用星号的信息。

      【讨论】:

        猜你喜欢
        • 2013-05-24
        • 1970-01-01
        • 1970-01-01
        • 2014-12-07
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2021-12-29
        • 2015-09-25
        相关资源
        最近更新 更多