如何在预期脚本中关闭 stderr 或在退出后停止"Connection to ... closed"消息?



所以我一直在尝试使用 expect 学习 bash 脚本,我遇到了一个烦人的问题,即使我通过将 log_user 设置为 0 来关闭输出,当我退出 ssh 服务器时,注销消息仍然打印为"注销"与blah.blah.blah的连接已关闭"。走黑客的方式并在脚本中发出 exit 命令是不可取的,并且忽略了在终端中打印新行,留下了难看的终端提示。如何在预期脚本中禁止或关闭此连接关闭消息?这是我期望脚本的代码模板:

#!/usr/bin/expect -f
#-f flag tells expect to read commands from file
# Set Password Prompt and Password
set PASSP "password:"
set PASSW "your_password_heren"
# Set SFTP Prompt 
set SFTP "sftp> "
# Set Remote Prompt and Project Directories
# The GL server is super weird, so make sure RPROMPT ends in the
# name of the project compilation directory and PROJDIR is the 
# relative path (from home but without the tilde) of the main 
# project directory.
set RPROMPT "projdir_here]"
set PROJDIR "path_to_projdir_here"
# Set SSH Address
set ADDRESS your_username_here@your_address_here
# Annoying long output turned off
log_user 0
send_user "Logging in...n"
spawn sftp $ADDRESS
expect $PASSP
send $PASSW
expect $SFTP
send_user "Uploading necessary files...n"
send "cd $PROJDIRn"
expect $SFTP
send "put *.cpp .n"
expect $SFTP
send "put *.h .n"
expect $SFTP
send "put Makefile .n"
expect $SFTP
send "exitn"
spawn ssh $ADDRESS
expect $PASSP
send $PASSW
expect "]"
send "cd $PROJDIRn"
expect $RPROMPT
send_user "Cleaning remote directory...n"
send "make cleann"
# Output turned on temporarily so compiler feedback can be determined
expect $RPROMPT
log_user 1
send_user "Compiling on server...n"
send "maken"
# Turn off output and submit (this assumes that your makefile has a 'submit'
# target with the command to submit your file there)
expect $RPROMPT
log_user 0
send_user "nSubmitting Requisite Files...n"
send "make submitn"
expect $RPROMPT
send_user "Quitting...n"
# I can't figure out how to turn off stderr in expect so that an annoying 'connection closed' 
# message is printed even the log_user has been set to 0
send "logoutn"
# Transfer control to user
interact

您可以看到,在程序结束时,在我使用 interact 命令之前,在发送"logout"并关闭与服务器的连接后打印出有问题的消息。尽管log_user被设置为上面的 0,但这种情况还是会发生。我到底如何关闭脚本中的 stderr 输出?我什至查看了期望手册页,但那里似乎没有多大用处。我不明白如何在期望脚本中关闭 stderr,以便不打印此消息,将不胜感激!我真的只是想在注销时脚本保持安静。因为很明显我发出了注销命令,所以我不确定为什么这个输出会转到 stderr。ssh 中是否有不会输出"连接到...用户退出时关闭"消息?如果我能通过管道将 stderr 遗忘或以某种方式压制它,那就更好了。正常的方法似乎不起作用,因为这是一个预期脚本。

这只是不正确地使用了log_user。它应该用作,

log_user 0
send "logoutr"  
expect eof
log_user 1

请注意,我期待发送logoutreof模式,因为它会导致连接关闭。使用 send 命令时,始终使用 r 代替n

阅读此处以了解有关抑制输出log_user的更多信息。

无需提示将其定义为静态字符串,而是可以概括为:

# We escaped the `$` symbol with backslash to match literal '$' 
# The last dollar sign represents line-end.
set prompt "#|>|%|\$ $"; 

在使用 expect 时,我们必须附带 -re 标志以将其指定为正则表达式。

expect -re $prompt

SshDemo.exp

#!/usr/bin/expect 
set prompt "#|>|\$ $"
spawn ssh dinesh@myserver
expect {
        "(yes/no)" { send "yesr";exp_continue}
        "password"
}
send "welcome123r"
expect -re $prompt 
# Simply executing 'ls -l' command...
send "ls -lr"
expect -re $prompt
log_user 0
send "logoutr"
expect eof
log_user 1

这是我基于上述建议的新的改进脚本。我还决定使用 scp 而不是 sftp,因为它更简洁,而且我只上传文件。

#!/usr/bin/expect -f
#-f flag tells expect to read commands from file
# Set Password Prompt and Password
set PASSP "password: "
set PASSW "your_password_here"
# Set Remote Prompt and Project Directories
# The ssh server is super weird, so make sure PROJDIR is the 
# directory name of the main project directory and PATH is
# the relative path to the project directory from home (with the tilde)
set PROJDIR "your_projdir_name_here"
set PATH "your_projdir_path_here"
# Set SSH Address
set ADDRESS your_username_here@source_hostname_here
# Turn off annoying output
log_user 0
send_user "Logging in and uploading necessary files...n"
# upload files via scp, (shows upload prompt for user, concise)
spawn bash -c "scp *.cpp *.h Makefile $ADDRESS:$PATH"
expect $PASSP 
send "$PASSWr"
interact
spawn ssh $ADDRESS
expect $PASSP
send "$PASSWr"
expect "]"
send "cd $PATHr"
expect "$PROJDIR]"
send_user "nCleaning remote directory...n"
send "make cleanr"
# Output turned on temporarily so compiler feedback can be determined
expect "$PROJDIR]"
log_user 1
send_user "Compiling on server...nn"
send "maker"
# Turn off output and submit (this assumes that your makefile has a 'submit'
# target with the command to submit your file there)
expect "$PROJDIR]"
log_user 0
send_user "nnSubmitting Requisite Files...n"
send "make submitr"
expect "$PROJDIR]"
send_user "Quitting...n"
send "logoutr"
expect eof
# Exit
exit

最新更新