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

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

    Как скопировать настройки с одной машины на другую?

    Кэширование записывает изменения на SSD, чтобы избежать разгона HDD? ZFS, но (возможно) не L2ARC

    Как запустить приложение в другом рабочем пространстве?

    Когда символическая ссылка рассматривается как вещь, на которую она ссылается, и как символическая ссылка?

    Уничтожать локальные файлы на удаленном сервере

    Как я рекурсивно применяю PKGREPOSITORY при вызове make-recursive во FreeBSD?

    Применение наложения дерева устройств

    Проблема аутентификации HTTPS: Polipo

    Вставьте новую строку перед каждой строкой, соответствующей шаблону, если предыдущая строка уже не указана

    Очередь – задача в рабочей оболочке

    Появится сообщение «rcu_preempt обнаруженные стойки на процессорах / задачах»

    Изменить диспетчер окон в Fedora 18

    постоянные сеансы ssh без экрана или tmux

    команда tree в скрипте оболочки не добавляет слэши для каталогов

    Докерная связь между контейнерами

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