ruby script.rb по сравнению с xterm -e ruby ​​script.rb

У меня возникла странная проблема с Ruby, которую я не могу объяснить. У меня есть следующий скрипт, который захватывает любой код, который в данный момент находится в буфере обмена, запускает его через подсветку синтаксиса, а затем помещает новую версию НАЗАД в буфер обмена:

#!/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 возвращал объект ввода-вывода, и я мог вручную вызывать close, но это не имеет значения.


person Matthew    schedule 06.10.2010    source источник
comment
Я определил, что проблема в xsel. Я попытался добавить строку в конец файла (без сумасшедшего цикла puts), которая просто выгружает выделенный код в файл, и его содержимое верно независимо от того, как я запускаю скрипт. Вместо этого я попробовал xclip, и, похоже, он работает в большем количестве ситуаций, хотя я когда-либо получал только основной (также известный как средний щелчок) буфер обмена для работы с ним. xclip работает при вызове из другого скрипта, где xsel не работает, но xclip по-прежнему не работает и через xterm -e.   -  person Matthew    schedule 23.02.2011


Ответы (1)


Как насчет того, чтобы выполнить его с помощью gnome-terminal -e вместо xterm -e?

ОБНОВЛЕНИЕ:

Хорошо, вот мое лучшее предположение. Вы знаете, как если вы отправляете терминальную программу в фоновый режим (либо с помощью & после команды, либо с помощью ctl-z), а затем закрываете терминал, это убивает программу, верно? Что ж, xsel разветвляет дочерний процесс для записи в буфер обмена, но он должен быть убит, когда сценарий ruby-оболочки завершится и xterm закроется.

Это объясняет, почему пауза в конце позволяет ему работать — она просто дает достаточно времени для завершения дочернего процесса до закрытия терминала. Это также объясняет, почему он работает при ручном запуске — вы оставляете терминал открытым достаточно долго, чтобы дочерний процесс завершился.

Попробуйте добавить параметр -n в свою команду xsel, и я уверен, что это сработает. -n удерживает xsel от разветвления.

person James    schedule 07.05.2011
comment
Нет, похоже, это тоже не работает... с xclip или с xsel. Впрочем, спасибо. Я редко использую этот скрипт, так что это не так уж важно, но было бы неплохо узнать, почему он делает это просто ради знания. - person Matthew; 09.05.2011
comment
ах, черт. Я подумал, что, возможно, это была проблема с эмулятором терминала, и возможно вы открывали gnome-terminal при запуске вручную. - person James; 10.05.2011
comment
Прости, что мне потребовалось так много времени, чтобы принять это. Я давно не использовал сценарий, поэтому заметил, что вы обновили свой ответ. Я не могу продублировать это сейчас (разные версии всего, верно?), поэтому я продолжу и приму, поскольку ваш ответ имеет действительное объяснение поведения. - person Matthew; 31.01.2012
comment
ах, теперь я хотел бы знать наверняка, прав я или нет. О, спасибо за прием! - person James; 02.03.2012
comment
Я точно знаю? Извини за это. Тем не менее, я очень ценю вашу помощь. - person Matthew; 02.03.2012