zsh compinit: 不安全的目录

769

这是什么意思,我该如何修复它?

zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?

运行compaudit命令会返回以下内容:

There are insecure directories:
/usr/local/share/zsh/site-functions

1
如果您没有更改答案中所给出的所需文件夹所有权的权限,则打开.zshrc文件并在文件开头放置此行ZSH_DISABLE_COMPFIX=true - codeman48
6
这个问题怎么可能不被认为是关于“主要由程序员使用的软件工具”呢?如果不是程序员,那么主要使用zsh的职业是什么? - twiz
28个回答

975

注意:这个答案是从2012年的。


这个方法对我起作用:

$ sudo chmod -R 755 /usr/local/share/zsh/site-functions

致谢:zsh邮件列表上的一篇文章


编辑:如@biocyberman在评论中指出的那样。 您可能还需要更新site-functions的所有者:

$ sudo chown -R root:root /usr/local/share/zsh/site-functions

在我的电脑上(OSX 10.9),我不需要这样做,但你的情况可能会有所不同。

EDIT2: 在OSX 10.11上,只有这个方法有效:

$ sudo chmod -R 755 /usr/local/share/zsh
$ sudo chown -R root:staff /usr/local/share/zsh

在OSX上,用户(user):工作人员(staff)是正确的默认权限。


3
@kirill_igum 你所说的“no root”是指“没有root访问权限”吗?如果是这样,那么你应该将文件复制到你有权限的文件夹中,修复你的.zshenv.zshrc以使用新的文件夹,并对新文件夹执行与我发布的文件夹相同的chmod操作。 - chakrit
1
我注意到在将所有者设置为root之后,需要撤销组和其他用户的写入权限。我修改了chmod命令为sudo chmod -R go-w zsh - gdvd
4
注意:在 /usr/local/share/zsh/site-functions 目录下我有符号链接指向 /usr/local/Cellar,在此之前我还需要运行 chown -R root:staff /usr/local/Cellar,这样才能正常工作。 - mVChr
2
没有明确说明在 macOS 中应该是 root:staff 还是 user:staff。令人困惑。 - Franklin Yu
4
这个回答对我没有用。下面使用“compaudit”命令的回答对我有用。 - Vini
显示剩余14条评论

833

20
值得注意的是,“compaudit”不仅可以用于修复问题,还可用于诊断此类问题,因此这个回答更好。 - Wolph
27
请注意,您可能还需要将文件的所有者更改为root - 我必须执行以下操作:compaudit | xargs chown root - Brad Parks
8
这绝对是最适合我的解决方案。我使用Homebrew安装了zsh和zsh-completions,所以显然不想将其改为由root拥有。 - katy lavallee
6
“compaudit | xargs chmod g-w” 与 “ompaudit | xargs chown root” 对我也有用,似乎可以让 HomeBrew 正常运行。能否有人稍微解释一下这是怎么回事。” 这段话在描述一个解决问题的命令行代码,第一个命令 compaudit | xargs chmod g-w 的作用是去掉某些文件的写权限,第二个命令 ompaudit | xargs chown root 的作用是将某些文件的所有权转移给根用户。通过执行这两个命令,可以让 HomeBrew(软件管理器)正常工作。 - nyxee
3
这非常类似于Homebrew推荐的解决方案:https://docs.brew.sh/Shell-Completion。 - Oliver Joseph Ash
显示剩余3条评论

268

大多数答案都提供了解决方案,但没有说明为什么会出现此警告。以下是来自ZSH的compinit摘录:

  

出于安全原因,compinit还会检查补全系统是否会使用非根用户或当前用户拥有的文件,或世界可写或组可写的目录中的文件,或者不属于根用户或当前用户拥有的文件。如果找到这样的文件或目录,compinit将询问是否真的应该使用补全系统。要避免这些测试并使找到的所有文件在不询问的情况下被使用,请使用选项-u,并使用选项-i使compinit默默地忽略所有不安全的文件和目录。当给出-C选项时,将完全跳过此安全检查。

因此,解决方案意味着修复以下内容之一(或全部):

  • 将当前用户设置为所涉及的所有目录/子目录/文件的所有者:

