2009-03-25 3 views
2

Не совсем то, что я могу запустить функцию Bash с 000 разрешений, но почти. Мой код:Почему я могу запустить функцию Bash с разрешением 000?

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

вводное-файл имеет разрешения:

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

Firtsly, я типа с текущими правами:

$ . ./hello_file;hello 

твик для изменения 400 разрешений 000 перед запуском сценария сценария bash:

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

Он дает одну ошибку, но не останавливает выполнение функции. Я не могу понять. Теперь я отключил приветственную функцию: «unset hello». Я получаю ошибки:

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

Почему я не получил их в первый раз? Это что-то связано с кешем, буфером или чем-то вроде этого? Почему я могу запустить скрипт Bash с 000 правами [1]?

+0

Первой строкой должно быть «#!/Bin/bash». –

+0

@Andrew Спасибо. –

+0

Большое спасибо Эндрю Медико, который критически интерпретировал мое письмо. Следовательно, я нашел некоторые неприятные ошибки в моем письме, из которых, казалось, были небольшие дебаты.Надеюсь, теперь все правильно. –

ответ

11

Вы не запуска скрипта, вы источников (в том числе) его. Чтобы загрузить сценарий, вам нужно только разрешение на чтение.

Кстати, функции просто существуют, у них нет разрешения. После того, как файл был найден и определенная функция, вы можете запустить его столько, сколько хотите.


Update:

Почему я не получил их в первый раз? Это что-то связано с кешем, буфером или чем-то вроде этого?

Да, как ответил Пакс, привет, вероятно, ранее был определен там из предыдущего источника файла. Вы можете быть смущены тем, что делает sourcing ("." Встроенная команда). Sourcing считывает файл и запускает все его команды в текущей оболочке, а затем возвращается к приглашению. Итак, если вы запускаете файл один раз, его функции определяются в текущем экземпляре оболочки, и они остаются там до тех пор, пока вы не закончите этот сеанс оболочки (или не отмените их).

Почему я могу запустить сценарий Bash с разрешением 000 [1]?

Вы не можете. Обратите внимание, что он представляет ошибку. Цитирование вашего вывода:

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

Вы выполнили две команды в одной командной строке. Не удалось найти источник с «Permission denied». «Привет!» вывод - из предыдущего источника файла. Вы просто доказали это сами, когда вы отменили его и снова попробовали ту же командную строку.

Вы не можете назвать это кеширование ... это то, как работает оболочка. Вы отправляете другой файл, все его определения включены в текущий сеанс оболочки и остаются там. Если вы на самом деле запустите сценарий (не источник), вы не должны получать никаких остатков в текущем сеансе.

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

Это не так. С perm = 100 он все равно не позволяет вам запускать сценарий, предоставляя «разрешение отклонено». Sourcing просто выполняется в контексте текущей оболочки, а не в подоболочке. Предложите вам попробовать сами. – paxdiablo

+0

Pax: Я не спорю о 100 или 000 разрешениях, я просто утверждаю, что разрешение exec не влияет на команду sourcing ("." Builtin), вот что он действительно делает. Почему нисходящий? – Juliano

+0

Недостаток в том, что вы ошибаетесь - попробуйте и посмотрите. Sourcing не работает, если perm = 000 или 100. – paxdiablo

5

Наиболее вероятным объяснением является то, что вы запустили hello_file до того, как он был защищен, и эта функция уже создана. Затем вы защитили свой скрипт (вы скажете 100 в команде, но упомяните 000 в своем тексте).

Итак, сценарий не будет работать. Но hello() по-прежнему определяется из предыдущего запуска.

Попробуйте открыть новую оболочку или просто выполнить unset hello.

+0

Ваш ответ звучит так, как будто вы догадываетесь. Я думаю, что первый ответ, данный правильно, - это просто поиск в читаемом файле. Функции оболочки не имеют и не имеют прав доступа. –

+0

Это не догадка, я протестировал его. И разрешения находятся в * файле *, который создает функцию, * не * сама функция. – paxdiablo

+0

Я стою исправлено. Извините, это так. –

2

Перед тем, как изменить режим на 100, вы отправили сценарий (то есть выполнили «./hello_file»)? Если это так, то функция «hello» просто загружается в bash. Впоследствии попытка получить нечитаемый файл не изменит этого. Чтобы правильно протестировать, убедитесь, что вы запустили свежую оболочку.

+0

Я внесла некоторые исправления и добавил более подробную информацию к вопросу. Ясно, что они необходимы для ответа на вопрос. –

2

Чтобы запустить программу (будь то скрипт 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, у вас не должно быть прав на чтение, а затем функция не будет определена.

+1

Эх, почему нисходящий? Есть ли в моем описании что-то неправильное или бесполезное? –

+0

Это, в основном, правда, но не имеет отношения к вопросу (почему можно - по-видимому, получить файл mode-100). В частности, файлы не должны быть исполняемыми, чтобы быть источником - только читаемым. –

+0

Я добавил абзац, разъясняющий разрешения; он явно получил ошибку разрешения, когда он получил файл, поэтому у него должно было быть определение из предыдущего вызова. Причина, по которой я описал разницу между поиском и запуском, - это то, что я думаю, что это путаница. –

 Смежные вопросы

  • Нет связанных вопросов^_^