프로그램 대화를 모니터링하고 알림을 보냅니다.

프로그램 대화를 모니터링하고 알림을 보냅니다.

저는 우분투 16.04 LTS를 사용하고 있습니다. 내 별칭은 다음을 .bashrc사용합니다 notify-send.

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

alert다른 명령을 somecommand; alert또는 으로 추가하고 somecommand && alert완료되면(성공적으로) 팝업 알림을 받을 수 있습니다 . somecommand터미널 창(현재 최소화됨)이나 다른 작업 공간에서 실행한 명령이 실행을 완료했음을 상기시켜줍니다.

하지만 완료보다는 사용자 입력을 기다릴 때(예/아니요 프롬프트와 같은) 유사한 경고를 원합니다. 어떻게 해야 하나요?

유사한 솔루션을 사용하는 것이 좋지만 notify-send다른 솔루션을 사용하는 것이 좋습니다.더 쉽게대안도 좋습니다.

혼란을 방지하기 위해 프롬프트에 대한 자동 응답을 생성하지 않겠습니다. 사용자 입력(예: )이 필요할 수 있는 긴 출력이 포함된 명령을 실행할 때 터미널 창을 (최소화/다른 작업 공간에서) 잊어버린 경우 알림을 받기를 원합니다 apt update && apt upgrade.

답변1

프로그램 대화를 모니터링하고 알림을 보냅니다.

다음 활동을 모니터링할 수 있습니다.

  1. 선입선출또는
  2. 하나xterm로그 파일, 이제 대화형 모드가 있습니다.

그리고 시작해 보자zenity정보 메시지, 모니터링되는 프로그램에서 입력이 있는 경우. 원하시면 설치도 가능합니다espeak그리고 그것을 보내도록 하세요오디오 메시지.

zenity1. fifo를 사용하여 모니터링되는 프로그램에 입력이 있을 때 정보 메시지를 시작합니다.

다음 쉘스크립트는 프로그램의 출력 대화 상자를 모니터링하고 경고를 보냅니다.

  • 그래픽 데스크탑 환경을 가정
  • "콘솔"처럼 작동하는 터미널 창에서 래퍼 쉘스크립트를 실행합니다.wrapper
  • xterm모니터링하고 싶은 프로그램을 창에서 시작하세요
  • xterm창에서 대화 실행(이곳은 귀하의 의견을 작성하는 곳입니다)
  • 모니터링하려는 프로그램의 출력에 액세스하려면 fifo를 사용 /dev/stdout하고 dev/stderr.
  • while루프 를 실행하다
    • FIFO가 수정되었는지 테스트합니다. 어떤 경우에는
      • zenity정보 메시지 창을 실행합니다 .

내용을 입력한 창 으로 돌아가려면 창 을 닫아야 합니다 zenity("Enter" 키를 사용할 수 있음) .xterm

#!/bin/bash

