Как запустить несколько фоновых команд в bash в одной строке?

169

Я обычно запускаю несколько команд с чем-то вроде этого:

sleep 2 && sleep 3

или

sleep 2 ; sleep 3

но что, если я хочу запустить их обоих в фоновом режиме из одной команды командной строки?

sleep 2 & && sleep 3 &

не работает И ни один не делает замену &&с;

Есть ли способ сделать это?

Дворец Чан
источник
8
Используйте, ()чтобы окружить команду.
nhahtdh
1
unix.stackexchange.com/questions/67006/…
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Ответы:

319

Как именно вы хотите, чтобы они запускались? Если вы хотите, чтобы они запускались в фоновом режиме и запускались последовательно , вы должны сделать что-то вроде этого:

(sleep 2; sleep 3) &

Если, с другой стороны, вы хотите, чтобы они работали параллельно в фоновом режиме, вы можете вместо этого сделать это:

sleep 2 & sleep 3 &

И эти два метода могут быть объединены, такие как:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Bash, будучи bash, часто для решения одной и той же задачи часто используют множество различных методов, хотя иногда с небольшими различиями между ними.

Kitsune
источник
20
Это краткий, хорошо продуманный ответ, который «учит человека ловить рыбу» на всю жизнь. Спасибо.
Ambrus
2
Что будет, если мы это сделаем sleep 2 && sleep 3 &? Я попробовал это в Bash, и, кажется, работает так же (пробовал с эхо).
Ваджахат
@HakanBaba, да, это действительно создает подоболочку в фоновом режиме.
Доу ван дер Лист
3
@ Wajahat, ты пробовал sleep 2 && echo "foo" && sleep 3 & echo "bar""? &&Оператор говорит оболочке , чтобы выполнить команду перед ним, и только тогда , когда эта команда выполняется без каких - либо ошибок оболочка выполняет последующую команду. Это существенно отличается от того ;, что ;позволяет последующей команде выполняться независимо от состояния выхода предыдущей команды, если только это не было фатальной ошибкой. &Говорит оболочке , чтобы выполнить все «Connected» команд , предшествующих его, в фоновом режиме. «подключен» здесь означает, что команда является частью pipe ( |) или логического оператора.
Доу ван дер Лист
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.в руководстве по bash.
Jinbeom Hong
49

Вам нужно добавить несколько паренов в вашей последней версии -

(sleep 2 &) && (sleep 3 &)

или это тоже работает -

(sleep 2 &) ; (sleep 3 &)
iagreen
источник
Примечание. Когда используется список &, статус выхода всегда равен нулю. Итак, два приведенных выше случая делают одно и то же (оболочка выполняет обе стороны по очереди асинхронно ).
Jinbeom Hong
9

для запуска нескольких фоновых команд необходимо добавить &конец каждой команды. например: (command1 &) && (command2 &) && (command3 &)

Saeed
источник
5

Ответы выше используют круглые скобки. Bash также может использовать фигурные скобки для аналогичной цели:

{ sleep 2 && sleep 3; } &

Обратите внимание, что скобки более требовательны к синтаксису - требуется пробел после {, пробел до }и последняя точка с запятой. В некоторых ситуациях брекеты более эффективны, потому что они не разворачивают новую подоболочку. В этом случае я не знаю, если это имеет значение.

Грег Рейгл
источник
1
Как насчет { sleep 2; sleep 3; } &?
Кенни Эвитт
4

Это работает:

$(sleep 2 &) && sleep 3 &

Также вы можете сделать:

$(sleep 2 && sleep 3) &
higuaro
источник
0

У меня тоже такая же миссия. Я пытался (sleep2 ; fg )& sleep3 ; fg, это работает. И когда вы преуспеете, Ctrl + C удвоится, два процесса могут быть остановлены.

Диньянг Ван
источник
0

Вы можете использовать подстановку команд bash $(command)следующим образом:

$(command1 ; command2) &

Обратите внимание, что stdin и stdout по-прежнему связаны с родительским процессом, и перенаправление, по крайней мере, stdout может быть сложным. Таким образом, в качестве альтернативы вы можете объединить команды в одну строку, а затем передать строку bashкоманде, чтобы породить новый процесс, который будет обрабатывать выполнение.

bash -c "command1 ; command2" & 

Это особенно полезно в скрипте bash, когда вам нужно запустить несколько команд в фоновом режиме.

Эти два утверждения должны быть эквивалентны. Баш процесс икру в обоих случаях для обработки команды (цепь команд) и& в конце отсоединяет исполнения.

На этот раз вы можете добавить &>/dev/nullперед &в конце команды, чтобы перенаправить как минимум стандартный вывод и избежать вывода на стандартный вывод родительского процесса. Что-то вроде:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
источник
-1

Если вы хотите выполнить несколько команд последовательно , есть действительно простой метод, который работает везде: создание файла! Преимущество этого метода в том, что он чистый и простой.

Сначала создайте файл с именем, например commands.sh. Затем поместите свои команды там. Вот пример:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

Хорошо, теперь мы на последнем этапе. Чтобы запустить команды в фоновом режиме (последовательно), просто запустите:

$ sh commands.sh &
MAChitgarha
источник