compaudit | xargs chown -R "$(whoami)"
  • 取消有关文件的组/其他用户的写入权限:

  • compaudit | xargs chmod go-w
    

    另一种方法是通过使用跳过这些检查:

    compinit -u
    

    但我并不建议这样做,因为把问题藏起来只能短期解决问题。


    11
    谢谢。我很惊讶人们会没有理解问题就随意输入命令。 - shriek
    16
    多用户系统怎么办?在这种情况下,对于家目录之外的文件(如/usr/local/),执行chown -R "$(whoami)"就不起作用了。根据文档,把这些文件改为属于root会更合理,你觉得呢? - goetz
    2
    我最喜欢这个答案。让我思考为什么会发生这种情况。结果是在将另一个用户添加到我的用户的主组后发生了这种情况。$HOME/.antigen/bundles目录下的文件夹归属于我的用户和我的组。所以在我的情况下,将该用户从组中移除解决了问题。 - Samuel
    5
    这是数十个答案中排前三的答案之一。和其他几个优秀答案一样,它解释了正在发生的事情并提供了解决方案。 - David J.
    2
    这是一个非常出色的回答!干得好,谢谢。毫无疑问,这应该是最佳答案。 - James DeCarlo
    显示剩余2条评论

    215

    一旦你理解了原因,解决方案就会变得琐碎明确无误

    • 原因:由compaudit输出的目录具有写入权限,可以被任何其他人(世界可写)所访问;或这些文件的所有者是除root或你自己之外的其他人。

    • 示例:在我的情况下,compaudit给了我这个:

    % compaudit 
    There are insecure directories:
    /usr/local/share/zsh/site-functions
    /usr/local/share/zsh
    

    如果我们列出我们拥有的这些文件/目录的权限(在这种情况下)

    % ls -lh /usr/local/share 
    total 0
    drwxr-xr-x  12 chbrandt  admin   384B Aug 14 10:45 aclocal
    drwxr-xr-x   8 chbrandt  admin   256B Aug 14 10:45 doc
    drwxr-xr-x   3 chbrandt  admin    96B Jul 24 21:00 fish
    lrwxr-xr-x   1 chbrandt  admin    36B Aug 14 10:45 gettext -> ../Cellar/gettext/0.21/share/gettext
    lrwxr-xr-x   1 chbrandt  admin    41B Aug 14 10:45 gettext-0.21 -> ../Cellar/gettext/0.21/share/gettext-0.21
    lrwxr-xr-x   1 chbrandt  admin    37B Aug 14 10:45 gtk-doc -> ../Cellar/libidn2/2.3.0/share/gtk-doc
    drwxr-xr-x   9 chbrandt  admin   288B Aug 14 10:45 info
    drwxr-xr-x  58 chbrandt  admin   1.8K Aug 14 10:45 locale
    lrwxr-xr-x   1 chbrandt  admin    41B Jul 27 17:12 luajit-2.0.5 -> ../Cellar/luajit/2.0.5/share/luajit-2.0.5
    drwxr-xr-x   5 chbrandt  admin   160B Jul 27 17:12 man
    lrwxr-xr-x   1 chbrandt  admin    33B Aug 14 10:45 nvim -> ../Cellar/neovim/0.4.4/share/nvim
    drwxrwxr-x   3 chbrandt  admin    96B Jul 24 20:57 zsh
    %
    % ls -lh /usr/local/share/zsh 
    total 0
    drwxrwxr-x  4 chbrandt  admin   128B Jul 24 21:00 site-functions
    %
    % ls -lh /usr/local/share/zsh/site-functions 
    total 0
    lrwxr-xr-x  1 chbrandt  admin    39B Jul 24 21:00 _brew -> ../../../Homebrew/completions/zsh/_brew
    lrwxr-xr-x  1 chbrandt  admin    44B Jul 24 21:00 _brew_cask -> ../../../Homebrew/completions/zsh/_brew_cask
    

    现在我们很容易发现问题,不是吗?注意 zsh/ zsh / site-functions 目录与其他目录的区别...

    那个 'w' 允许 admin 组对它们进行修改,但 Zsh 不希望这样。

    • 解决方法:关闭组可写权限!
    % chmod g-w /usr/local/share/zsh 
    % chmod g-w /usr/local/share/zsh/site-functions 
    

    就是这样了!你可以开始了。打开一个新的终端,你应该不会再看到“zsh compinit: insecure directories”的信息了;)


    1
    这些目录的权限通常会因为什么原因发生改变? - Jaap Wijnen
    2
    @JaapWijnen 我认为它们并没有被“更改”,那些目录可能是像那样被“创建”的。我甚至不认为这是一个错误(如果你考虑整个环境和chbrandt是一个“su”,而admin是一个特权组等等...)。在这种情况下 - 现在回答你的问题 - 那些“错误”的权限可能是/曾经是zsh/homebrew领域中微小错误的结果...或者是一个被误解的功能 ;) - Brandt
    4
    这是最佳答案,因为它解释了问题并展示了一个真实的具体例子,同时应用了解决方案。 - Alessio
    1
    @Brandt 我尝试了您建议的更改,但错误仍然存在,我发布了一个单独的问题 https://apple.stackexchange.com/questions/431861/zsh-compinit-errors?noredirect=1#comment618960_431861 - Koenig Lear
    2
    太好了。这解决了我在尝试在zsh中启用aws cli命令完成时遇到的问题。如果你想要一个一行代码,这里是 compaudit | sed -n '2,$ p' | xargs -I{} chmod g-w {} - GMaster
    显示剩余5条评论

    58

    自从 High Sierra 更新以来,这适用于我的 Mac。

    移除组写入权限:

    sudo chmod g-w /usr/local/share/zsh/site-functions
    sudo chmod g-w /usr/local/share/zsh
    

    最好将更改限制在zsh目录中。


    6
    这是我在Mac Catalina上唯一有效的解决方法。 - user8467470
    1
    目录仍被列为不安全。 - Farid

    47

    这个答案主要是为了我自己以后参考使用,因为大多数答案并没有提供完整的解决方案。以下是解决方案:

    首先运行:

    compinit
    

    如果上述方法不起作用,请使用 compaudit

    对于打印的每个路径,运行以下命令:

    sudo chown $(whoami) PATH_HERE
    
    sudo chmod -R 755 PATH_HERE
    

    简单的例子,假设运行compinit后打印出来的路径之一是“/usr/local/share/zsh”。然后:

    sudo chown $(whoami) /usr/local/share/zsh
    
    sudo chmod -R 755 /usr/local/share/zsh
    

    3
    对我来说,只需运行“sudo chown $(whoami)PATH_HERE”就可以了。 谢谢! - R Sun
    3
    这个答案对我来说很有帮助。 - Yohan W. Dunon
    2
    这是唯一一个对我实际起作用的。谢谢。 - Chaos Monkey
    1
    奇怪,那是唯一对我起作用的解决方案。 - Farid
    1
    只有这个适用于我——OSX Monterey 12.5.1。 - Michael Paler

    42

    以下命令将更新所有文件/文件夹的正确权限:

    compaudit | xargs chmod g-w

    更改所有者时,除非文件属于root,否则不需要使用sudo

    (在macOS BigSur上测试通过)


    1
    这应该是正确的答案。在使用“sudo”时必须小心。 - Vaibhav Sidapara
    没有任何改变,compaudit 仍然列出不安全的目录。 - Farid

    31

    当我使用sudo -i启动root shell时,我收到了与@chakrit的解决方法相同的警告,但这并没有对我起作用。

    但是我发现compinit-u开关可以解决问题,例如在你的.zshrc/zshenv或者你调用compinit的地方使用。

    compinit -u
    

    注意:不建议在生产系统中使用

    另请参见http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Initialization


    那是唯一对我有效的解决方案。我试图在Windows 10上的Linux子系统中使用带有compinit的zsh。 - denns
    我尝试了所有其他的解决方案,然后尝试了这个,它是唯一对我有效的。谢谢。 - danfromisrael

    26
    在Mojave中,可以使用以下命令来解决问题: sudo chmod go-w /usr/local/share [2022年更新] 如果使用ZSH Completions,则应该使用以下命令: chmod -R go-w "$(brew --prefix)/share"

    4
    更好的做法是:sudo chmod -R go-w /usr/local/share。该命令会递归地移除其他用户和组的写权限,以确保/usr/local/share目录下的文件和子目录不会被误操作修改。 - ecmanaut
    1
    /usr/local/share/zsh 就可以了。 - greatvovan
    3
    如果使用zsh自动补全:https://docs.brew.sh/Shell-Completion#configuring-completions-in-zsh 建议运行 chmod -R go-w "$(brew --prefix)/share" - dijonkitchen

    24

    最近在Catalina上我也遇到了同样的警告。 一个简单的解决方法是将以下内容放置在你的.zshrc文件的顶部:

    ZSH_DISABLE_COMPFIX=true
    

    2
    这是唯一在 macOS Catalina 10.15.5 上帮助我的解决方案!所有其他类似于 compaudit | xargs chmod go-wcompinit -u 的方法似乎在这个版本的 macOS 上都不起作用。 - Denis L
    1
    仅有的解决方案适用于macOS BigSur 11.2.1 (20D74)。非常感谢。 - Ahmet Ardal
    1
    到目前为止,这是最好的解决方案。由于我在MacBook上为多个客户和个人使用单独的帐户,因此有多个用户使用zsh文件夹,我不想一直切换所有权。 至少添加了这个环境变量就可以摆脱令人讨厌的消息了。 - Joost den Boer
    1
    是的,这也是我在Catalina上工作的全部内容。这是苹果近年来更新其操作系统的典型例子,它破坏了越来越多的东西,并添加了许多隐私和安全检查,使得OS X成为任何类型开发都不受欢迎的操作系统。 - pilcrowpipe

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接