expect
起動したら、端末を監視し、一致するものが見つかるたびにコマンドを実行するスクリプトを作成しようとします。
これは可能ですかexpect
?それでは、expect_background
使用するのが正しいのでしょうか?
編集:確かに言えば、expect
入力ではなく端末から出力しようとしています。
答え1
はい、bashでは簡単にこれを行うことができます。標準出力をtee
パターンを表示するときに操作を実行できるプロセスにリダイレクトします。tee
標準出力に標準出力を追加するので良いです。
exec 1> >(tee >(awk '/foobar/ {print "*** DING DING ***"}'))
tee
これは、標準入力をstdoutとプロセス置換2(何かを実行するawkスクリプト)にコピーするプロセス置換1にstdoutを送信します。コードまたはスクリプトへのパスを内部プロセス置換に入れることができます。
展示する
$ echo this is foobar stuff
this is foobar stuff
$ exec 1> >(tee >(awk '/foobar/ {print "*** DING DING ***"}'))
$ date
Thu Mar 10 16:37:14 EST 2016
$ pwd
/home/jackman
$ echo this is foobar stuff
this is foobar stuff
*** DING DING ***
答え2
#!/usr/bin/env expect
#
# Adapted from autoexpect(1). Matches stuff from user.
if {[llength $argv] == 0} {
send_user "Usage: $argv0 command \[cmd args...]\n"
exit 64
}
match_max 100000
set userbuf ""
proc input {c} {
global userbuf
send -- $c
append userbuf $c
# if see this pattern in the input, execute command
# NOTE may well muss up the terminal display, depending
# on the output, etc.
if {[regexp "echo.foo\r" $userbuf]} {
system "uptime"
# trim buffer between commands so not chewing up all the memory
} elseif {[regexp "\r" $userbuf]} {
set userbuf ""
}
}
spawn -noecho $argv
interact {
# match incoming characters, send to buffer builder (otherwise
# if just "echo foo" here that input will vanish until expect
# can run a command, or fails the match, which isn't nice.
-re . { input $interact_out(0,string) }
eof { return }
}
他の方法はもっと簡単です(しかしシェルエコーに注意してください)。
#!/usr/bin/env expect
#
# Also adapted from autoexpect(1).
if {[llength $argv] == 0} {
send_user "Usage: $argv0 command \[cmd args...]\n"
exit 64
}
match_max 100000
proc output {s} {
send_user -raw -- $s
# NOTE shells tend to echo commands as they are typed, which may
# cause double-triggers depending on the expression being looked
# for an what exactly is passed to this call from the echos.
if {[regexp "foo" $s]} {
system "uptime"
}
}
spawn -noecho $argv
interact {
-o -re .+ { output $interact_out(0,string) }
eof { return }
}