Hey Sam,
Regarding your initial question
How does one show stdout of an external program?
please check my answer here.
I'll repost the code:
library(shiny)
file.create("commands.sh", "output.log")
Sys.chmod("commands.sh", mode = "0777", use_umask = TRUE)
writeLines(c("#!/bin/bash", "echo output 1","sleep 2", "echo output 2"), con = "commands.sh")
ui <- fluidPage(
actionButton("run_intern", "Run intern"),
textOutput("myInternTextOutput"),
hr(),
actionButton("run_extern", "Run extern"),
textOutput("myExternTextOutput")
)
server <- function(input, output, session) {
systemOutputIntern <- eventReactive(input$run_intern,{
system(command = "echo output 1; sleep 2; echo output 2", intern = TRUE)
})
output$myInternTextOutput <- renderText(systemOutputIntern())
observeEvent(input$run_extern,{
system(command = "./commands.sh 2>&1 | tee output.log", intern = FALSE, wait = FALSE)
})
log <- reactiveFileReader(200, session, filePath = "output.log", readLines)
output$myExternTextOutput <- renderText(log())
}
shinyApp(ui, server)
The stdout can also be passed to R using processx::process
via the stdout = ""
argument (see ?process
) as already shown in my answer to your SO post.
In my opinion hosting a second shiny app to display a log in an iframe is to use a sledge-hammer to crack a nut and in the end it also means running the external process asynchronously (+ wasting resources).
The above approach is using reactiveFilereader
to do the same, when running the shell script asynchronously (as mentioned in your 1st post). In my eyes this is a reasonable approach.
PS: check shinyAce to display the reactive log.
Cheers