2015-09-08 44 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" 
相关问题