2015-09-08 46 views
1

我寫了一個期望腳本,它有助於在遠程計算機中執行命令。當執行完成後,我想獲取用戶輸入的一條線,然後將其發送到遠程的bash,這裏是代碼片段:獲取一行用戶輸入,然後將其作爲Bash命令執行

#! /usr/bin/env expect 
... 
spawn ssh -l $user $host 
... 
send_tty -- "Enter your command: " 
set timeout -1 

# match only printable characters (prevent from pressing TAB) 
expect_tty eof exit -re {([[:print:]]*)\n} 
send_tty -- "\n" 
set timeout 10 

# send the command to remote shell 
send "$expect_out(1,string)" 
expect "$GENERAL_PROMPT" 

然而,如果輸入的是一樣的東西:ls /",我的程序將被阻止,因爲遠程shell期望通過提示字符串「>」來獲得更多字符。其實,我希望bash將不提示輸入更多,而不是隻打印錯誤消息:

$ read COMMAND 
ls /" 
$ eval "$COMMAND" 
bash: unexpected EOF while looking for matching `"' 
bash: syntax error: unexpected end of file 

我可以在我的腳本實現這一目標?

+0

@ zhujs:我不是專家慶典,但是,當我試圖簡單地執行'和'LS讀COMMAND' /「'作爲輸入和'EVAL $ COMMAND'我在得到上面的錯誤如果輸入沒有雙引號,即'ls /',那麼它工作正常 – Dinesh

+0

我只想讓我的腳本在用戶輸入'ls /'時打印同樣的錯誤' – zhujs

+0

使用'eval'就好像你試過了。 – pynexj

回答

1
#!/usr/bin/expect 
set prompt "#|%|>|\\\$ $"; # A generalized prompt to match known prompts. 
spawn ssh -l dinesh xxx.xx.xx.xxx 
expect { 
    "(yes/no)" { send "yes\r";exp_continue} 
    "password" 
} 
send "mypassword\r" 
expect -re $prompt 
send_tty -- "Enter your command: " 
set timeout -1 

# match only printable characters (prevent from pressing TAB) 
expect_tty eof exit -re {([[:print:]]*)\n} 
send_tty -- "\n" 
set timeout 10 
puts "\nUSER INPUT : $expect_out(1,string)" 

# send the command to remote shell 
# Using 'here-doc', to handle possible user inputs, instead of quoting it with any other symbol like single quotes or backticks 
send "read COMMAND <<END\r" 
expect -re $prompt 
send "$expect_out(1,string)\r" 
expect -re $prompt 
send "END\r" 
expect -re $prompt 

# Since we want to send the literal dollar sign, I am sending it within braces 
send {eval $COMMAND} 
# Now sending 'Return' key 
send "\r" 
expect -re $prompt 

爲什麼使用'here-doc'?

如果我使用反引號或單引號來轉義命令,那麼如果用戶在命令本身中給了反引號或單引號,那麼它可能會失敗。所以,爲了克服這一點,我在這裏添加了doc。

輸出:

[email protected]:~/stackoverflow$ ./zhujs 
spawn ssh -l dinesh xxx.xx.xx.xxx 
[email protected]'s password: 

[[email protected] ~]$ matched_literal_dollar_sign 
Enter your command: ls /" 


USER INPUT : ls /" 
read COMMAND <<END 
> ls /" 
> END 
[[email protected] ~]$ eval $COMMAND 
-bash: unexpected EOF while looking for matching `"' 
-bash: syntax error: unexpected end of file 
[[email protected] ~]$ [email protected]:~/stackoverflow$ 

更新:

使用here-doc的主要原因是由於它使得讀充當非阻塞命令這一事實。即我們可以通過下一條命令快速進行。否則,我們必須等到Expect的超時時間。 (當然,我們可以動態更改超時值。)

這只是一種方法。你可以根據需要改變它,只需要使用read命令。

+0

哇,似乎會工作,你可以用一個例子來解釋你的'爲什麼「在這裏-DOC」 used'? – zhujs

+0

更新輸出。希望有所幫助。 – Dinesh

+0

「如果我用反引號或單引號逃逸的命令,那麼如果用戶給反引號或單引號中的命令本身,那麼它可能會失敗。」這是什麼意思嗎? – zhujs

1

我認爲這將是interact的一個很好的例子 - 期望放手一邊,讓用戶直接與衍生程序進行交互。

spawn ssh -l $user $host 
#... 

send_user "You are now about to take control: type QQQ to return control to the program\n" 

interact { 
    QQQ return 
} 

send_user "Thanks, I'm back in charge ...\n" 
相關問題