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

发布于 2024-07-15 17:34:07 字数 738 浏览 3 评论 0原文

我可以用 000 权限运行 Bash 函数并不完全正确,但差不多了。 我的代码是:

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

hello 文件具有权限:

-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 函数:“unset hello”。 我收到错误:

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

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

It is not totally rigth that I can run a Bash function with 000 permissions, but almost. My code is:

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

The hello-file has permissions:

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

Firtsly, I type with the current permissions:

$ . ./hello_file;hello

The tweak is to change the 400 permissions to 000 right before running the bash script script:

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

It gives one error, but it does not stop running the function. I cannot understand. I now unset the hello-function: "unset hello". I receive the errors:

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

Why did I not get them at the first time? Has it something to do with cache, buffer or something like it? Why can I run the Bash script with 000 permissions [1]?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

生寂 2024-07-22 17:34:07

不是运行该脚本,而是采购(包括)它。 为了获取脚本的来源,您只需要读取权限。

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


更新:

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

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

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

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

$ . ./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

You are not running the script, you are sourcing (including) it. In order to source a script, you only need the read permission.

By the way, functions simply exist, they don't have permission. Once the file was sourced and the function defined, you can run it as much as you want.


Update:

Why did I not get them at the first time? Has it something to do with cache, buffer or something like it?

Yes, like Pax answered, hello was probably previously defined there from a previous sourcing of the file. You may be confused with what sourcing ("." builtin command) does. Sourcing reads the file and runs all its commands in the current shell, then goes back to the prompt. So, if you run the file once, its functions are defined in the current shell instance, and they stay there until you finish that shell session (or unset them).

Why can I run the Bash script with 000 permissions [1]?

You can't. Note that it presents an error. Quoting your output:

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

You executed two commands in a single command-line. The sourcing failed with "Permission denied". The "Hello!" output is from a previous sourcing of the file. You just proved it yourself when you unset it and tried the same command-line again.

You can't call that caching... it is how the shell works. You source another file, all its definitions are included in the current shell session and stay there. If you actually run the script (not sourcing) you shouldn't get any residues in the current session.

$ chmod +x hello_file
$ ./hello_file           # note: executed, not sourced
$ hello
-bash: hello: command not found
倒数 2024-07-22 17:34:07

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

那么,脚本将不会运行。 但 hello() 仍然是您之前运行时定义的。

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

The most likely explanation is that you've run hello_file before it was protected and the function has already been created. Then you protected your script (you say 100 in the command but mention 000 in your text).

So, then the script won't run. But hello() is still defined from you previous run.

Try to open a new shell or just execute unset hello.

水染的天色ゝ 2024-07-22 17:34:07

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

Did you source the script (i.e. run ". ./hello_file") before changing the mode to 100? If that's the case, then the "hello" function is simply still loaded into bash. Subsequently attempting to source an unreadable file won't change that. To test correctly, make sure you launch a fresh shell.

柒七 2024-07-22 17:34:07

为了运行程序(无论是 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 它,您不应该具有读取权限,然后该函数将不会被定义。

In order to run a program (whether it's a bash script, or binary executable), you need to have execute permissions. When you enter a command, the first word (such as ./foo in the below) specifies the command to run, and that is started up as a separate process; in the case of a shell script, it executes a new copy of the shell interpreter listed on the #! line, and runs the program using that interpreter.

$ 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

When you use the . command, that is a shell builtin command that says to source the file into the current shell; that means that it executes the commands in the file as if you had run them from the command line, right in the current file. You need only read permission to source a file. For example, if you set a variable in a sub-process, it doesn't change the value in the current shell; but if you source a bash script into the current shell, then it does change the value:

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

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

A shell function (like in your example) is a lot like a variable, but it acts like a command in the current shell. So, when you source your hello_file using ., that defines that function in the current shell, and it can execute like any other shell function you have defined.

As far as the permissions are concerned, I would bet that before changing the permissions to 100 (which means only executable, not readable, which is fairly useless for a file since you need to be able to read it and execute it to do anything), you had already sourced the file into your current shell. That would mean that the function was already defined, and it doesn't matter the permissions of the file after it's defined; once the function is defined in the current shell, you can even delete the file, and as long as that shell is still open, the function will still be defined.

Edit: As I see from your edited question, once you unset the function, you get an error. That indicates strongly to me that my hypothesis was correct, and that you had already sourced the file before you changed permissions. As I explained, sourcing and executing the file are entirely different operations, and once you source a file, its permissions (or existence) don't matter at all; the function has already been loaded into the currently running shell. You can tell by running your original experiment after doing the unset hello; if you chmod 000 it, you shouldn't have read permissions, and then the function won't be defined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文