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

Есть ли способ, чтобы выход подпроцесса (что-то вроде «сна») был согласован с выходом из командного цикла 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

    Как удалить GNOME 3 и восстановить GNOME 2

    sar / sysstat выводит журналы во второй каталог

    Почему необходимо стереть первый MByte устройства OpenBSD CRYPTO?

    Последовательная связь не работает в обоих направлениях

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

    Как проверить, существует ли один или оба из двух файлов?

    почему nginx содержит описания файлов журналов?

    Как вставить первый столбец во многие файлы + как преобразовать время unix в обычное время

    Что такое смещение файла в lsof output?

    Как обновить календарь Google в Gnome?

    Как отображать только процесс и процессы его потомков на htop?

    Клавиша Gnome-Terminal застревает и повторяется навсегда

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

    Как я могу получить пакет recoll для индексирования файлов markdown (.md)?

    systemd-networkd по умолчанию, если dhcp не работает

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