Отслеживание прогресса из фонового процесса без угона подсказки

10

Рассмотрим простой скрипт hello:

#!/bin/bash

echo 'hello world!'

Теперь из bash, если я попытаюсь запустить это в фоновом режиме:

$ hello &
[1] 12345
$ hello world!
 <--- prompt is stuck here until I hit enter!
[1]+ Done
$  <--- prompt back to normal

Что я бы предпочел увидеть:

$ hello &
[1] 12345
[1]+ hello world!
[1]+ Done
$  <--- prompt normal the whole time

Как я могу изменить поведение?

Дейв Джонсон
источник

Ответы:

13

Это вопрос времени: bash запускает helloкоманду в фоновом режиме, затем отображает приглашение, позволяющее ввести новую команду, а затем фоновая команда выводит некоторые выходные данные. Когда вы вводите следующую командную строку (пустую командную строку, если вы просто нажимаете Enter), bash отображает уведомление о том, что фоновое задание завершено, а затем следующее приглашение.

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

Вы можете сделать так, чтобы bash немедленно уведомлял вас о завершении фонового задания, установив notifyпараметр с помощью set -b. Тогда вы увидите:

$ set -b
$ hello &
[1] 12345
$ hello world!
[1]+ Done

Bash в этом случае не перерисовывает подсказку. Вы по-прежнему редактируете командную строку в строке приглашения, которая появилась до печати фонового задания hello world!. Вы можете перерисовать текущую строку, нажав Esc 1 Ctrl+ L. Вы можете привязать команду redraw-current-lineк более удобной клавише; например, чтобы Ctrl+ Lперерисовать текущую строку и Ctrl+ Alt+ Lочистить экран, добавьте следующие строки в ваш ~/.inputrc:

"\C-l": redraw-current-line
"\e\C-l": clear-screen

Я не знаю, как заставить bash перерисовать строку подсказки автоматически. Zsh делает это по умолчанию.

Жиль "ТАК - перестань быть злым"
источник