Подавление вывода команды, запущенной с использованием системного метода, при запуске ее в сценарии ruby - PullRequest
29 голосов
/ 25 декабря 2009

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

Ответы [ 8 ]

41 голосов
/ 02 февраля 2016

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

TL; DR - используйте :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
23 голосов
/ 25 декабря 2009

После вызова 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
7 голосов
/ 16 апреля 2011

Как дополнение, я несколько раз удивлялся, когда использовал обратные пометки и видел, как вывод «проскальзывал» через мои переменные при запуске сценариев из командной строки.

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

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

1 голос
/ 13 июля 2015

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

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

Например:

system 'curl -s "your_params_here"'

Подавит вывод, который обычно сопровождает вызов curl.

1 голос

IO.popen

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

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

Ничто не получит вывод на ваш стандартный вывод.

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

0 голосов
/ 26 января 2017
  • определяют null_device, его операционные системы зависят : windows 7 и новее используют nul, в то время как * nix систем использует /dev/null
  • запустить команду
  • перенаправить его стандарт и вывод ошибок на null_device
  • затем используйте код завершения или метод обратного ключа, как , упомянутый @mikej, чтобы определить вывод

следующим образом:

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

 do method
   system "run command 1>#{null_device} 2>#{null_device} "
   p ($? == 0)
 end
0 голосов
/ 08 апреля 2015

Это должно работать

system ls, STDOUT:'/dev/null'
0 голосов
/ 25 декабря 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...