Posso ter um shell (bash) esperando executar em segundo plano?

0

Estou tentando escrever um script expect que, uma vez iniciado, assistirá ao meu terminal e executará um comando toda vez que encontrar uma correspondência.

Isso é possível com expect ? Em caso afirmativo, expect_background seria a coisa certa a ser usada?

EDIT: Para maior clareza, estou tentando expect a saída do meu terminal, não a entrada ...

    
por Questionmark 10.03.2016 / 20:59

2 respostas

2

Sim, você pode fazer isso apenas com bash: redirect stdout para um processo tee que pode fazer algo quando seus padrões são vistos. tee é bom porque também coloca stdout na stdout.

exec 1> >(tee >(awk '/foobar/ {print "*** DING DING ***"}'))

Isso envia stdout para processar a substituição 1, tee , que copia seu stdin para stdout e processa a substituição 2, um script awk que faz alguma coisa. Você poderia colocar seu código, ou o caminho para um script, na substituição do processo interno.

Para demonstrar

$ 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 ***
    
por 10.03.2016 / 22:39
1
#!/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 }
}

E o outro jeito é mais simples (mas cuidado com o eco do shell).

#!/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 }
}
    
por 10.03.2016 / 21:46