Для достижения сначала 2 точек, необходимо заключить в тюрьму пользователя к желаемому каталогу, это иногда - названная игра в песочнице термина, и это связано с chroot
в Linux.
Хорошая статья Хов к chroot (тюрьма) пользователь SSH может быть найдена здесь.
О третьей точке я не уверен, но можно посмотреть на то, Как Ограничить доступ к сети пользователем / группа, использующая iptables - Соответствие Владельца.
Но я не уверен, необходимо ли дать ему такие ограничения/полномочия.
Итак, когда команда уволена из оболочки, вилка () наследует ребенка Процесс этого и EXEC () загружает дочерний процесс в память и выполняет.
не совсем. Вилка ()
клоны текущего процесса, создавая идентичный ребенок. Exec ()
нагружает новую программу в текущий процесс, заменяя существующий.
Мой QS:
Если дочерний процесс содержит все атрибуты родительского процесса (который является исходным процессом), то какова необходимость этого Детский процесс? Оригинальный процесс также мог быть загружен в объем памяти.
Необходимость заключается в том, что родительский процесс еще не хочет расторгнуть; Он хочет, чтобы новый процесс выйти и сделать что-то одновременно, что он также продолжает выполнять.
Эта концепция Fork и Exec применяется ко всей исполняемой программе в Unix? Как для Shell Script также или только для команд? Делает это также Подайте заявку на Shell встроенные команды?
для внешних команд, оболочка выполняет вилку ()
, чтобы команда проводится в новом процессе. Встроенные просто бегите оболочкой напрямую. Другая заметная команда
, что говорит оболочку EXEC ()
внешней программы без снаружи Fork ()
. Это означает, что сама раковина заменяется новой программой, поэтому она больше не должна для этой программы вернуться к тому, когда она выходит. Если вы говорите, exect true
, то / bin / true
заменит вашу оболочку и немедленно выйдите, оставляя ничего не находящегося в вашем терминале, поэтому он будет закрыт.
Когда копия в концепции записи используется, если я выполняю команду / скрипт?
Назад в каменном веке, Fork ()
Фактически пришлось скопировать всю память в процессе вызова к новому процессу. Копирование на запись - это оптимизация, в которой настраиваются таблицы страниц, чтобы два процесса начнулись разделяться всеми той же памятью, и только страницы, которые записываются для любого процесса, копируются при необходимости.
Чтобы сделать это как можно проще, я использую аналогию. Давайте испечем пирог!
Берем книгу рецептов, начинаем читать и садимся на клубничный пирог с ревенем (мой любимый), с корочкой ручной работы. Почти все, что нам нужно, находится на кухне, за исключением яиц и фруктов, но так как мы живем на ферме и фрукты в сезон, это не проблема. проблема в том, что печь сломалась и не хватает времени, чтобы сделать каждую вещь. Разве не здорово было бы иметь больше одного из меня?
вилка() для спасения. Теперь меня двое. и мы оба идем на кухню, чтобы начать готовить корочку для пирога. Упс. Итак, мы смотрим на возвращение из вилки. У меня большая цифра, у него ноль, так что я иду на кухню, пока он идет в курятник и сад. Проходя мимо духовки, я снова вилкой смотрю на возвратное значение: облом я получил ноль. Он продолжает муку, когда я смотрю на сломанную печь. Я открываю дверь, нет света, я закрываю дверь. Кто-нибудь знает, как починить печь?
exec() на помощь. Я тянусь к вольтметру на моем ремне, лампа может быть диагностической, так что я проверяю власть, Действительно споткнулся выключатель, легко исправить. как я иду к панели выключателя, я вижу парень собирая ревень. Фу! Я предпочитаю шоколадный шелковый пирог.
execve()
, чтобы наложить на себя другой код. fork()
и exec()
действительно применяются ко всем исполняемым файлам - на самом деле, наряду с argc и argv, и трубы, вилка и exec являются тем, что отличает Unix от других операционных систем. Существует несколько специализаций или обобщений fork()
, таких как BSD vfork()
, Plan 9 rfork()
и Linux' clone()
, но основной принцип остается тем же самым. malloc()
, или даже статические переменные или переменные глобальной области видимости) могут быть "копией при записи". Когда дочерний процесс создаётся вызовом fork()
, кернел устанавливает, что дочерний процесс будет иметь те же самые страницы памяти, что и куча и стек, что и родительский процесс. Если аппаратное обеспечение (устройство управления памятью) обнаружит запись кучи или стека, ядро получит новую физическую страницу памяти, скопирует родительскую страницу в новую страницу и отобразит эту новую страницу в стеке или куче дочернего процесса. Это является оптимизацией, так как ядро тратит меньше времени на настройку отображения страниц, чем оно потратило бы на полное копирование стека и кучи для дочернего процесса. Если дочерний процесс содержит все атрибуты родительского процесса (который является исходным процессом), то зачем ему нужен этот дочерний процесс? Исходный процесс также мог быть загружен в память.
На этот вопрос очень наглядно ответить, если взглянуть на самые ранние реализации Unix, которые должны были работать в условиях жестких ограничений памяти и имели только один выполняющийся процесс в памяти / адресном пространстве за раз.
Многозадачность была достигнута путем замены процесса на диск и замены другого процесса на.
Теперь системный вызов fork
был почти таким же: он выгружал процесс на диск, но вместо заменяя другой процесс, он дал копии в памяти другой идентификатор процесса и вернулся к нему. И это был подходящий момент для этого процесса, чтобы в конце концов решить просто exec
в другой исполняемый файл.
fork
+ exec
, таким образом, фактически не повлекло за собой заметных накладных расходов из-за создания: вам все равно приходилось выгружать процесс на диск, и у вас все равно был старый образ процесса в рабочих местах памяти.
С ростом количества доступной памяти и модулей управления памятью и множеством процессов в памяти, изначально незначительная стоимость вилки стала несколько неприятнее для некоторых архитектур: так родился vfork
.