ruby Подавление вывода команды с использованием метода «system» во время ее запуска в рубиновом скрипте



rails meta tags (7)

Если вы хотите использовать вариационную форму Kernel.system, которая ставит перед собой многие проблемы с кавычками с оболочками, вы можете использовать те же опции, которые принимает Kernel.spawn .

TL; DR - Use :out => File::NULL чтобы отключить вывод из Kernel.system

Аргументы со специальными символами (пробелы и т. Д.) Могут вызвать проблемы с оболочкой:

irb(main):001:0> filename_with_spaces = "foo bar.txt"
=> "foo bar.txt"

irb(main):002:0> system "ls -l #{filename_with_spaces}"
ls: bar.txt: No such file or directory
ls: foo: No such file or directory
=> false

Поэтому, если вы интерполируете переменные в системный вызов, безопаснее предоставить аргументы отдельно:

irb(main):003:0> system "ls", "-l", filename_with_spaces
-rw-r--r--  1 nobody  nobody  9 Feb  1 16:53 foo bar.txt
=> true

Но теперь у нас есть проблема, если мы хотим скрыть вывод.

irb(main):004:0> system "ls", "-l", filename_with_spaces, "> /dev/null"
ls: > /dev/null: No such file or directory
-rw-r--r--  1 nobody  nobody  9 Feb  1 16:53 foo bar.txt
=> false

Мы могли бы закрыть STDOUT, используя опцию: :out => :close :

irb(main):005:0> system "ls", "-l", filename_with_spaces, :out => :close
=> true

Однако это может вызвать проблемы с некоторыми командами, которые могут попытаться подключиться к STDOUT.

irb(main):006:0> system "echo", "hi there", :out => :close
echo: write: Bad file descriptor
=> false

Чтобы исправить это, мы можем вернуться к перенаправлению нашего вывода, используя File::NULL чтобы оставаться портативным:

irb(main):007:0> system "echo", "hi there", :out => File::NULL
=> true

Я не уверен, что это имеет смысл, но я думаю, есть ли способ подавить вывод, показанный для команды при запуске с использованием system метода в ruby? Я имею в виду, что он должен просто выводить true или false в STDOUT, а не вывод команды. Я думаю, что это может быть сделано только в том случае, если команда может работать тихо, а не из system метода. Может ли кто-нибудь дать немного больше понимания?


Answer #1

В качестве дополнения я несколько раз удивился, когда использовал backticks и увидел, что выходные «проскальзывают» мои переменные при запуске скриптов из командной строки.

Неизменно, проблема в том, что текст, который я вижу, на самом деле происходит из stderr а не из stdout . Поэтому, чтобы прервать этот текст в stdout, не забудьте добавить 2>&1 к команде, которую вы пытаетесь запустить.

Надеюсь, это полезно кому-то. Я просто потратил двадцать минут на повторное изучение этого урока :)


Answer #2

Вы также можете использовать backticks или% x


Answer #3
  • определить null_device , это dependent от операционной системы: окна 7 и более новые используют nul , а в системах * nix используется /dev/null
  • выполнить команду
  • перенаправить его стандартным и выводить ошибку на null_device
  • затем используйте код выхода или метод backtick, mentioned @mikej, чтобы определить выход

следующее:

 null_device = Gem.win_platform? ? "/nul" : "/dev/null"

 do method
   system "run command 1>#{null_device} 2>#{null_device} "
   p ($? == 0)
 end

Answer #4

Я тоже столкнулся с этим вопросом ...

Имейте в виду, что при вызовах system ruby команда UNIX, которую вы пытаетесь использовать, может предложить «тихую» опцию - аннулирование необходимости полного отключения вывода терминала!

Например:

system 'curl -s "your_params_here"'

Будет подавлять вывод, который обычно сопровождает завиток.


Answer #5

После вызова system код выхода находится в специальной переменной $? поэтому, если useradd возвращает разные значения, чтобы указать, был ли пользователь успешно добавлен (например, 0 для успеха), вы можете сделать следующее:

system('useradd xx > /dev/null')
if $? == 0
  puts 'added'
else
  puts 'failed'
end

где перенаправление на /dev/null будет подавлять выход.

Альтернативно, если вызываемая программа не использует свой код выхода для указания успеха или неудачи, вы можете использовать обратные вызовы и искать определенную подстроку в выходе, например

if `useradd xx`.include? 'success'
  puts 'it worked'
else
  puts 'failed to add user'
end

Answer #6

IO.popen

Это еще один хороший вариант:

IO.popen(['echo', 'a']) do |f|
  f.read == "a\n" or raise
end
$?.exitstatus == 0 or raise

Ничто не будет выводиться на ваш stdout.

http://www.ruby-doc.org/core-2.1.4/IO.html#method-c-popen





ruby