隐藏调用系统命令的函数的输出

Hiding output of function that calls system command

背景

我正在考虑使用 pingr::ping function on macOS to ping certain destinations. I want to hide pingr::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

这可能会增加您的问题,但这里有一个方法可以避免这个问题:

> 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() 可能需要很长时间才能失败,因此可能首先过滤明显的不良主机。

如果创建了系统消息,我找不到转移系统消息的方法。它们似乎不是来自 R 的消息流。

我能找到的最佳解决方案是修改 ping:

hide_ping_output <- function(...) {
  f <- pingr::ping
  body(f)[[4]] <- quote(output <- suppressWarnings(system(os$cmd, 
                          intern = !verbose, ignore.stderr = TRUE)))
  f(...)
}