Newlines
我如何期望期望腳本中的換行符?
考慮這個互動式腳本:
#!/usr/bin/env bash set -eu while true; do read -p '> ' if [ "$REPLY" == quit ]; then break fi echo "'$REPLY'" done
現在我想
expect
與之互動:#!/usr/bin/env bash set -eu echo ' spawn ./1.sh expect > send cmd1\n expect {\n> } send quit\n ' | expect -d
但是當我執行它時,它說:
... expect: does " cmd1\r\n'cmd1'\r\n> " (spawn_id exp6) match glob pattern "\n> "? no expect: timed out send: sending "quit\n" to { exp6 }
為什麼不匹配?如何檢測新提示的出現(完成命令)?
tl;博士添加
-ex
標誌。這裡的事情是
expect
更容易將復雜的參數傳遞給一些命令(expect
/interact
):接受包含在單個列表中的參數的命令(期望變體和互動)使用啟發式方法來確定列表實際上是一個參數還是多個參數。僅當列表確實表示具有多個嵌入的 \n 且它們之間具有非空白字元的單個參數時,啟發式方法才會失敗。這似乎不太可能,但是參數“-nobrace”可用於強制將單個參數作為單個參數處理。可以想像,這可以與機器生成的 Expect 程式碼一起使用。同樣, -brace 強制將單個參數作為多個模式/動作處理。
(來自expect命令的描述)如果整個expect語句的參數需要多於一行,所有的參數可以“支撐”成一個,以避免每一行都以反斜杠結束。在這種情況下,儘管有大括號,仍會發生通常的 Tcl 替換。
讓我在這裡舉個例子:
#!/usr/bin/env bash set -eu f() { echo line 1 sleep 1 echo line 2 } export -f f echo ' spawn bash -c f expect { {line 1} {puts 1} {line 2} {puts 2} } expect \ {line 1} {puts 1} \ {line 2} {puts 2} ' | expect
輸出:
spawn bash -c f line 1 1 line 2 2
在我發現的儲存庫中,最新送出(2014 年 5 月)中的啟發式如下:如果傳遞了一個參數並且在第一個非空格之前有一個換行符,則該參數被認為是多個參數支撐成一個。
在語言中,用和
expect
tcl
引用的字元串是有區別的。您可以在 2 個範例中看到這一點:""``{}
$ expect -c 'puts "a\nb"' a b ~ $ expect -c 'puts {a\nb}' a\nb
您的 glob 模式
{\n> }
由 4 個要匹配的字元組成,但\n
不會特別解釋為轉義。如果您使用模式,"\n> "
您的匹配應該可以工作。或者您可以使用 flag-re
代替預設的 glob 模式,這兩個字元將被正則表達式程式碼解釋為轉義,-re {\n> }
.