我正在尝试使用 io.Copy 从一个文件中进行复制,它在实际将字节复制出其内部缓冲区之前等待 EOF,对吗?在我的用例(PTY/SSH session )中,EOF 仅在 session 完成时出现,这意味着我一直在盲目飞行,直到 session 决定结束。
我曾尝试一次使用 1 个字节的 CopyN,这确实有效,但如果我尝试等待某一位文本出现,然后复制一个已推送到文件的内容,代码将挂起,我失去了 session 。是否有仅“读取那里的内容”然后停止的功能,或可以告诉副本暂时停止的不同标记(如 EOF)?
我也尝试读取 ptyI.pty 指向的文件的内容,但它总是返回 0 字节,所以我无法在那里检查更新
这是目前处理它的代码:
type PtyInterface struct {
pty *os.File
buf *bytes.Buffer
}
func (ptyI *PtyInterface) PrivCmd(cmdStr string) (string, error) {
// Copy the command provided into the STDIN of the bash shell we opened with
// the earlier PtyInterface
_, _ = io.Copy(ptyI.pty, strings.NewReader(string("somecommand")))
// Assuming everything has gone well, we wait for the prompt to appear
// We do this by running through individual bytes until the prompt is
// fully printed (otherwise we might try to send in the answer at the wrong time)
for !strings.HasSuffix(ptyI.buf.String(), "Prompt question? ") {
_, _ = io.CopyN(ptyI.buf, ptyI.pty, 1)
}
// Once we hit the prompt we throw the answer into STDIN along with a newline
// and the bash shell should accept this and begin executing the command.
_, _ = io.Copy(ptyI.pty, strings.NewReader(string("answer\n")))
// If we dont throw an exit in there then the PTY will never receive an EOF marker and we'll
// hang on the next copy
_, _ = io.Copy(ptyI.pty, strings.NewReader(string("exit\n")))
// Now this copy will wait for an EOF
_, _ = io.Copy(ptyI.buf, ptyI.pty)
//Debug info to be printed after
fmt.Println("\nBytes written to buffer (newone): \n" + ptyI.buf.String())
return ptyI.buf.String(), nil
}
最佳答案
将 io.Copy 视为批量复制或流的便利函数,而不是请求/响应模式的正确工具。
通过检查每个字节是否与消息匹配,将字节累积到消息中。直接使用Read方法。
func Expect(message string, r io.Reader) (resp string, err error) {
b := []byte{0} // 1 byte buffer
var n int
for err == nil {
n, err = r.Read(b)
if n == 0 {
continue
}
resp += string(b[0])
if strings.HasSuffix(resp, message) {
return resp, err
}
}
return resp, err
}
在您的示例中,您可以这样使用:
resp, err := Expect("Prompt question? ", ptyI.pty)
这是一个模拟连接 io.Reader 的实际演示:playground .
关于shell - Golang 从 *os.file 复制而不挂起等待 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51502276/
从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
CSV.open(name,"r").eachdo|row|putsrowend我得到以下错误:CSV::MalformedCSVErrorUnquotedfieldsdonotallow\ror\n文件名是一个.txt制表符分隔文件。我是专门做的。我有一个.csv文件,我转到excel,并将文件保存为.txt制表符分隔的文件。所以它是制表符分隔的。CSV.open不应该能够读取制表符分隔的文件吗? 最佳答案 尝试像这样指定字段分隔符:CSV.open("name","r",{:col_sep=>"\t"}).eachdo|row|
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我想将我的MacSnowLeopardruby从1.8.7升级到1.9.1版本,有人知道轻松且最好的升级方法吗?因为我读了一些论坛/帖子/博客/讨论说覆盖苹果发布的ruby不好将Rails从版本2.2.2升级到2.3.8的最佳方法是什么?因为我找到的所有信息都仅适用于豹/老虎,而且很少有关于雪豹的复杂文章。他们还说覆盖apple提供的rails不好吗。谁能帮帮我?谢谢。 最佳答案 DanBenjamin有一些greatinstructionsforcompilingandinstallingRuby,RubyGemsandRai
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
这个问题在这里已经有了答案:Whatdoes`if__FILE__==$0`meaninRuby(6个答案)关闭6年前。我在审查Ruby代码时偶然发现了这个语法。代码是:if__FILE__==$PROGRAM_NAME#somecode...end我想__FILE__是一个变量,可以让我获取我所在文件的名称?但是$PROGRAM_NAME简化了什么?另外,为什么这个if语句是必需的,因为程序可以使用或不使用它?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.