我可以运行具有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脚本?
答案 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
它,你就没有读权限,然后就不会定义该函数。