Скрытие вывода функции, которая вызывает системную команду - PullRequest
3 голосов
/ 25 марта 2019

Фон

Я рассматриваю использование функции pingr::ping в macOS для проверки связи с определенными получателями. Я хочу скрыть pingr::ping выходных данных в случае неправильного назначения.

Примечания

  • pingr::ping фактически использует функцию pingr::ping_os для сборки команды и команду system для выполнения команды ping. В macOS неправильно отформатированный пункт назначения возвращается в ping, возвращая сообщение о неправильно отформатированной команде Я хочу скрыть это сообщение от его печати на консоли.

Пример

hide_ping_output(destination = "www.google.com") -> a
hide_ping_output(destination = "wrong destination") -> b

Выход для скрытия

usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize]
            [-g sweepminsize] [-h sweepincrsize] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern]
            [-S src_addr] [-s packetsize] [-t timeout][-W waittime]
            [-z tos] host
       ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern] [-S src_addr]
            [-s packetsize] [-T ttl] [-t timeout] [-W waittime]
            [-z tos] mcast-group
Apple specific options (to be specified before mcast-group or host like all options)
            -b boundif           # bind the socket to the interface
            -k traffic_class     # set traffic class socket option
            -K net_service_type  # set traffic class socket options
            -apple-connect       # call connect(2) in the socket
            -apple-time          # display current time
[1] NA NA NA

Желаемые результаты

Системный вывод не печатается в случае неправильного назначения.

hide_ping_output(destination = "www.google.com")
hide_ping_output(destination = "wrong destination")
a; b
[1] 190.027  36.846  35.243
[1] NA NA NA

Попытка

sink()

hide_ping_output_sink <- function(...) {
     sink(tempfile())
     pingr::ping(...)
     sink(NULL)
}
hide_ping_output_sink(destination = "wrong destination") -> b

Появляется нежелательный консольный вывод.

usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize]
            [-g sweepminsize] [-h sweepincrsize] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern]
            [-S src_addr] [-s packetsize] [-t timeout][-W waittime]
            [-z tos] host
       ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern] [-S src_addr]
            [-s packetsize] [-T ttl] [-t timeout] [-W waittime]
            [-z tos] mcast-group
Apple specific options (to be specified before mcast-group or host like all options)
            -b boundif           # bind the socket to the interface
            -k traffic_class     # set traffic class socket option
            -K net_service_type  # set traffic class socket options
            -apple-connect       # call connect(2) in the socket
            -apple-time          # display current time

capture.output / invisible

hide_ping_output_capture <- function(...) {
    capture.output(invisible(pingr::ping(...) ->> b))
    b
}
hide_ping_output_capture(destination = "wrong destination") -> b

Появляется нежелательный вывод на консоль.

>> hide_ping_output_capture(destination = "wrong destination") -> b
usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize]
            [-g sweepminsize] [-h sweepincrsize] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern]
            [-S src_addr] [-s packetsize] [-t timeout][-W waittime]
            [-z tos] host
       ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait]
            [-l preload] [-M mask | time] [-m ttl] [-p pattern] [-S src_addr]
            [-s packetsize] [-T ttl] [-t timeout] [-W waittime]
            [-z tos] mcast-group
Apple specific options (to be specified before mcast-group or host like all options)
            -b boundif           # bind the socket to the interface
            -k traffic_class     # set traffic class socket option
            -K net_service_type  # set traffic class socket options
            -apple-connect       # call connect(2) in the socket
            -apple-time          # display current time

Ответы [ 2 ]

1 голос
/ 31 марта 2019

Я не могу найти способ переадресации системных сообщений, если они созданы.Кажется, они не приходят из потока сообщений R.

Лучшее решение, которое я могу найти, - это изменение ping:

hide_ping_output <- function(...) {
  f <- pingr::ping
  body(f)[[4]] <- quote(output <- suppressWarnings(system(os$cmd, 
                          intern = !verbose, ignore.stderr = TRUE)))
  f(...)
}
1 голос
/ 25 марта 2019

Это может добавить к вашим проблемам, но вот способ обойти проблему:

> library(iptools)
> library(pingr)

> hn <- "www.google.com"
> if (hostname_to_ip(hn) != "Not resolved") { ping(hn) }
[1] 617.094 610.771 610.603
> hn <- "foo bar"
> if (hostname_to_ip(hn) != "Not resolved") { ping(hn) }
>

hostname_to_ip() может потребоваться много времени для сбоя, поэтому, возможно, сначала отфильтруйте очевидные плохие хосты.

...