Захват ввода пользователем при выполнении других действий

Есть ли способ, чтобы выход подпроцесса (что-то вроде «сна») был согласован с выходом из командного цикла foreground? Например:

while true do echo "updating screen..." sleep 3 & # Replace with command which takes some time and updates the screen read -s -n 1 -p "Input: " input case "$input" in q) exit ;; f) echo 'foo' ;; esac done 

  • Является ли `ln` атомным и надежным на NFS? Может ли NFS заменить GFS в этом случае?
  • One Solution collect form web for “Захват ввода пользователем при выполнении других действий”

    Оболочка делает предположения о многопроцессорности; первая и самая важная: одна программа должна контролировать терминал за раз, иначе вход (и выход) будет запутан. Что делать, если программа, которую вы ставите вместо «сна», хочет получить вход от терминала? Где посылается ввод с клавиатуры? К подпроцессу («sleep») или к инструкции read ?

    Из этого вы должны предположить, что подпроцесс («sleep») не будет вводиться. Вам также нужно подождать, пока не закончатся оба командных цикла (обработка «q» или «f») и подпроцесс. Я бы посоветовал написать это нечто иное, чем скрипт оболочки, например, python, чтобы обойти предположения оболочки; но, как я покажу, это можно сделать в оболочке Bourne (или ksh или bash или zsh).

     #!/usr/bin/python import os, select, subprocess, sys devnull = open('/dev/null', 'a') # this is the same as "sleep 3 </dev/null > pipefile &" but will handle # processing output at the same time p = subprocess.Popen( ['/bin/sh', '-c', 'i=0; while [ $i -lt 30 ]; do echo $i; sleep 2; i=`expr $i + 1`; done' ], stdin=devnull, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) command_done = False try: # endless loop until both input and output are done while True: inputs = [] # only send input to our command loop if not command_done: sys.stdout.write('Input: ') sys.stdout.flush() inputs.append(sys.stdin) if p.returncode is None: # still not finished p.poll() inputs.append(p.stdout) outputs = [] if not inputs and not outputs: # both are done break # exit while loop #print inputs, outputs r, w, x = select.select(inputs, outputs, []) #print 'r=', r, 'w=', w, 'x=', x # input from the user is ready for file in r: if file is sys.stdin: input = file.read(1) if input == 'q': command_done = True if p.returncode is None: os.kill(p.pid, 15) elif input == 'f': sys.stdout.write('foo\n') # the subprocess wants to write to the terminal too else: input = file.readline() sys.stdout.write(input) finally: if p.poll(): try: print os.kill(p.pid, 15) except OSError: pass 

    Вы можете сделать это в сценарии оболочки, но вход / выход не будут столь же хорошо интегрированы.

     #!/bin/bash mkfifo /tmp/mergedout.p ( i=0; while [ $i -lt 30 ]; do echo $i; sleep `expr 30 - $i`; i=`expr $i + 1`; done ) </dev/null >/tmp/mergedout.p 2>&1 & pid=$! exec 3</tmp/mergedout.p done=false trap 'rm /tmp/mergedout.p' 0 while [ -n "$pid" -a $done = false ]; do if [ $done = false ]; then echo -n "Input: " read -t 0.1 -s -r -n 1 case $REPLY in q) done=true; if [ -n "$pid" ]; then kill $pid; fi;; f) echo foo;; esac fi if [ -n "$pid" ]; then kill -0 $pid 2>&- if [ $? -ne 0 ]; then echo "$pid terminated" wait $pid pid="" exec 3<&- else read -t 0.1 -u 3 -r echo "reading from fd3: X${REPLY}X $?" if [ -n "$REPLY" ]; then echo "$REPLY" fi fi fi sleep 0.5 done 

    Сам, питон немного более ясен и более «согласован», но по большей части это можно сделать в любом случае.

    Interesting Posts

    Исходные файлы с расширением `* .in`

    эхо-символы в терминале / bash

    Карта нестандартных скрытых отчетов для scancodes для игровой клавиатуры Logitech G105

    Не удается установить ПК BSD

    Слияние двух файлов: две строки, частичная линия, две строки, частичная линия и т. Д.

    Странная ошибка с ccsm (fedora 16) 32-битная

    Редактируйте несколько строк из определенного раздела INI-файла

    Отказ в доступе к нескольким каталогам в файле vsftpd.conf

    Ошибка при установке Fedora 19

    Взаимодействие команд initrd и системных служб, выполняющих то же самое

    Синхронизация каталогов через SSHFS с символическими ссылками

    Проверка Ghostscript + QPDF и PDF / A-1b: как добавить разделитель EOL до конца

    Бот, запрашивающий нечетный ресурс в журналах apache

    Почему соединение с использованием ключа ssh прерывается с одним именем хоста, но работает с другими?

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

    Linux и Unix - лучшая ОС в мире.