在运行以下命令时,Fedora 31和Debian 10的行为有所不同:
/bin/ls /bin/!(znew) | /bin/grep znewFedora它什么也不输出,但是Debian它输出:
znewznew存在于Fedora上,如果我运行/bin/ls /bin/znew | /bin/grep znew,就会得到:
/bin/znew(在Debian上发生的事情是一样的)
我检查了这两个发行版的bash配置,唯一的不同是在Fedora上我有:
cdable_vars on
cdspell on
dirspell on
login_shell on在Debian上,这些选项是禁用的,extglob在两个发行版上都处于打开状态。
注意:命令grep --这里只使用它来缩短清单
版本:
为什么会有这样的差别呢?
/bin是到Debian和Fedora上/usr/bin的符号链接。
这是在文件名中搜索znew字符串的输出:
updatedb && locate znew
/usr/bin/znew
/usr/share/man/man1/znew.1.gz
/var/lib/flatpak/runtime/org.freedesktop.Platform/x86_64/19.08/5a35247ad1c941455f2f9c4139d9136c6c0662e1b04e5b3c56121e7f67ba0100/files/bin/znew
/var/lib/lxc/centos/rootfs/usr/bin/znew
/var/lib/lxc/centos/rootfs/usr/share/man/man1/znew.1.gz
/var/lib/lxc/opensuse/rootfs/usr/bin/xznew
/var/lib/lxc/opensuse/rootfs/usr/bin/znew
/var/lib/lxc/opensuse/rootfs/usr/share/man/man1/xznew.1.gz
/var/lib/lxc/opensuse/rootfs/usr/share/man/man1/znew.1.gz我发现了一些有趣的东西,Debian中有一个/bin/X11的符号链接,在删除它之后指向.,就像在Fedora中一样。
发布于 2020-05-08 06:48:31
如果在交互式extglob会话中设置了bash shell选项,则命令
ls /bin/!(znew) | grep znew将首先运行ls,其中/bin中的所有名称都不是znew作为参数。如果这个名称列表包含子目录的名称,ls将输出这些子目录的内容(因为-d没有与ls一起使用)。如果其中一个子目录包含名称znew,则grep将匹配并输出该名称。
/bin的未知子目录的内容将由ls列出,而不会在其中的名称之前加上任何目录路径。因此,如果子目录包含znew名称,则它将输出为znew而不是/bin/some-dir/znew。
使用ls时,如
ls /bin/znew | grep znew它将输出字符串/bin/znew而不是znew (如果存在路径名)。这样做是因为它输出作为命令行参数的文件的特定路径名,而不是作为参数提供的目录内容。
如果有人试图为/usr/bin创建一个名为/bin的符号链接,而/bin已经是指向/usr/bin的符号链接,或者/bin仍然是一个目录,则可能会出现这种情况。
在对问题的更新中,发现/bin/X11是指向. (当前目录)的符号链接。这意味着znew可以通过路径名/bin/X11/znew访问。
因此,总之,所发生的是/bin/!(znew)全局模式扩展为路径名列表,其中之一是/bin/X11 (但不是/bin/znew)。然后,ls实用程序将获取所有路径名,包括作为参数的/bin/X11。当ls获得list /bin/X11时,由于/bin/X11指向那里,所以列出了/bin目录的内容。然后,grep实用程序选择znew,这将是ls输出的一部分。
作为Stéphane Chazelas 在评论中指出,如果您的Debian系统上有一个/bin文件,其中包含一个换行符和字符串znew (可能后面跟着另一个换行符,可能还有更多的字符),您将得到同样的效果。
由于名称不完全是字符串znew,所以它将匹配模式/bin/!(znew),而ls将输出这个名称为
/bin/something
znew
maybe moregrep将从该输出中提取znew。
https://unix.stackexchange.com/questions/585295
复制相似问题