Search code examples
rmacosfunctionpingstderr

Hiding output of function that calls system command


Background

I'm looking at using pingr::ping function on macOS to ping certain destinations. I want to hide pingr::ping outputs in case of a malformatted destination.

Notes

  • The pingr::ping actually makes use of pingr::ping_os function to assemble command and system command to execute ping. On macOS, malformatted destination returns in ping returning a message about wrongly formatted command. I want to hide that message from being printed to console.

Example

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

Output to hide

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

Desired results

No system output is printed in case of a malformatted destination.

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

Attempts

sink()

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

Unwanted console output appears.

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

Unwanted console output appears.

>> 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

Solution

  • I can't find a way to divert the system messages if they are created. They don't seem to come from R's message stream.

    The best solution I can find is modifying ping:

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