Я не уверен, что это имеет смысл, но я думаю, есть ли способ подавить вывод, показанный для команды при запуске с использованием метода system
в ruby? Я имею в виду, что он должен просто выводить true или false в STDOUT, а не вывод команды. Я думаю, что это может быть сделано только в том случае, если команда может работать без звука, а не из метода system
. Может ли кто-нибудь дать немного больше информации?
Подавление вывода команды с использованием метода "system" во время ее запуска в рубине script
Ответ 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
к команде, которую вы пытаетесь запустить.
Я надеюсь, что кому-то это поможет. Я просто потратил двадцать минут на повторное изучение этого урока:)
Ответ 4
IO.popen
Это еще один хороший вариант:
IO.popen(['echo', 'a']) do |f|
f.read == "a\n" or raise
end
$?.exitstatus == 0 or raise
Ничего не выйдет на ваш stdout.
Ответ 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'