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

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

Ответ 1

После вызова 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

Ответ 2

Если вы хотите использовать вариационную форму 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

Ответ 3

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

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

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

Ответ 5

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

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

Например:

system 'curl -s "your_params_here"'

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

Ответ 6

  • define null_device, это операционные системы зависимые: окна 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

Ответ 7

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

Ответ 8

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

system ls, STDOUT:'/dev/null'