Ожидание завершения процесса ИЛИ пользовательский ввод для продолжения - PullRequest
3 голосов
/ 12 июля 2019

У меня есть скрипт bash, который запускает команду в фоновом режиме. После того, как это выполнит это, это покажет пользователю: Press any key to continue (питание от read -n1 -r -p 'Press any key to continue' value)

Мне бы хотелось, чтобы кто-то наблюдал за командой в фоновом режиме, чтобы видеть, когда она закончится, и если это так, я хочу, чтобы скрипт все равно продолжался. С другой стороны, процесс все еще может продолжаться, и я хотел бы позволить пользователю нажать клавишу для kill этого процесса, а не ждать его завершения.


Я думаю, что самый простой способ визуализировать это было бы так:

mac shut down

Пользователь может либо подождать, пока таймер перейдет в 0, и он автоматически отключится, либо, если они нажмут кнопку выключения, он немедленно выключится.

Ответы [ 3 ]

3 голосов
/ 12 июля 2019

Если вы хотите подождать, пока пользователь нажмет клавишу, вы можете сделать это следующим образом:

./long_command.sh &
waitpid=$!
echo "Hit any key to continue or wait until the command finishes"
while kill -0 ${waitpid} > /dev/null ; do
    #if [[ ${#KEY} -gt 0 ]] ; then
    if read -n 1 -t 1 KEY ; then
        kill ${waitpid}
        break
    fi
done

Просто замените long_command.sh вашей командой. Здесь $! возвращает pid последнего запущенного подпроцесса и kill -0 ${waitpid} проверяет, существует ли процесс еще (он не убивает процесс). ps -q ${waitpid} работает и в Linux, но не в Mac - спасибо @leetbacoon за упоминание этого. read -n 1 -t 1 означает «читать один символ, но ждать только до 1 секунды» (здесь вы также можете использовать дроби, например, 0,5). Статус возврата этой команды зависит от того, может ли она прочитать символ в указанное время или нет.

2 голосов
/ 12 июля 2019

Нечто подобное может работать для вас

#!/bin/bash

doStuff() {
    local pidOfParent="$1"

    for i in $(seq 10); do
        echo "stuff ${i}" > /dev/null
        sleep 1
    done

    kill $pidOfParent
}

doStuff $$ &

doStuffPid="$!"

read -n1 -rp 'Press any key to continue' && kill $doStuffPid

Разбивка

doStuff - это наша функция, которая содержит то, что вы хотите запустить в фоновом режиме, то есть музыку.

$$ - это PID запущенного скрипта, который мы передаем в нашу функцию, чтобы он стал более информативным pidOfParent, в котором мы kill после того, как закончим что-то делать.

& после вызова функции переводит ее в фоновый режим.

$! получает PID последней выполненной команды, поэтому теперь у нас есть PID фонового процесса, который мы только что начали.

Вы указали read -n1 -rp 'Press any key to continue', поэтому я могу предположить, что вы уже знаете, что он делает, && kill $doStuffPid будет kill фоновым процессом после выхода read (это также работает, если вы завершаете сценарий с помощью ^C).

1 голос
/ 12 июля 2019

Если вы хотите использовать встроенное ожидание, вы можете написать:

expect <(cat <<'EOD'
spawn sleep 10
send_user "Press any key to continue\n"
stty raw -echo
expect {
  -i $user_spawn_id -re ".+" {}
  -i $spawn_id eof {}
}
EOD
)

, где вы бы заменили sleep 10 своим процессом.

...