Асинхронні команди оболонки


100

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


2
Пов’язано, див. Різниця між nohup, disown та & на Unix та Linux Stack Exchange.
jww

1
Для тих , хто шукає більш відповідь поглиблені , що говорить про відмінності між nohup, &іdisown , натисніть тут , щоб перейти до четвертого відповіді .
noɥʇʎԀʎzɐɹƆ

Відповіді:


116

Ви можете просто запустити сценарій у фоновому режимі:

$ myscript &

Зауважте, що це відрізняється від розміщення &всередині вашого сценарію, що, ймовірно, не буде робити те, що ви хочете.


1
Я знав, що це буде щось легке, дякую тоні ... Linux просто не моя річ, але я намагаюся досягти швидкості ... До речі, це буде працювати в поєднанні з nohup?
LorenVS

2
Яка різниця між тим, як поставити & в командний рядок і помістити його в сценарій? Я не усвідомлював, що вони різні.
Якоб Шарф

8
@JacobSharf, спробуйте, і ви побачите. Якщо &всередині скрипту є і у вас немає а wait, фонова команда буде знищена, коли сценарій завершиться.
Карл Норум

ой. Це багато що пояснює. Нещодавно я помітив якийсь ефект, який би викликаний цим. Погугливши це насправді привело мене до цієї сторінки. Спасибі
Якоб Шарф

Якщо myscriptзмінюється середовище терміналу, напр. це команда ініціалізації терміналу, яка не потрібна негайно і може бути відкладена, чи все-таки змінить середовище терміналу?
noɥʇʎԀʎzɐɹƆ

58

Усі просто забули disown. Отже, ось короткий виклад:

  • & ставить роботу на другий план.

    • Блокує його при спробі зчитування вводу та
    • Змушує оболонку не чекати її завершення.
  • disown видаляє процес з управління роботою оболонки, але він все ще залишає його підключеним до терміналу.

    • Одним із результатів є те, що оболонка не надсилатиме її SIGHUP(Якщо оболонка отримує а SIGHUP, вона також надсилає a SIGHUPв процес, що зазвичай призводить до припинення процесу).
    • І очевидно, що його можна застосувати лише до фонових завдань (тому що ви не можете ввести його під час виконання переднього плану).
  • nohupвідключає процес від терміналу, перенаправляє його вихід nohup.outі захищає його SIGHUP.

    • Процес не отримає жодного надісланого SIGHUP.
    • Він повністю незалежний від контролю за роботою, і в принципі може використовуватися і для переднього плану (хоча це не дуже корисно).
    • Зазвичай використовується з &(як фонове завдання).

Я не можу знайти disownна Debian чи OS X. Я думав, що це програма, але я, здається, помиляюся. Що це?
jww


6
Це найкраща відповідь. Найбільш вичерпний.
noɥʇʎԀʎzɐɹƆ

3
Однозначно найкраща відповідь, не знаю, чому так мало підйомів
HeberLZ

1
@VladGanshin No.
Ані Менон

39
nohup cmd

не зависає, коли ви закриваєте термінал. вихід за замовчуванням переходить до nohup.out

Ви можете комбінувати це з фоном,

nohup cmd &

і позбутися результату,

nohup cmd > /dev/null 2>&1 &

Ви також disownможете командувати. типу cmd, Ctrl-Z, bg,disown


2
Круто, божевільно, як все поєднується, я думаю, що спочатку замовлення дісталося б мені, але, мабуть, ти можеш просто запам'ятати його (те, що ти написав, або "nohup cmd &> / dev / null 2> & 1" :))
LorenVS

Я натрапив на це сьогодні ввечері. Я боровся зі сценарієм оболонки 2 дні, і ця пропозиція спрацювала. Дякую мухо!
JD Довгий

Дивовижно, це дуже корисно. Під час запуску у фоновому режимі ви можете перевіряти вихід команди раз у раз, використовуючи tail nohup.out, це відображатиме останні 10 рядків команди. Я використовую це для завдань резервного копіювання rsync, щоб побачити, у якому файлі він знаходиться.
Мартін Хансен

Що робити, якщо я це роблю, але хочу зупинити фоновий процес?
Стефан Біцзіттер

Оболонка друкує ідентифікатор завдання, коли ви починаєте завдання саме для цієї мети. Ви можете бачити свої запущені завдання в будь-який час із jobs.
трійчатка

26

Крім того, після запуску програми ви можете натиснути Ctrl-Z, який зупинить програму, а потім набрати

bg

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


2
Дякую, це крутий маленький трюк ... Починаючи по-справжньому цінувати частину
користі

3

screen -m -d $command$запускає команду в окремому сеансі. Ви можете використовувати screen -rдля приєднання до розпочатого сеансу. Це прекрасний інструмент, надзвичайно корисний і для віддалених сеансів. Детальніше читайте на man screen.


@LadenkovVladislav Я на 95% впевнений, що ти можеш встановити екран на RedHat. У мене на CentOS.
BuvinJ

У Ubuntu я хотів наслідувати команду Windows / batch "start". Тобто асинхронно запускайте програму переднього плану (gui) та продовжуйте роботу через сценарій оболонки. Це робить саме це.
BuvinJ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.