2010-10-06 33 views
2

我遇到了Ruby无法解释的奇怪问题。我有以下脚本,抓住任何代码目前在剪贴板上,运行它通过一个语法高亮,然后把新版本返回到剪贴板:“ruby script.rb”与“xterm -e ruby​​ script.rb”

#!/usr/bin/ruby1.9.1 

require 'coderay' 

language = "auto"; 
if(ARGV.length > 0) 
    language = ARGV[0]; 
end 

print("Using language: #{language} \n"); 

codeToHighlight = `xsel --clipboard` 

highlightedCode = CodeRay.scan(codeToHighlight, language.intern()).div 

IO.popen("xsel --clipboard", mode='w') do |io| 
    io.write highlightedCode 
    io.flush 
end 

奇怪的是,如果我直接在运行一个终端,它工作正常。如果我通过“xterm -e”运行它,但它不起作用。我发现另一个网站是问同样的问题这个线程,但人没有得到回答:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/138423

那人发现,如果他们加入在像这样的脚本的结尾处的停顿......

10000.times do 
    puts "" 
end 

...它的工作原理。为什么是这样?有没有办法来解决这个问题?我试着重写脚本,以便popen返回一个IO对象,我可以手动调用close,但这没有什么区别。

+1

我已经确定,无论问题是在xsel中。我试着在文件末尾添加一行(没有疯狂的puts“”循环),只是将突出显示的代码转储到一个文件中,而且无论运行脚本如何,它的内容都是正确的。我尝试了xclip,它似乎可以在更多情况下工作,尽管我只能获得主要(即中间单击)剪贴板来处理它。当从另一个脚本调用xclip时xclip不起作用,但xclip仍然无法通过xterm -e工作。 – Matthew 2011-02-23 14:14:12

回答

1

如果使用gnome-terminal -e而不是xterm -e执行它,那么该怎么办?

UPDATE:

OK,这里是我最好的猜测。你知道如果你发送一个终端程序到后台(使用命令后的&ctl-z),然后关闭终端,它会杀死程序,对吧?好吧,xsel会派生一个子进程来写入剪贴板,但是当ruby包装脚本完成并且xterm关闭时它必须被杀死。

这将解释为什么最后的暂停允许它工作 - 它只是给子进程提供足够的时间在终端退出前完成。它还解释了为什么它在手动运行时工作 - 您将终端打开足够长的时间,以便完成子进程。

尝试将-n选项添加到您的xsel命令,我敢打赌它的工作原理。 -n使xsel保持分叉状态。

+0

不,看起来没有用xclip或xsel。不过谢谢你。我很少再使用这个脚本,所以它没有什么大不了的,但知道它为什么这么做只是为了知道。 – Matthew 2011-05-09 13:09:35

+0

啊,夹子。我的想法可能是终端模拟器出现问题,当手动运行时,_maybe_打开gnome-terminal。 – James 2011-05-10 16:07:31

+0

我更新了我的答案,因为我刚刚有一个顿悟。 – James 2011-05-10 16:31:35