Чи може хтось пояснити, якими є використання команди exec в сценарії оболонок простими прикладами?
Чи може хтось пояснити, якими є використання команди exec в сценарії оболонок простими прикладами?
Відповіді:
На exec
вбудованої командних дзеркалах функції в ядрі, є сім'я з них на основі execve
, яка зазвичай викликається з C.
exec
замінює поточну програму в поточному процесі, не fork
застосовуючи новий процес. Це не те, що ви використовували б у кожному написаному вами сценарії, але це корисно при нагоді. Ось кілька сценаріїв, якими я користувався;
Ми хочемо, щоб користувач запускав конкретну прикладну програму без доступу до оболонки. Ми могли б змінити програму входу в / etc / passwd, але, можливо, ми хочемо, щоб налаштування середовища використовувались із запуску файлів. Отже, в (скажімо) .profile
, останньому твердженні сказано щось на зразок:
exec appln-program
тому зараз немає оболонки, до якої можна було б повернутися. Навіть якщо відбувається appln-program
збій, кінцевий користувач не може потрапити до оболонки, оскільки його там немає - exec
замінив його.
Ми хочемо використовувати іншу оболонку до тієї в / etc / passwd. Як не здається, деякі сайти не дозволяють користувачам змінювати оболонку входу. Один сайт, який я знаю, мав почати з усіх csh
, і кожен просто вніс у свій .login
(csh файл запуску) дзвінок на ksh
. Поки це працювало, він покинув блукаючий csh
процес, і вихід був два етапи, які могли заплутатися. Тож ми змінили його на те, exec ksh
що просто замінили програму c-shell на оболонку korn, і зробили все простішим (з цим є інші проблеми, наприклад, те, що ksh
це не оболонка входу).
Просто для збереження процесів. Якщо ми дзвонимо prog1 -> prog2 -> prog3 -> prog4
і т. Д. І ніколи не повертаємось назад, то зробіть кожен виклик виконавцем. Це економить ресурси (не багато, правда, якщо не повториться) і робить зупинку спрощенням.
Ви, очевидно, бачили, що exec
десь використовувались, можливо, якщо ви показали код, який вас помиляє, ми могли б виправдати його використання.
Редагувати : Я зрозумів, що моя відповідь вище неповна. Існує два варіанти використання exec
в оболонках, як ksh
і bash
- використовується для відкриття дескрипторів файлів. Ось кілька прикладів:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
Зауважте, що інтервал тут дуже важливий. Якщо ви розмістите пробіл між номером fd та символом перенаправлення, тоді exec
повертається до початкового значення:
exec 3 < thisfile # oops, overwrite the current program with command "3"
Існує кілька способів їх використання, наприклад, за допомогою ksh read -u
або print -u
, bash
наприклад:
read <&3
echo stuff >&4
exec gunicorn
повертає правильний pid назад до супервізора.
exec
їх можна використовувати для перенаправлення:> Якщо команда не вказана, будь-які перенаправлення набувають чинності в поточній оболонці, а статус повернення - 0. Якщо є помилка перенаправлення, стан повернення дорівнює 1. Але як це exec
насправді працює над зміною дескриптора файлу? Чому саме для цього завдання обрана така команда? (Маркдаун зараз не вдається?)
exec >.\logfilename.log 2>&1
&>
це bash
розширення (див. man bash
), І ваш приклад еквівалентний exec >/var/log/userdata.log 2>&1
. Іншими словами, він перенаправляє stdout та stderr до цього файлу. Команди, які слідують, успадкують ці перенаправлення, якщо вони не будуть скинуті, але вони будуть виконані.
Просто, щоб доповнити прийняту відповідь короткою короткою відповіддю для новачків, вам, мабуть, не потрібно exec
.
Якщо ви все ще знаходитесь тут, з наступною дискусією слід сподіватися розкрити, чому. Коли ти біжиш, скажи:
sh -c 'command'
ви запускаєте sh
екземпляр, а потім починаєте command
як дитина цього sh
примірника. Після command
завершення sh
екземпляр також закінчується.
sh -c 'exec command'
запускає sh
екземпляр, а потім замінює цей sh
примірник наcommand
двійковим і запускає його замість цього.
Звичайно, обидва в даному обмеженому контексті є марними; ви просто хочете
command
Існують деякі ситуації з бахромою, коли ви хочете, щоб оболонка читала файл конфігурації або якось іншим чином встановлювала середовище як підготовку до запуску command
. Це майже єдина ситуація, коли exec command
це корисно.
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
Це робить деякі речі, щоб підготувати навколишнє середовище, щоб воно містило те, що потрібно. Як тільки це буде зроблено, sh
екземпляр більше не потрібен, і тому (незначна) оптимізація просто замінить sh
екземпляр command
процесом, а не матиsh
запустити його як дочірній процес і чекати його, а потім вийти, як тільки він закінчиться.
Аналогічно, якщо ви хочете звільнити якомога більше ресурсів для важкої команди в кінці сценарію оболонки, ви можете exec
цією командою як оптимізацією.
Якщо щось змушує вас запустити, sh
але ви дійсно хотіли запустити щось інше, exec something else
звичайно, це рішення для заміни небажаного sh
екземпляра (наприклад, якщо ви дійсно хотіли запустити власний спіфій gosh
замість, sh
але ваш не вказаний у/etc/shells
щоб ви могли не вказати його як свою оболонку для входу).
Друге використання для управління exec
дескрипторами файлів - окрема тема. Прийнята відповідь це гарно висвітлює; щоб зберегти це самостійно, я просто відкладу керівництво для будь-якого місця exec
, за яким слід переспрямування замість імені команди.