Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-Line Rscript in Dockerfile

I am trying to build a docker image with R, and I'd like to be able to break out my package install steps in a clean, easy to read, manner across multiple lines, but bash does not seem to like the approach due to not knowing where the ending ) is.

Is there a way to make this long line of code split across multiple lines?

Rscript -e 'devtools::install_cran(c("tidytext","janitor","corrr","officer","devtools","pacman"))'

To maybe, something like this:

Rscript -e 'devtools::install_cran(c("tidytext","janitor",
                              "corrr","officer","devtools","pacman"))'

Is this possible to do with Rscript? I have tried using a \ at the end of each line, and it still does not work.

I understand install2.r can list out the packages line by line, but I would like to have a vector of packages to pass to devtools::install_cran if possible. I have seen others simply refer to their R script by simply calling it via Rscript, but I would like to see all my installation steps inside my Dockerfile, and not copy and run an external R script in my container. Thanks for your help.

Rscript test.R
like image 416
petergensler Avatar asked Jan 29 '23 06:01

petergensler


2 Answers

BASH will interpret a newline as the end of the command.

In BASH (which I'm assuming you're using), a backslash followed by a newline is interpreted as a continuation of the line. Except when it is inside single quotes!

So...

Rscript -e 'devtools::install_cran(c("tidytext","janitor",
                          "corrr","officer","devtools","pacman"))'

will be interpreted as two commands...

Rscript -e 'devtools::install_cran(c("tidytext","janitor",

and

"corrr","officer","devtools","pacman"))'

Neither of which are well formed.

Additionally, single quoted strings in BASH will not handle escapes. They simply assume your text is literal. So you cannot continue a line within single quoted strings in BASH.

The bottom line is that if you want continuation within a quoted string in BASH, you must use double quoted strings. Your options are as follows:

Rscript -e "devtools::install_cran(c('tidytext','janitor', \  
                'corrr','officer','devtools','pacman'))"

using double quotes in BASH and single quotes in R or...

Rscript -e "devtools::install_cran(c(\"tidytext\",\"janitor\", \    
                \"corrr\",\"officer\",\"devtools\",\"pacman\"))"

using double quotes in both.

like image 83
dcdillon Avatar answered Jan 31 '23 19:01

dcdillon


There are quite a few reference Docker files you could look at. Here is a part from one of ours from the Rocker Project producing the official r-base image:

RUN apt-get update \     
        && apt-get install -y --no-install-recommends \     
                ed \                                 
                less \   
                locales \     
                vim-tiny \   
                wget \  
                ca-certificates \
                fonts-texgyre \ 
        && rm -rf /var/lib/apt/lists/* 

Now this is for apt packages but R packages from CRAN work in the same way: one long line, broken up by backslashes. We tend to use install.r or install2.r from littler for this. So your code would become

install.r tidytext \
   janitor \
   corrr \
   officer \
   devtools \
   pacman 

An under-appreciated aspect is that you can in fact get some of these as binaries from either Debian or Ubuntu, but I leave the legwork of finding this out for yourself.

like image 42
Dirk Eddelbuettel Avatar answered Jan 31 '23 21:01

Dirk Eddelbuettel