if [ $# -eq 0 ]
then
 echo "'$0' is a wrapper, that sends a notification, when the wrapped program
has written to standard input and standard error and may be waiting for input.
---
Usage:   $0 <program name> [parameters]
Example: $0 .program"
 exit
fi

message="'${1##*/} $2 ...' has written something, maybe asks for input"

tmpdir=$(mktemp -d)
tmpfifo=$(mktemp --tmpdir=$tmpdir)
rm "$tmpfifo"
mkfifo "$tmpfifo"
#ls -l "$tmpdir"
cnt1=$(stat --printf "%Y" "$tmpfifo")
sleep 1

xterm -title "${1##*/} $2 ..." -fa default -fs 11 -bg '#403600' \
 -e bash -c "$* 2>&1 | tee /dev/stderr 2>&1 > $tmpfifo" 2> /dev/null & pid=$!

#< "$tmpfifo" espeak &
< "$tmpfifo" cat &

cont=true
while $cont
do
 tmpstr=$(ps -Af |sed "s/grep $pid//"|grep "$pid")
# echo "$tmpstr"
 if [ "$tmpstr" != "" ]
 then
  cnt0=$cnt1
  cnt1=$(stat --printf "%Y" "$tmpfifo")
  if [ "$cnt1" != "$cnt0" ]
  then
#   zenity --notification --text="$message" 2> /dev/null
#   espeak "$message" &
   zenity --info --title="${0##*/} ${1##*/} $2 ..." \
    --text="$message" --width=500  2> /dev/null
  fi
  sleep 1
  else
  sleep .2
  # echo "process $pid has finished"
  cont=false
 fi
done

# clean up

rm -r "$tmpdir"

오디오 메시지를 받기 위해 espeak더 가까이 달려가고 싶을 수도 있습니다 . zenity이 경우 #줄 시작 부분의 문자를 제거할 수 있습니다. (프로그램에 많은 텍스트가 있을 수 있으므로 fifo를 로 리디렉션하는 것은 일반적으로 좋은 생각이 아닙니다 . fifo를 로 리디렉션 하고 콘솔에서 인쇄하는 espeak것이 좋습니다 .)cat

데모

cp -i사용하고 테스트할 수 있는 몇 가지 명령줄이 있으며 mv -i다음과 같은 작은 쉘스크립트로 테스트할 수 있습니다 program.

#!/bin/bash

while true
do
 read -p "Waiting for input. 'Stop' to Quit " string
 if [ "${string:0:4}" == "Stop" ]
 then
  printf "$string. Gotcha\n"
  break
 elif [ "$string" != "" ]
 then
  printf "$string\n"
  printf "Working for 10 seconds ...\n"
  sleep 10
 else 
  sleep 3
 fi
done

도움말 텍스트:

$ ./wrapper
'./wrapper' is a wrapper, that sends a notification, when the wrapped program
has written to standard input and standard error and may be waiting for input.
---
Usage:   ./wrapper <program name> [parameters]
Example: ./wrapper .program

모니터 program:

$ ./wrapper ./program

zenity정보 메시지 창:

여기에 이미지 설명을 입력하세요.

창 대화상자 xterm:

Waiting for input. 'Stop' to Quit Hello
Hello
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit World
World
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit Goodbye
Goodbye
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit Stop

완료되면 원래 터미널 창에 "콘솔" 출력:

$ ./wrapper ./program
Waiting for input. 'Stop' to Quit Hello
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit World
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit Goodbye
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit Stop. Gotcha

모니터 cp -ip:

$ LANG=C /path/wrapper cp -ip ubuntustudio-18.04-dvd-amd64.iso ubuntu-18.04.1-desktop-amd64.iso /tmp

zenity정보 메시지 창:

여기에 이미지 설명을 입력하세요.

대화 xterm:

cp: overwrite '/tmp/ubuntustudio-18.04-dvd-amd64.iso'? y
cp: overwrite '/tmp/ubuntu-18.04.1-desktop-amd64.iso'? n

모니터 sudo parted /dev/sdc:

$ LANG=C ./wrapper sudo parted /dev/sdc

대화 xterm:

[sudo] password for sudodus: 
GNU Parted 3.2
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
Model: SanDisk Extreme (scsi)
Disk /dev/sdc: 16,0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type      File system  Flags
 3      2097kB  258MB   256MB   primary   fat32        boot
 4      258MB   1366MB  1108MB  primary
 2      1366MB  12,4GB  11,0GB  extended               lba
 5      1367MB  6736MB  5369MB  logical   ext2
 6      6737MB  12,4GB  5615MB  logical   ext4
 1      12,4GB  16,0GB  3662MB  primary   ntfs

(parted) q

zenity2. 창에 무언가가 기록되면 xterm(모니터링되는 프로그램 또는 사용자로부터) 정보 메시지가 시작됩니다.

다음 쉘스크립트는 프로그램과의 대화를 모니터링하고 경고를 보낼 수 있습니다.

  • 그래픽 데스크탑 환경을 가정
  • "콘솔"처럼 작동하는 터미널 창에서 래퍼 쉘스크립트를 실행합니다.wrapper
  • xterm모니터링하고 싶은 프로그램을 창에서 시작하세요
  • xterm창에서 대화 실행(이곳은 귀하의 의견을 작성하는 곳입니다)
  • 로그 파일을 사용하여 xterm모니터링하려는 프로그램의 출력 및 입력에 액세스하세요.
  • while루프 를 실행하다
    • 로그 파일이 수정되었는지 테스트합니다. 수정된 경우
      • zenity정보 메시지 창을 실행합니다 .
      • 입력 시 짧은 지연을 허용합니다(8초, 스크립트 파일을 편집하여 지연을 변경할 수 있음).

내용을 입력한 창 으로 돌아가려면 창 을 닫아야 합니다 zenity("Enter" 키를 사용할 수 있음) .xterm

xterm이제 이 창을 터미널 창처럼 사용할 수 있는 대화형 모드가 있습니다 .xterm모니터링을 중지하려면 창을 닫으세요 .

#!/bin/bash

# date        editor   comment
# 2018-12-31  sudodus  version 1.0

version=1.0

name="${0##*/}"
if [ "$1" == "-h" ] || [ "$1" == "--help" ]
then
 echo "'$name' is a wrapper, that sends a notification, when the wrapped program
has written to standard input and standard error and may be waiting for input.
---
Usage:    $name [program name] [parameters]
Examples: $name          # to run program(s) interactively in an xterm window
          $name program
          $name -h       # to get help (this text)
          $name -v       # show version"
 exit
elif [ "$1" == "-v" ]
then
 echo "$name version $version"
 exit
fi
tstart=$(date '+%s')
echo "----- start $name at $(date '+%F %T') ----------------------------"
tmpstr="${1##*/}"
xtermlog=$(mktemp -u)

if [ $# -eq 0 ]
then
 mess_zenity="Check, if the monitored program asks for input"
 mess_espeak="${mess_zenity/program/, Program,}"
 xterm -title "monitored by ${0##*/}" -fa default -fs 11 -bg '#2c2b2a' \
 -l -lf "$xtermlog" -sb -rightbar 2> /dev/null & pid=$!
else
 mess_espeak="Check if '${tmpstr^} ${2##*/} ${3##*/} ...' asks for input"
 mess_zenity="Check if '$tmpstr $2 $3 ...' asks for input"
 xterm -title "${1##*/} $2 $3 ..." -fa default -fs 11 -bg '#2c2b2a' \
 -l -lf "$xtermlog" -e "$@" 2> /dev/null & pid=$!
fi
sleep 0.5
sync
cnt1=$(stat --printf "%Y" "$xtermlog")
tail -f "$xtermlog" & ptail=$!

cont=true
while $cont
do
 sleep 1
 cnt0=$cnt1
 tmpstr=$(ps -Af |sed "s/grep $pid//"|grep "$pid")
# echo "$tmpstr"
 if [ "$tmpstr" != "" ]
 then
  cnt1=$(stat --printf "%Y" "$xtermlog")
  if [ $cnt1 -gt $((cnt0 + 8)) ]
  then
#   zenity --notification --text="$message" 2> /dev/null
   espeak "$mess_espeak" &
   zenity --info --title="${0##*/} ${1##*/} $2 ..." \
    --text="$mess_zenity" --width=500  2> /dev/null
   touch "$xtermlog"
   cnt1=$(stat --printf "%Y" "$xtermlog")
  fi
  sleep 1
  else
  sleep .2
  # echo "process $pid has finished"
  cont=false
 fi
done

# clean up
tmpstr="$(tail -n1 "$xtermlog" | sed 's/.*exit.*/exit/')"
if [ "$tmpstr" != "exit" ]
then
 echo ""
fi
rm -r "$xtermlog"
kill $ptail
tend=$(date '+%s')
tuse=$((tend-tstart))
echo "------- end $name at $(date '+%F %T') --- used $tuse seconds"

bash코드를 파일에 저장하고 이름(예:)을 지정하거나 vialog실행 가능하게 만들거나 경로의 디렉터리로 이동합니다.

$ vialog
----- start vialog at 2018-12-31 14:37:41 ----------------------------

xterm창에서 작업하면 대화가 시작 창으로 다시 에코됩니다 .

여기에 이미지 설명을 입력하세요.

sudodus@bionic64 /media/multimed-2/test/test0/pomsky-wrap $ ./program
Waiting for input. 'Stop' to Quit Hello World
Hello World
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit I am writing ...
I am writing ...
Working for 10 seconds ...
Waiting for input. 'Stop' to Quit Stop
Stop. Gotcha
sudodus@bionic64 /media/multimed-2/test/test0/pomsky-wrap $ scrot -sb
sudodus@bionic64 /media/multimed-2/test/test0/pomsky-wrap $ exit
exit
------- end vialog at 2018-12-31 14:39:02 --- used 81 seconds

여기에 이미지 설명을 입력하세요.

답변2

피드백 초대

이미 기존 답변에 다른 쉘스크립트를 추가하는 대신 두 번째 답변을 사용하는 것이 더 낫다고 생각합니다. 나는 피드백을 듣고 선호하는 스크립트/방법에 초점을 맞추고 선호하는 스크립트/방법을 단일 답변으로 병합하려고 노력할 것입니다(다른 목적을 위해 모두 유지할 이유가 없는 한).

프로그램 대화를 모니터링하고 알림을 보냅니다.

다음 활동을 모니터링할 수 있습니다.

  1. 선입선출또는
  2. 하나xterm로그 파일

그리고 시작해 보자zenity정보 메시지, 모니터링되는 프로그램에서 입력이 있는 경우. 원하시면 설치도 가능합니다espeak그리고 그것을 보내도록 하세요오디오 메시지.

이 답변은 다음을 사용하여 두 번째 옵션에 중점을 둡니다.선입선출.

zenityfifo를 사용하여 모니터링되는 프로그램에 입력이 있을 때 정보 메시지를 시작합니다.

1.1 xtermfifo를 통해 표준 출력 및 표준 오류를 사용하고 모니터링합니다.

wrapper방법은

  • 이점, 직접 입력해도 알람이 발생하지 않습니다. 이는 cp -i및 와 같은 많은 프로그램에서 작동합니다 sudo.
  • 피해, 저것
    • 일부 프로그램은 표준 출력 및 표준 오류 이상의 기능을 사용하여 출력을 작성하므로 비활성화됩니다. 예: sftp프롬프트가 사라지고 사용자는 프로그램이 언제 새 작업을 수행할 준비가 되었는지 알 수 없습니다.
    • 일부 프로그램은 경고를 트리거하는 입력(간접 입력이 있음)을 에코합니다. 이로 인해 이를 고려하지 않는 쉘 스크립트에 많은 경고가 발생할 수 있습니다. 예: ssh.

script1.2 fifo를 통해 컴파일된 프로그램과 해당 로그 파일 사용

다음 쉘스크립트는 프로그램의 출력 대화 상자를 모니터링하고 경고를 보냅니다. espeakscript( scriptUbuntu 및 Debian에서는 설치가 필요하지 않음) 이 필요합니다 .

sudo apt update
sudo apt install espeak
  • 그래픽 데스크탑 환경을 가정
  • 터미널 창에서 쉘스크립트를 시작하고 호출해 보겠습니다.viafifo.
  • viafifo" 에서" 모니터링할 프로그램을 시작합니다.
  • 터미널 창에서 대화 실행(이곳은 귀하의 의견을 작성하는 곳입니다)
  • 모니터링하려는 프로그램의 출력에 액세스하려면 fifo를 사용 하고 /dev/stdin. 쉘스크립트의 주요 작업은 프로그램의 라인과 관련된 것입니다./dev/stdoutdev/stderrscript즉, 터미널 창에서 활동을 모니터링하고 fifo에 씁니다.
  • while루프 를 실행하다
    • FIFO가 수정되었는지 테스트합니다. 어떤 경우에는
      • zenity정보 메시지 창과 해당 음성 메시지를 실행합니다 espeak.
      • 입력 시 짧은 지연을 허용합니다(8초, 스크립트 파일을 편집하여 지연을 변경할 수 있음).

내용을 입력한 창 으로 돌아가려면 창 을 닫아야 합니다 zenity("Enter" 키를 사용할 수 있음) .xterm

exit휴가 script및 를 입력합니다 viafifo. 그런 다음 전체 대화가 포함된 로그 파일을 얻을 수 있습니다.

viafifo테스트를 거쳤습니다.

데모 예시

스크린샷

여기에 이미지 설명을 입력하세요.

여기에 이미지 설명을 입력하세요.

time viafifo

user@debian:~$ time viafifo
----- Start viafifo ------------------------------------------------------------
user@debian:~$ echo hello
hello
user@debian:~$ exit
exit
----- End viafifo --------------------------------------------------------------
See 'viafifo.log'
viafifo used 8 seconds plus a few (5-10) seconds for preparing and finishing
real    0m13.295s
user    0m0.104s
sys 0m0.012s

viafifo.log

user@debian:~$ cat viafifo.log
Script started on Sat 05 Jan 2019 07:57:45 PM UTC
user@debian:~$ echo hello
hello
user@debian:~$ exit
exit
viafifo used 8 seconds
user@debian:~$ 

관련 정보