Чому функція не повертається до закінчення фонового процесу?


21

Розглянемо цей сценарій:

#!/bin/bash
function start {
  leafpad &
  echo $!
}
PID=$(start)
echo "PID is $PID"

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

Чому це? Чи можливо запустити фоновий процес з функції?

Відповіді:


22

Функція повертається, але заміна блокує команду, оскільки ви створили фонове завдання, але у вас все-таки відкрито stdout fd. Просто закрийте його, додавши >/dev/nullперед &.

#!/bin/bash
function start {
  leafpad >/dev/null &
  echo $!
}
PID=$(start)
echo "PID is $PID"

Якщо ви хочете, щоб у вашому процесі було також закрито stdin, stdout, stderr, скористайтеся цим:

leafpad >/dev/null 0>&1 2>&1 &

Це закриє stdin (0), stdout (1) та stderr (2), а потім фон (&). Крім того, використовуючи ці перенаправлення потоку , не забувайте, що вони "дупіровані", це означає, що вони дублюються в порядку виконання.

1>/dev/null 2>&1

і

2>&1 1>/dev/null

не однакові! У першому ви дублюєте потік в / dev / null (що саме ви хочете), в другому ви дублюєте / dev / stdout в stderr, а потім, закриваючи stdout. Тож будь-яке повідомлення, надіслане на stderr, з’явиться у вашій консолі.


Підтверджено в моїй системі
user120161

10
Ви не закриваєте потоки, ви перенаправляєте їх.
dcat

4
закрити; n>&-де nдескриптор файлу.
dcat

1
@dcat: Так, але перенаправлення на / з /dev/nullне призведе до помилок вводу / виводу, коли процес намагається записати його stdout, але виявить, що 1це FD. Тож термінологія в пості неправильна, а не власне баш програмування. (Насправді, дублювання FD 1 на 0 означає, що stdin буде файловим дескриптором, відкритим за допомогою O_RDONLYякого, ймовірно, помилка (а не потрібна кількість байтів), коли процес намагається прочитати.) Наприклад wc >/dev/null 0>&1->wc: standard input: Bad file descriptor
Peter Корди

1
@PeterCordes - Закриття старого дескриптора та переадресація нового не повинні бути взаємовиключними. exec <&- >&- <>/dev/null >&0обробляє stdin / out досить вичерпно. Це має значення, zshщонайменше, яке сортування об'єднає всі відкриті в одному і тому ж дескрипторі автоматично, коли встановлено багаторіччя.
mikeserv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.