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


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.