Reputation: 631
I have a bash script that i'm running using shiny and system
. It takes a long time to run so I'd like to provide feedback to the user about progress. In the bash script I have messages that periodically updates the user and I'm trying to find a way to have them printed in the UI.
Here is a minimal working example for which I'd like to have "Output 1" and "Output 2" returned to the user as they appear in the console.
Any help is greatly appreciated.
library(shiny)
ui <- fluidPage(
actionButton("run", "Print to Console")
)
server <- function(input, output, session) {
observeEvent(input$run,{
system(c("echo output 1; sleep 2; echo output 2"))
})
}
shinyApp(ui, server)
Upvotes: 3
Views: 485
Reputation: 33580
I'd suggest to run your system
command asynchronously and redirect the output to a log file. In parallel you can continuously read in the logfile via reactiveFileReader
.
In contrast, when intern = TRUE
the R session (and shiny) is blocked while the command is executed.
Please check the following:
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)
PS: As an alternative you might want to check AsyncProgress
from library(ipc).
Upvotes: 2