0

SAMPLE FROM RSTUDIO

Start a command with results displayed in a terminal buffer

termId <- rstudioapi::terminalExecute("ping rstudio.com")

If viewing the result in the terminal buffer is sufficient, then no need to do anything else. The command will continue running and displaying its results without blocking the R session.

To obtain the results programmatically, wait for it to finish.

while (is.null(rstudioapi::terminalExitCode(termId))) {
  Sys.sleep(0.1)
}

result <- rstudioapi::terminalBuffer(termId)

Delete the buffer and close the session in the IDE

rstudioapi::terminalKill(termId)

My goal is to 'PING' multiple website for examples:

c = c("google.com","bing.com","rstudio.com")

I want to put this in the sleep loop so the code that comes after ping does not get run yet until the ping process finishes. I want to print that every ping process is complete once it is and then a final message when all the pings are done and then last to clear and close all terminal windows.

bvowe
  • 3,004
  • 3
  • 16
  • 33
  • 2
    I'm a little confused: most of the "question" looks like instructions from homework or a tutorial, and then you ask about how to `ping` multiple websites. What function are you using to even try to ping one host? (BTW: it's not good practice to name a variable `c`; even though R will typically do the right thing, (1) if you forget to name it in follow-on scripts, errors are *really* confusing; (2) it's difficult for those more familiar with R to look at your code and instantly know what you're doing. (This is compounded by `c = c(...)`.) – r2evans Mar 30 '19 at 21:07
  • This I copy from tutorial but I try to modify this with no success. I want to execute multiple "pings" but while doing that not run any commands that come after and also print when each one finish. – bvowe Mar 30 '19 at 21:10
  • Is there a reason you are using the RStudio API instead of `system2` or perhaps the `processx::` package? (I can't really help, I don't use RStudio regularly, and most of the `rstudioapi::` functions do not work outside of their IDE.) – r2evans Mar 30 '19 at 21:19
  • Perhaps if you just want to do a check-ping (*"one ping only"*), you should look into options to `ping` that restrict the number of packets sent and the timeout to call pass/fail. These arguments depend on your OS, so having that would help. – r2evans Mar 30 '19 at 21:26
  • if i run lots of process then I have 80+ terminal windows open. how I can close them all with one command? i currently close all the boxes and it takes much time. – bvowe Apr 01 '19 at 15:01
  • The need for an R `ping` function is not new to SO. I've extended it with my answer, but it's just another function. – r2evans Apr 01 '19 at 16:15

1 Answers1

0

I'll bite. Here's a quick function and use of it:

ping <- function(hosts, count = 1, timeout = 1, all. = FALSE) {
  GOOD <- TRUE
  if (R.version$os == "mingw32") {
    countopt <- "-n"
    timeoutopt <- "-w"
    timeout <- timeout * 1000 # milliseconds
  } else {
    countopt <- "-c"
    timeoutopt <- "-w"
  }
  success <- fail <- character(0)
  for (host in hosts) {
    out <- suppressWarnings(
      system2("ping", c(countopt, count, timeoutopt, as.character(timeout), shQuote(host)),
              stdout = FALSE, stderr = FALSE)
    )
    if (out == 0) {
      success <- c(success, host)
    } else {
      fail <- c(fail, host)
      GOOD <- FALSE
      if (!all.) break
    }
  }
  attr(GOOD, "ping_success") <- success
  attr(GOOD, "ping_fail") <- fail
  GOOD
}

The default behavior is to ping each in turn, and return TRUE only if all succeeded. This stops and returns on the first fail:

ping(c("google.com", "bing.com", "rstudio.com"))
# [1] TRUE
# attr(,"ping_success")
# [1] "google.com"  "bing.com"    "rstudio.com"
# attr(,"ping_fail")
# character(0)

By default, it stops after the first fail and includes its progress (in the attributes):

ping(c("google.com", "quux.not", "rstudio.com"))
# [1] FALSE
# attr(,"ping_success")
# [1] "google.com"
# attr(,"ping_fail")
# [1] "quux.not"

If you need to know which are good regardless of the fails, then

ping(c("google.com", "quux.not", "rstudio.com"), all. = TRUE)
# [1] FALSE
# attr(,"ping_success")
# [1] "google.com"  "rstudio.com"
# attr(,"ping_fail")
# [1] "quux.not"

Because it reports its happiness/sadness as attributes, you should always be able to rely on a singular logical value and, if needed, dive deeper into what worked or didn't work.

r2evans
  • 141,215
  • 6
  • 77
  • 149