使用Expect调用Rails控制台无实时输出,仅进程终止后可见如何解决?
解决Expect调用Rails控制台无实时输出的问题
原脚本的问题
你用exec bundle exec rails c的方式会卡住,因为exec命令会等待目标进程完全退出后才返回所有输出,而Rails控制台是交互式会话,不会主动终止,所以必须杀死进程才会拿到输出。
正确的Expect脚本写法
用spawn替代exec来启动交互式进程,配合expect和send处理输入输出,示例脚本:
#!/usr/bin/expect -f # 启动Rails控制台 spawn bundle exec rails c # 等待控制台提示符出现(根据你的Rails版本,提示符可能略有不同,比如"[1] pry(main)>") expect "irb(main):" # 示例:执行一条测试命令,打印当前Rails环境 send "puts Rails.env\n" # 等待命令执行完成,再次匹配提示符 expect "irb(main):" # 打印捕获到的输出内容 puts $expect_out(buffer) # 正常退出控制台 send "exit\n" expect eof
处理输入文件每一行的扩展
如果要批量处理输入文件的每一行,可添加文件读取和循环逻辑:
#!/usr/bin/expect -f # 读取输入文件 set input_file "your_input.txt" set fp [open $input_file r] set lines [split [read $fp] "\n"] close $fp # 启动Rails控制台 spawn bundle exec rails c expect "irb(main):" # 循环处理每一行 foreach line $lines { # 跳过空行 if {$line eq ""} continue # 发送自定义命令(这里替换成你需要执行的操作) send "puts 'Processing line: $line'\n" # 等待命令执行完成 expect "irb(main):" # 输出结果 puts $expect_out(buffer) } # 退出控制台 send "exit\n" expect eof
关键注意事项
- 确保
expect匹配的提示符和你的Rails控制台实际输出一致(比如用Pry的话是pry(main)>) - 发送命令时必须加
\n模拟回车键,否则控制台不会执行命令 $expect_out(buffer)会保存从上次expect到这次匹配到的所有输出,可以按需提取或打印
内容的提问来源于stack exchange,提问作者marco
相关产品推荐
相关产品推荐

