Чтобы запустить программу (будь то скрипт bash или исполняемый файл), вам необходимо иметь разрешения на выполнение. Когда вы вводите команду, первое слово (например, ./foo
ниже) указывает команду для запуска и запускается как отдельный процесс; в случае скрипта оболочки он выполняет новую копию интерпретатора оболочки, указанную в строке #!
, и запускает программу с использованием этого интерпретатора.
$ 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
При использовании команды .
, то есть оболочка встроенной команды, которая говорит источник файла в текущей оболочке; это означает, что он выполняет команды в файле, как если бы вы запускали их из командной строки прямо в текущем файле. Вам нужно только разрешение на чтение для источника файла. Например, если вы установите переменную в подпроцессе, она не изменит значение в текущей оболочке; но если источник Баш скрипт в текущей оболочке, то это действительно изменяет значение:
$ foo=bar
$ cat setvariables
#!/bin/sh
foo=hello
$ ./setvariables
$ echo $foo
bar
$ . ./setvariables
$ echo $foo
hello
Функция оболочки (как в вашем примере) много как переменная, но она действует как команда в текущая оболочка. Итак, когда вы отправляете hello_file
с помощью .
, который определяет эту функцию в текущей оболочке, и она может выполняться как любая другая функция оболочки, которую вы определили.
Что касается разрешений, я бы поспорил, что перед изменением разрешений на 100 (что означает только исполняемый, не читаемый, который бесполезен для файла, поскольку вам нужно его прочитать и выполнить делать что-либо), вы уже отправили файл в свою текущую оболочку. Это означало бы, что функция уже определена, и это не имеет значения для разрешений файла после его определения; как только функция определена в текущей оболочке, вы даже можете удалить файл, и пока эта оболочка все еще будет открыта, функция все равно будет определена.
Редактировать: Как я вижу из вашего отредактированного вопроса, как только вы отключите функцию, вы получите сообщение об ошибке. Это указывает на то, что моя гипотеза правильная, и что вы уже использовали файл перед изменением разрешений. Как я объяснил, поиск и выполнение файла - это совершенно разные операции, и как только вы отправляете файл, его разрешения (или существование) вообще не имеют значения; функция уже загружена в текущую рабочую оболочку. Вы можете сказать, выполнив свой оригинальный эксперимент после выполнения unset hello
; если у вас есть chmod 000
, у вас не должно быть прав на чтение, а затем функция не будет определена.
Первой строкой должно быть «#!/Bin/bash». –
@Andrew Спасибо. –
Большое спасибо Эндрю Медико, который критически интерпретировал мое письмо. Следовательно, я нашел некоторые неприятные ошибки в моем письме, из которых, казалось, были небольшие дебаты.Надеюсь, теперь все правильно. –