我们在各个子目录中有一些应用程序,我们限制 unix 组对其进行访问,并且我们希望它们只能执行。因此,例如,如果我们希望“chem”组的成员对 a.out 具有仅执行访问权限,我们可以:
$ ll -d /tmp/dir1
drwx--x--- 2 root chem 18 Oct 20 07:50 /tmp/dir1/
$ ll /tmp/dir1/a.out
-rwx--x--- 1 root chem 8728 Oct 20 07:50 /tmp/dir1/a.out
现在,我(“chem”组的成员)可以从 bash shell 将此目录添加到我的路径中并执行 a.out:
$ export PATH=/tmp/dir1:$PATH
$ a.out
This is a test. . .
但是,从 tcsh 中,我不能:
$ set path = ( /tmp/dir1 $path )
$ a.out
a.out: Command not found.
我必须向父目录添加组读取权限,以便 tcsh 用户能够运行 a.out(bash 在这两种情况下都有效):
$ ll -d /tmp/dir1
drwxr-x--- 2 root chem 18 Oct 20 07:50 /tmp/dir1/
chmod 之后,我注销并重新登录(在 tcsh 下),然后:
$ set path = ( /tmp/dir1 $path )
$ a.out
This is a test. . .
我们预计不需要父目录的读取权限。我已经查阅了所有文档来解释在这种情况下 bash 和 tcsh 之间明显的行为差异,但没有运气。谁能解释一下吗?顺便说一句,我在 SLES 12 和 CentOS 7 下进行了这些测试,两种情况下的行为是相同的。
答案1
bash
每次运行命令时,都会搜索 $PATH 中的每个目录(从第一个到最后一个),并尝试从该目录运行该命令。它要么成功,要么失败。因此,如果/tmp/dir1
位于您的 $PATH 中,并且a.out
位于该目录中,您可以尝试运行a.out
- bash
will try to run /tmp/dir1/a.out
,并且会成功,因为您具有执行权限。
csh
是不同的。当您更改(或设置) 时$path
,csh
会构建在路径中每个目录中找到的所有内容的哈希表,并且它会记住这些目录在路径中出现的顺序。默认情况下,当您运行命令(不使用完整路径名)时,csh
会查看其哈希表以查看它是否记得该命令位于路径中的某处(并且如果路径中的多个目录都有该命令,则它会选择第一个)它按照 中列出的顺序找到它$path
。如果它在哈希表中没有找到它,那么它假设不存在这样的命令,并且您会收到一个错误,这在很久以前就很有用,当时它所花费的时间量。向下搜索路径中的所有目录并查找命令实际上不再那么重要了,但csh
一直都是这样,今天仍然如此。
为了csh
构建其哈希表,它需要对$path
.因为它需要能够准确地知道哪些可执行文件位于$path
.因为您已拒绝 的读取权限/tmp/dir1
,csh
所以无法为其构建哈希表,并且它会将其视为该目录中根本没有命令。这就是为什么在没有读取权限的目录中csh
找不到您的文件的原因。a.out
$path
为了能够csh
在 $path 上的目录中找到没有读取权限的命令,您必须关闭哈希函数。您可以通过运行内置命令来完成此操作unhash
。一旦你运行它,哈希表函数就会关闭,并且csh
将回退到仅尝试搜索路径中的每个目录,看看它是否可以从中运行命令,就像这样bash
做一样。
这种哈希行为的另一个副作用是,如果您将可执行文件添加到csh
搜索路径上的目录,csh
则不会知道这一点。因此,假设您输入emacs
(/usr/local/bin
位于您的搜索路径上)。然后你尝试运行emacs
,然后...命令未找到。为了解决这个问题(不关闭散列),您可以运行rehash
它,告诉csh
我们构建一组新的散列表,它将拾取已添加的任何新内容。