簡體   English   中英

獲取一行用戶輸入,然后將其作為 Bash 命令執行

[英]Get one line of user input and then execute it as Bash commands

我寫了一個期望腳本,有助於在遠程機器上執行命令。 執行完成后,我想獲取一行用戶輸入,然后將其發送到遠程 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

我可以在我的腳本中實現這一點嗎?

#!/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”?

如果我使用反引號或單引號來轉義命令,那么如果用戶在命令本身中使用反引號或單引號,則它可能會失敗。 所以,為了克服這個問題,我添加了 here-doc。

輸出 :

dinesh@MyPC:~/stackoverflow$ ./zhujs
spawn ssh -l dinesh xxx.xx.xx.xxx
dinesh@xxx.xx.xx.xxx's password: 

[dinesh@lab ~]$ matched_literal_dollar_sign
Enter your command: ls /"


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

更新 :

使用here-doc主要原因是它使讀取充當非阻塞命令。 即我們可以快速進行下一個命令。 否則,我們必須等到Expect超時。 (當然,我們可以動態更改超時值。)

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

我認為這將是一個很好的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"

這是一個單行版本

read > export cmd ; eval $cmd ; unset cmd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM