为什么我可以使用000权限运行Bash函数?

时间:2009-03-25 23:52:59

标签: bash file-permissions

我可以运行具有000权限的Bash功能并不是完全严格的,但差不多。我的代码是:

#!/bin/bash
function hello {
echo Hello! }

hello-file有权限:

-r--------  1 UnixBasics hello_file

首先,我使用当前权限键入:

$ . ./hello_file;hello

调整是在运行bash脚本脚本之前将400权限更改为000:

$ chmod 000 hello_file
$ . ./hello_file;hello                                             [1]
-bash: ./hello_file: Permission denied 
Hello!

它给出了一个错误,但它并没有停止运行该函数。我不明白。我现在取消设置hello-function:“unset hello”。我收到错误:

-bash: ./hello_file: Permission denied
-bash: hello: command not found

为什么我第一次没有得到它们?它与缓存,缓冲区或类似的东西有关吗?为什么我可以使用000权限[1]运行Bash脚本?

4 个答案:

答案 0 :(得分:11)

正在运行脚本,您采购(包括)它。要获取脚本,您只需要读取权限。

顺便说一句,功能只是存在,他们没有权限。一旦文件来源并定义了函数,您就可以根据需要运行它。


更新

  

为什么我第一次没有得到它们?它与缓存,缓冲区或类似的东西有关吗?

是的,就像Pax回答的那样,你好之前可能已经从之前的文件来源中定义了问题。您可能会对采购(“。”内置命令)的作用感到困惑。 Sourcing读取文件并在当前shell中运行其所有命令,然后返回到提示符。因此,如果您运行该文件一次,其函数将在当前shell实例中定义,并且它们会一直保留在那里,直到您完成该shell会话(或取消设置它们)。

  

为什么我可以使用000权限[1]运行Bash脚本?

你做不到。请注意,它会出现错误。引用你的输出:

$ . ./hello_file;hello                                             [1]
-bash: ./hello_file: Permission denied 
Hello!

您在一个命令行中执行了两个命令。采购失败,“许可被拒绝”。 “你好!”输出来自先前的文件来源。当你取消它并再次尝试相同的命令行时,你就自己证明了这一点。

你无法调用缓存......它是shell的工作方式。您获取另一个文件,其所有定义都包含在当前shell会话中并保留在那里。如果你实际上运行脚本(不是采购),你不应该在当前会话中得到任何残留。

$ chmod +x hello_file
$ ./hello_file           # note: executed, not sourced
$ hello
-bash: hello: command not found

答案 1 :(得分:5)

最可能的解释是,在受保护之前运行hello_file并且已经创建了该函数。然后你保护你的脚本(你在命令中说100但在文中提到000)。

因此,脚本将无法运行。但是hello()仍然是从你之前的运行中定义的。

尝试打开新shell或只执行unset hello

答案 2 :(得分:2)

在将模式更改为100之前,您是否获取了脚本(即运行“./hello_file”)?如果是这种情况,那么“hello”函数仍然只是加载到bash中。随后尝试获取不可读的文件不会改变它。要正确测试,请确保启动 fresh shell。

答案 3 :(得分:2)

为了运行程序(无论是bash脚本还是二进制可执行文件),您需要具有执行权限。输入命令时,第一个单词(如下面的./foo)指定要运行的命令,并将其作为单独的进程启动;在shell脚本的情况下,它执行#!行上列出的shell解释器的新副本,并使用该解释器运行程序。

$ ls -l foo
-rw-r--r--  1 lambda  lambda  23 Mar 25 20:02 foo
$ chmod 744 foo # or chmod u+x foo
$ ls -l foo
-rwxr--r--  1 lambda  lambda  23 Mar 25 20:02 foo
$ ./foo
Hello

当您使用.命令时,这是一个shell内置命令,用于将文件提供到当前shell中;这意味着它执行文件中的命令,就像您从命令行运行它们一样,就在当前文件中。您只需要读取权限即可获取文件。例如,如果在子流程中设置变量,则不会更改当前shell中的值;但是如果你将bash脚本输入到当前shell中,那么它确实会更改值:

$ foo=bar
$ cat setvariables 
#!/bin/sh

foo=hello
$ ./setvariables
$ echo $foo
bar
$ . ./setvariables
$ echo $foo
hello

shell函数(如您的示例中)很像变量,但它的作用类似于当前shell中的命令。因此,当您使用hello_file来源.时,它会在当前shell中定义该函数,并且它可以像您定义的任何其他shell函数一样执行。

就权限而言,我敢打赌,在将权限更改为100之前(这意味着只有可执行文件,不可读,这对文件来说相当无用,因为您需要能够读取并执行它做任何事情),你已经把文件发送到你当前的shell中了。这意味着函数已经定义,并且文件定义后的权限无关紧要;一旦在当前shell中定义了该函数,您甚至可以删除该文件,只要该shell仍处于打开状态,该函数仍将被定义。

编辑:正如我从您编辑过的问题中看到的那样,一旦取消设置该功能,就会出现错误。这向我强烈表明我的假设是正确的,并且您在更改权限之前已经获取了该文件。正如我所解释的那样,获取和执行文件是完全不同的操作,一旦你获取文件,它的权限(或存在)根本不重要;该函数已加载到当前运行的shell中。您可以在执行unset hello之后运行原始实验。如果你chmod 000它,你就没有读权限,然后就不会定义该函数。

相关问题