У меня есть сценарий EXPECT, который отслеживает http pid на сервере IBMIHS:
....
send "ps -ef|grep htt|grep start|wc -l \r"
expect {
-re {.*(\d+).*} {
set theNum $expect_out(1,string)
}
}
puts "theNum = $theNum"
if {$theNum > 8} {
puts "it is ok"
} else {
puts "it is not ok"
}
....
send "ps -ef|grep htt|grep start|wc -l \r"
генерирует:
send: sending "ps -ef|grep htt|grep start|wc -l \r" to { exp5 }
Gate keeper glob pattern for '.(\d+).' is ''. Not usable, disabling the performance booster.expect: does "" (spawn_id exp5) match regular expression ".(\d+)."? (No Gate, RE only) gate=yes re=no
ps -ef|grep htt|grep start|wc -lexpect: does "ps -ef|grep htt|grep start|wc -l \r\n" (spawn_id exp5) match regular expression ".(\d+)."? (No Gate, RE only) gate=yes re=no
11expect: does "ps -ef|grep htt|grep start|wc -l \r\n11\r\n" (spawn_id exp5) match regular expression ".(\d+)."? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) "ps -ef|grep htt|grep start|wc -l \r\n11\r\n"
expect: set expect_out(1,string) "1"
expect: set expect_out(spawn_id) "exp5" expect: set expect_out(buffer) "ps -ef|grep htt|grep start|wc -l \r\n11\r\n"
theNum = 1
it is not ok
Командная строка на самом деле возвращает число «11», но вместо этого (\d+)
ловит один '1'.
Ваши комментарии приветствуются заранее.
Это происходит из-за жадности ведущего .*
— поскольку это поглощает как можно больше символов, текст, остающийся для части (\d+)
, представляет собой цифру прошлой. Вот демонстрация, в которой я также фиксирую начальный «.*»:
expect1.11> exp_internal 1
expect1.12> spawn sh -c {echo foo; echo 1234; echo bar}
spawn sh -c echo foo; echo 1234; echo bar
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {78523}
78523
expect1.13> expect -re {(.*)(\d+).*}
Gate keeper glob pattern for '(.*)(\d+).*' is ''. Not usable, disabling the performance booster.
expect: does "" (spawn_id exp10) match regular expression "(.*)(\d+).*"? (No Gate, RE only) gate=yes re=no
foo
1234
bar
expect: does "foo\r\n1234\r\nbar\r\n" (spawn_id exp10) match regular expression "(.*)(\d+).*"? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) "foo\r\n1234\r\nbar\r\n"
expect: set expect_out(1,string) "foo\r\n123"
expect: set expect_out(2,string) "4"
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) "foo\r\n1234\r\nbar\r\n"
Обратите внимание на то, что сохраняется в «1, строка» и «2, строка»
Решение состоит в том, чтобы упростить ваше регулярное выражение. Если вы просто хотите захватить набор цифр первый, используйте
expect -re {\d+}
set theNum $expect_out(0,string)
Или, если вы хотите захватить первые цифры это единственные символы в строке:
expect -re {\r\n(\d+)\r\n}
set theNum $expect_out(1,string)
Один из уроков здесь заключается в том, что обычно вам не нужны начальные и конечные подстановочные знаки .*
в ваших шаблонах регулярных выражений: просто сосредоточьтесь на том, что вам нужно, чтобы захватить нужный текст.
Гленн, Ваше решение работает отлично! нравится стиль ответа: чисто и по делу! Спасибо!