Вот несколько вещей, которые вы можете улучшить (не претендуя на полноту):
Никогда не анализируйте вывод ls
.
Ваш скрипт сломается, как только любое имя файла или каталога будет содержать пробелы (что вполне допустимо для большинства современных файловых систем).
Вместо этого используйте функцию подстановки в вашей оболочке:
shopt -s dotglob #, чтобы * glob соответствовал скрытым файлам (например, ls -a)
для i в "$ 1" / *
Всегда заключайте переменные в кавычки.
Ваша оболочка просматривает символы пробела (пробел, новая строка,…), чтобы определить, где заканчивается один аргумент команды и начинается другой. Рассмотрим следующий пример:
filename = "foo bar"
touch $ filename
# расширяется до `touch foo bar`, поэтому создается два файла с именем" foo "and" bar "
touch" $ filename "
# расширяется до` touch "foo bar`" ", поэтому создается один файл с именем" foo bar "{{ 1}}
A cd
too many
cd $ 1 / $ i
подсчитывает $ i
#, который, в свою очередь, вызывает ...
ls -a $ 1
ls
-parsing и переменные без кавычек, это попытается отобразить содержимое каталога ./ foo / bar / bar
, когда все, что у вас есть, это ./ foo / bar
.
Похоже, что значение "execute only" не имеет особого смысла для файла, но его можно использовать для предотвращения чтения содержимого каталога.
$ mkdir foo
$ touch foo/bar
$ ls foo/
bar
$ chmod 100 foo
$ ls foo/
ls: cannot open directory foo/: Permission denied
Для выполнения сценария необходимо иметь права на чтение и выполнение. Чтение содержимого сценария позволяет ему выполняться, поэтому вы должны иметь права read и execute
. В противном случае вы не сможете запустить сценарий без этого.
Каков пример использования разрешения только на выполнение?
Безопасность. Некоторые могут захотеть защитить свои файлы и не дать другим выполнить или использовать их.
Shell-скрипты требуют разрешения на чтение для выполнения, а бинарные файлы - нет:
$ cat hello.cpp
#include<iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
$ g++ -o hello hello.cpp
$ chmod 100 hello
$ ./hello
Hello, world!
$ file hello
hello: executable, regular file, no read permission
Отображение содержимого файла и его выполнение - это две разные вещи. В сценариях оболочки эти вещи связаны, потому что они "выполняются" путем "чтения" их в новую оболочку (или текущую), если вы простите за упрощение. Вот почему вам нужно уметь их читать. Бинарные файлы не используют этот механизм.
Для каталогов разрешение execute немного отличается; оно означает, что вы можете делать что-то с файлами внутри этого каталога (например, читать или исполнять их). Допустим, у вас есть набор инструментов в /tools
, которые вы хотите, чтобы люди могли использовать, но только если они знают о них. chmod 711 /tools
. Тогда исполняемые вещи в /tools
могут быть запущены явно (например, /tools/mytool
), но ls /tools/
будет запрещено. Аналогично, документы могут храниться в /private-docs
, которые могут быть прочитаны, если и только если известны имена файлов.
В Gentoo исполняемым программам с setuid (установленным для запуска с разрешениями их владельца, а не их инициатора) отказано в доступе для чтения (режим 4711). Это сделано для того, чтобы добавить уровень защиты от использования ошибок, чтобы помочь в повышении привилегий.
Если непривилегированный злоумышленник может прочитать файл setuid и знает об ошибке, которая допускает атаку в стиле возврата к libc , он может использовать содержимое файла, чтобы предсказать, где некоторые полезные функции или библиотеки могут быть помещены в память при вызове программы.
Современные системы часто включают более эффективные дополнительные средства защиты, такие как ASLR , но ограничения, существующие в 32-битных платформах, могут сделать их более уязвимыми.