プログラム会話を監視し、通知を送信します。

プログラム会話を監視し、通知を送信します。

私はUbuntu 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

フィードバックの招待

すでに既存の回答に別のシェルスクリプトを追加するのではなく、2番目の回答を使用する方が良いと思います。私はフィードバックを聞き、好みのスクリプト/方法に焦点を当て、好みのスクリプト/方法を単一の答えにマージしようとします(他の目的のためにすべてを維持する理由がない限り)。

プログラム会話を監視し、通知を送信します。

次のアクティビティを監視できます。

  1. 先入選出または
  2. 一つxtermログファイル

そして始めましょう。zenity情報メッセージ、監視対象プログラムに入力がある場合。ご希望であれば設置も可能ですespeakそしてそれを送るようにしてくださいオーディオメッセージ

この回答では、次を使用して2番目のオプションに焦点を当てます。先入選出

zenityfifoを使用して監視対象のプログラムに入力があると、情報メッセージを開始します。

1.1 xtermfifoを介して標準出力と標準エラーを使用して監視します。

このwrapper方法は

  • 利点、直接入力してもアラームは発生しません。これは、cp -iなどの多くのプログラムで機能しますsudo
  • ダメージ、それ
    • 一部のプログラムは、標準出力と標準エラー以上の機能を使用して出力を作成するため、無効になります。例:sftpプロンプトが消え、ユーザーはプログラムがいつ新しい操作を実行する準備ができたかを知ることができません。
    • 一部のプログラムは警告をトリガーする入力(間接入力がある)をエコーし​​ます。これにより、これを考慮しないシェルスクリプトに多くの警告が発生する可能性があります。例: ssh

script1.2 fifoでコンパイルされたプログラムとそのログファイルの使用

次のシェルスクリプトは、プログラムの出力ダイアログを監視し、警告を送信します。(UbuntuとDebianではインストールは不要)が必要ですespeakscriptscript

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:~$ 

関連情報