Використовуйте випадок / практичний приклад для вбудованого файлу Bash '


12

Розглянемо це з документації Bash 'buildin exec:

exec замінює оболонку без створення нового процесу

Наведіть, будь ласка, приклад використання / практичний приклад. Я не розумію, як це має сенс.

Я гуглив і дізнався про переадресацію вводу / виводу . Ви можете пояснити це краще?


Відповіді:


18

execчасто використовується в скриптах оболонки, які в основному виконують функції обгортки для запуску інших двійкових файлів. Наприклад:

#!/bin/sh

if stuff;
    EXTRA_OPTIONS="-x -y -z"
else
    EXTRA_OPTIONS="-a foo"
fi

exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"

так що після завершення роботи обгортки "справжній" двійковий файл переймається, і більше немає жодного сліду сценарію обгортки, який тимчасово займав той самий слот в таблиці процесів. "Справжній" двійковий файл - це пряма дитина того, що запустив його замість онука.

Ви також згадуєте перенаправлення вводу-виводу у своєму запитанні. Це зовсім інший випадок використання execі не має нічого спільного із заміною оболонки іншим процесом. Коли execнемає аргументів, так:

exec 3>>/tmp/logfile

то переадресація вводу / виводу в командному рядку набуває чинності в поточному процесі оболонки, але поточний процес оболонки продовжує працювати і переходить до наступної команди в сценарії.


1
Ви можете сказати, що два випадки пов'язані між собою тим, що для обох, execговорить оболонці не робити дії (виконувати команду або виконувати перенаправлення) у дочірньому процесі, а в тому самому процесі.
Стефан Шазелас

5

Я використовував execвбудовану оболонку для отримання ідентифікатора процесу (PID) для програми Java. Можливо, є спосіб отримати PID зсередини Java, але кілька років тому цього не було. Після того, як у процесу є власний PID, він може записати його у файл PID (шукайте /var/run/назви файлів із суфіксом '.pid'), щоб програма управління могла знати PID запущеного процесу та запобігти появі другої інстанції того ж сервера від запуску. Це працює приблизно так:

exec java -cp=YourServer.jar StartClass -p $$

Код у main()методі класу StartClassобробляє розбір аргументів і може знайти власний ідентифікатор процесу.


2

Для розваги запустіть наступну програму (перекладену на обрану мову вашої реалізації) у фоновому режимі в системі з обліковим записом користувача та обмеженнями.

while(true) fork();

Тепер, коли кожен слот у таблиці процесів, яким ви можете дозволити користуватися, заповнений копіями цієї запущеної програми, як ви збираєтесь її вбити? Запуск вбивства (1) вимагає іншого слота процесу, якого ви не можете мати. Звичайно, було б зручно, щоб оболонка замінила себе командою kill ...

exec /bin/kill -9 -1

(Припустимо, що у вашій системі є kill (1) at / bin / kill. "Exec` which kill` -9 -1 "потенційно безпечніший.) Це надсилає SIGKILL до кожного процесу, який ви можете.

(Примітка. Не виходите зі своєї запускової оболонки, якщо обмеження процесу завжди не дозволяють новому входу в слот процесу для своєї оболонки. Це може бути дещо складніше очистити, якщо це зробити. Я, звичайно, цього не робив у початку 90-х. Ні.)


3
(1) Ця відповідь була б трохи кращою, якби ви насправді показали execкоманду, яка була б корисною в цій ситуації. (2) Ця відповідь дещо архаїчна; killкоманда була команда в Баш вбудована команда на протязі багатьох років, в основному з -за цієї проблеми.
G-Man каже: "Відновіть Моніку"

@ G-Man: Ви розумієте, що ваш пункт (2) робить цю відповідь точною відповіддю на ОП?
Ерік Тауерс

Ні, я цього не розумію. Будь ласка, поясніть мені це.
G-Man каже: "Відновіть Моніку"

4
Я не стежу за тобою. Питання не вимагає практичних прикладів всіх bash вбудованих команд; він запитує приклади exec- і те, що killє вбудованим, насправді не має нічого спільного з execвбудованим.
G-Man каже «Відновити Моніку»

1
Я просто прочитав ваше оновлення до вашої відповіді. (1) Відгадай, що? Якщо таблиця процесів повна, підміна команд (наприклад, `which kill`) також не працює. (2) До речі, $(…)форма рекомендується над `…`формою. (3) Але в здогадуванні в каталозі немає нічого небезпечного. Якщо ви випадково наберете exec /binn/kill, ви просто отримаєте повідомлення про помилку, і ваша оболонка не піде. (4) Але вам навіть не потрібно турбуватися про те kill, в якому каталозі знаходиться.  execВикористовується $PATH, як і звичайні команди, так exec kill …працює (якщо вважати, що у вас є /binшлях пошуку).
G-Man каже: "Відновіть Моніку"

1
  • Це схоже на приклад Брюса про необхідність знати PID процесу:

    (cmdpid = $ BASHPID; (сон 300; вбити "$ cmdpid") & виконувати команду з довгого запуску )

    в якому ти

    1. Запустіть нижню частину корпусу (зовнішню (та )),
    2. Дізнайтеся PID підзаголовка. ( $$дасть вам PID основної оболонки.)
    3. Від'єднайте підзаділ, який вбиває ваш процес після таймауту, і
    4. Виконайте команду в процесі підскладу, який ви створили на кроці 1.

    Це буде працювати long-running-command, але лише протягом заздалегідь визначеного обмеженого часу. 

  • Це трохи легковажно, але, якщо ви вирішите, що ви хочете мати root (або якийсь інший користувач) до кінця вашого сеансу входу, ви могли б exec su.

    Власне, я можу уявити сценарій, коли це дійсно було б корисно. Припустимо, ви увійшли у віддалену систему, і чомусь виникла проблема з розривом з'єднання та запуском нового з'єднання. Наприклад, припустімо, що у віддаленій системі є брандмауер, який відповідає графіку. Вам дозволили підключитися, коли ви зробили це, і встановлені з'єднання не закриваються, але наразі нові з’єднання не приймаються.

    Ви зробили те, що хотіли зробити, і ви готові вийти з системи. Ваш друг Боб знаходиться в кімнаті з вами, і він хоче виконати деяку роботу над віддаленою системою - але він не зможе підключитися. Отже, ви набираєте текст exec su - bobі, коли з’являється запит про введення пароля, перетворіть робочу станцію на нього. Зараз з вашим UID не існує жодного процесу (якщо ви не запустили щось у фоновому режимі), тому Боб не зможе возитися з вашими файлами. Він фактично перейняв ваш зв’язок (за вашою згодою та співпрацею).

    Примітки:

    • Звичайно, це не спрацює, якщо вам не дозволяють бігати su.
    • Він буде зареєстрований, тому вам може знадобитися комусь пояснити свої мотиви. Оскільки ви обходите політику (графік брандмауера), ви можете потрапити в проблеми.
    • Я не гарантую, що це 100% безпека. Наприклад, whoнапевно, все одно буде показано ваше ім’я. Можливо, що якась (погано написана) програма використає це, щоб думати, що Боб - це ти, і надати йому доступ до ваших ресурсів.
    • Якщо система проводить аудит, дії Боба можуть бути перевірені під вашим іменем.

Зауважте, що на практиці в більшості оболонок (a;b)вже те саме, що (a;exec b)і оболонки оптимізують вилку для останньої команди в підпакеті. Єдиними винятками, здається, є bashі mksh. Використання execдопомагає гарантувати це.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.