I'm new to Ubuntu and would like to run a daily crontab. I'm running similar job under Windows Command Line but would like to switch to Ubuntu.
My R-Script has an Error-function which prints errors into a separate
folder everytime a job is done and an error has occured ():
# define error function
my.error.fun <- function() {
cat(geterrmessage(), file="/home/network/R/Test.txt", append=TRUE)
}
# output error
options("error"=my.error.fun)
Under crontab -e I have determined the following:
00 16 * * * /usr/bin/Rscript /home/R/network/Test.R 2> /home/R/RErrors/Test.txt
and the crontabhas been saved under /tmp/crontab.2t/crontab
where I append the errros inside the R-Script. In contrast to Windows Command Line that concept seems not to work in Ubuntu That seems not to work however. I'm not sure whether thats the correct syntax. There has been no file in the RErrors folder.
May I as for some suggestions?
Related
I have a '.js' script that I usually activate from the terminal using the command node script.js. As this is part of a process where I first do some data analysis in R, I want to avoid the manual step of opening the terminal and typing the command by simply having R do it for me. My goal would be something like this:
...R analysis
write.csv(df, "data.csv")
system('node script.js')
However, when I use that specific code, I get the error:
sh: 1: node: not found
Warning message:
In system("node script.js") : error in running command
Of course, the same command runs without problem if I type it directly on the terminal.
About my Software
I am using:
Linux computer with the PopOS!
RStudio 2021.09.1+372 "Ghost Orchid"
R version 4.0.4.
The error message node: not found indicates that it couldn't find the program node. It's likely in PATH in your terminal's shell, but not in system()'s shell (sh).
In your terminal, locate node by executing which node. This will show the full path to the executable. Use that full path in system() instead.
Alternatively, run echo $PATH in your terminal, and run system('echo $PATH') or Sys.getenv('PATH') in R. Add any missing directories to R's path with Sys.setenv(PATH = <your new path string>)
Note that system2() is recommended over system() nowadays - but for reasons unimportant for your case. See ?system and ?system2 for a comparison.
Examples
Terminal
$ which node
/usr/bin/node
R
system('/usr/bin/node script.js')
# alternatively:
system2('/usr/bin/node', c('script.js'))
or adapt your PATH permanently:
Terminal
% echo $PATH
/usr/local/bin:/home/caspar/programs:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
R
> Sys.getenv('PATH')
[1] "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/Applications/RStudio.app/Contents/MacOS/postback"
> Sys.setenv(PATH = "/home/caspar/programs:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/Applications/RStudio.app/Contents/MacOS/postback")
When you install Git on windows, it adds a context menu option when you right-click on a folder to "Git Bash Here". The way it does this is by adding a registry key like this:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\git_shell\command]
#="\"C:\\Program Files\\Git\\git-bash.exe\" \"--cd=%1\""
Notice the cd argument at the end that passes the directory name to the program.
I would like to do something similar for R (and other programs). Unfortunately R doesn't accept a cd argument. This will launch R:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\R\command]
#="\"C:\\Program Files\\R\\R-3.4.3\\bin\\x64\\Rgui.exe\" \"--cd=%1\""
but it gives an error message saying the cd argument is not recognized, and Rgui will start with whatever the default working directory is, defeating the entire point.
What I really want it to do is the equivalent of this command:
start "R" /D %1 "C:\Program Files\R\R-3.4.3\bin\x64\Rgui.exe"
where %1 is the folder that was right-clicked on. Is this possible?
You can write R code that runs on startup and checks the commandline arguments.
You can put the following code at the end of C:\Program Files\R\R-3.4.3\etc\Rprofile.site (or any other file that gets executed at startup):
local({
processArg <- function(arg) {
parts <- strsplit(arg, "=")[[1]]
if (length(parts) == 2) {
if (parts[1] == "R_startup_wd") {
setwd(parts[2])
}
}
}
invisible(sapply(commandArgs(FALSE), processArg))
})
It checks if R was called with an argument R_startup_wd=your_working_dir and changes the working directory if yes.
You can then call R like
"C:\Program Files\R\R-3.4.3\bin\x64\Rgui.exe" "R_startup_wd=your_working_dir"
Note that the argument name is given without "--", i.e. we have R_startup_wd and not --R_startup_wd. Otherwise RGui will complain about "unknown arguments"
You can of course still use R without the argument given.
I would like to set up a crontab that runs the emailSender.R script daily at 5pm Monday to Friday.
The script of emailSender.R is as follows:
library(rmarkdown)
rmarkdown::render("htmlmarkdown.Rmd")
library(gmailR)
gmailR::gmail(
to =c("recipient#email.com"),
subject = "Subject",
message = "Message",
username = "me#email.com",
password = "password",
attachment = "htmlmarkdown.html"
)
I then open up terminal to set up the crontab by first typing crontab -e.
Then a window pops up where I try to set up my cronjob using the following code.
0 17 * * * Rscript /Users/username/emailSender.R
Unfortunately, emailSender.R doesn't run as scheduled.
Would greatly appreciate any help on getting a crontab to schedule my R script
EDIT: After going back to my terminal and typing Rscript I am prompted:
-bash: Rscript: command not found
Perhaps I have to set Rscript in my PATH before cron can set-up the task. Unsure how to do that despite searching extensively.
Try installing the cronR package.
Once you do this, you should be able to navigate to tools > Addins where you can execute the package. It will bring up a scheduler that will allow you to schedule a time for your script to run.
If you have permission issues, go to System preferences > security > Privacy. Click the 'full disk access' and grant RStudio / R access. This should allow you to schedule jobs to run in the future.
You need to include the path of Rscript:
0 17 * * * /usr/local/bin/Rscript /Users/username/emailSender.R
Add this code at the beggining:
Sys.setenv(RSTUDIO_PANDOC="/usr/lib/rstudio-server/bin/pandoc")
I am new to programming and mainly I am able to do some scripts within R, but for my work I need to call an external program. For this program to work on the ubuntu's terminal I have to first use setenv and then execute the program. Googling I've found the system () and Sys.setenv() functions, but unfortunately I can make it function.
This is the code that does work in the ubuntu terminal:
$ export PATH=/home/meme/bin:$PATH
$ mast "/home/meme/meme.txt" "/home/meme/seqs.txt" -o "/home/meme/output" -comp
Where the first two arguments are input files, the -o argument is the output directory and the -comp is another parameter for the program to run.
The reason that I need to do it in R despite it already works in the terminal is because I need to run the program 1000 times with 1000 different files so I want to make a for loop where the input name changes in every loop and then analyze every output in R.
I have already tried to use:
Sys.setenv(PATH="/home/meme/bin"); system(mast "/home/meme/meme.txt" "/home/meme/seqs.txt" -o "/home/meme/output" -comp )
and
system(Sys.setenv(PATH="/home/meme/bin") && mast "/home/meme/meme.txt" "/home/meme/seqs.txt" -o "/home/meme/output" -comp )
but always received:
Error: unexpected constant string in "system(mast "/home/meme/meme.txt""
or
Error: unexpected symbol in "system(Sys.setenv(PATH="/home/meme/bin") && mast "/home/meme/meme.txt""
At this point I have run out of ideas to make this work. If this has already been answered, then my googling have just been poor and I would appreciate any links to its response.
Thank you very much for your time.
Carlos
Additional details:
I use Ubuntu 12.04 64-bits version, RStudio version 0.97.551, R version 3.0.2 (2013-09-25) -- "Frisbee Sailing" Platform: x86_64-pc-linux-gnu (64-bit).
The program I use (MAST) finds a sequence pattern in a list of letters and is part of the MEME SUIT version 4.9.1 found in http://meme.nbcr.net/meme/doc/meme-install.html and run through command line. The command-line usage for mast is:
mast <motif file> <sequence file> [options]
Construct the string you want to execute with paste and feed that to system:
for(i in 1:10){
cmd=paste("export FOO=",i," ; echo \"$FOO\" ",sep='')
system(cmd)
}
Note the use of sep='' to stop paste putting spaces in, and back-quoting quote marks in the string to preserve them.
Test before running by using print(cmd) instead of system(cmd) to make sure you are getting the right command built. Maybe do:
if(TESTING){print(cmd)}else{system(cmd)}
and set TESTING=TRUE or FALSE in R before running.
If you are going to be running more than one shell command per system call, it might be better to put them all in one shell script file and call that instead, passing parameters from R. Something like:
cmd = paste("/home/me/bin/dojob.sh ",i,i+1)
system(cmd)
and then dojob.sh is a shell script that parses the args. You'll need to learn a bit more shell scripting.
I have used R in the past to do very basic calls to the commmand line. The example can be found here.
This time around, I am looking to mimic this code which runs successfully from the command line in Windows:
> cd C:\Documents and Settings\BTIBERT\My Documents\My Dropbox\Eclipse\Projects\R\MLB\retrosheet\rawdata
> bgame -y 2010 2010bos.eva >2010bos.txt
This is the code I am trying to run inside of R. I have already set the working directory inside of R.
dir <- paste("cd", getwd(), sep=" ")
system(dir)
system("bgame -y 2010 2010bos.eva >2010bos.txt")
I am sure this is user error, but what am I doing wrong? It appears to work initially, but returns the following error. I very well could be doing something wrong, but I believe I am using the same commands.
Expanded game descriptor, version 109(185) of 05/08/2008.
Type 'bgame -h' for help.
Copyright (c) 2001 by DiamondWare.
[Processing file 2010bos.eva.]
>2010bos.txt: can't open.
Warning message:
running command 'bgame -y 2010 2010bos.eva >2010bos.txt' had status 2
Any help you can provide will be appreciated.
You need to issue all commands in one system() call:
system(paste("cd",getwd() "&& bgame -y 2010 2010bos.eva >2010bos.txt",sep=" "))
You should already be in your working directory, so I'm not sure the cd getwd() is necessary. And you may need quotes around your path because it contains spaces. The error may be resolved by putting spaces around >.
If I were in your shoes, I would try this:
system("bgame -y 2010 2010bos.eva > 2010bos.txt")
UPDATE:
And you should probably heed this advice in the "Differences between Unix and Windows" section of ?system that says you should use shell:
• The most important difference is that on a Unix-alike
‘system’ launches a shell which then runs ‘command’. On
Windows the command is run directly - use ‘shell’ for an
interface which runs ‘command’ _via_ a shell (by default the
Windows shell ‘cmd.exe’, which has many differences from the
POSIX shell).
This means that it cannot be assumed that redirection or
piping will work in ‘system’ (redirection sometimes does, but
we have seen cases where it stopped working after a Windows
security patch), and ‘system2’ (or ‘shell’) must be used on
Windows.
Has no-one else found that system("dir", intern = T) for example doesn't work, but that you need system("cmd.exe /c dir", intern = T)? Only the latter works for me. I found this at the discussion site here (William Dunlap's post, about a third of the way down).
Also, it doesn't work with the "cd" command, but you can use the setwd() function within R and then the command will be executed within that directory.
I created the following functions for convenience, for executing programmes and running commands:
#the subject is an input file that a programme might require
execute <- function(programme, subject.spec = "", intern = FALSE, wait = FALSE){
if(!identical(subject.spec, "")){subject.spec <- paste0(" ", subject.spec)} #put space before the subject if it exists
system(paste0("cmd.exe /c ", programme, subject.spec), intern = intern, wait = wait)
}
command <- function(command, intern = TRUE, wait = FALSE){
system(paste("cmd.exe /c", command), intern = T, wait = wait)
}
Does it break your code when you get error 1 or does execution continue?
Whenever executing system commands through another language it is useful to print the system call before you call it to see exactly what is happening, pull up the shell you are intending to use and check for the same error. As the command is executed correctly this could be a hickup in bgame or R.
If you look at http://astrostatistics.psu.edu/datasets/R/html/base/html/shell.html you can see the variable flag passed to the system call."flag the switch to run a command under the shell. If the shell is bash or tcsh the default is changed to "-c"."
Also "the shell to be used can be changed by setting the configure variable R_SHELL to a suitable value (a full path to a shell, e.g. /usr/local/bin/bash)."