set alias in bash got "syntax error near unexpected token `('" - r

I want to run a shiny app in command line and it did well:
R -e "shiny::runApp('~/User/Appname',launch.browser=TRUE)"
But got error: syntax error near unexpected token `(' once I set an alias in .profile:
alias report="R -e "shiny::runApp('~/User/Appname',launch.browser=TRUE)""
Need your help here, I guess something wrong in the quotes?

Since you're using double quotes inside double quotes you need to escape the inner ones like this:
alias report="R -e \"shiny::runApp('~/User/Appname',launch.browser=TRUE)\""
However cleaner approach is to have a shell function instead and avoid all the escaping:
report() {
R -e "shiny::runApp('~/User/Appname',launch.browser=TRUE)"
}

Related

Avoid variable expansion in zsh

If I use the zsh shell and execute the following command I get
$zsh
$echo '$_GET["test"]'
preexec: bad math expression: operand expected at `"test"'
$echo '$_GET[]'
preexec: invalid subscript
In bash I get what I expect:
$bash
$echo '$_GET["test"]'
$_GET["test"]
I assume that zsh is trying to expand the $_GET variable. How can I avoid this? I always expected this to only happen within double quotes anyhow.
[update]
I found the following three lines in the .zshrc:
# Display last command interminal
echo -en "\e]2;Parrot Terminal\a"
preexec () { print -Pn "\e]0;$1 - Parrot Terminal\a" }
After commenting them out everything seems to work as expected.
What I understand is that preexec is executed after a command in the terminal has been submitted but before it is executed. The $1 is the command that one submitted.
I still do not understand the purpose of the two lines but is it because of the double quotes in the preexec print statement that the variables are expanded?
The combination of print -P together with the expansion of $1 is killing you. With this, you first get a "normal" expansion of $1, yielding something like "\e]0;echo '$_GET["test"]'...". Now -P causes print to do a prompt expansion on this string, which means that it has to expand $_GET["test"] as well. This causes the error.
I suggest to remove the -P, in particular since you don't have any characters in your string which would benefit from prompt expansion.

Check syntax of R script without running it

After making changes to a R script, is there a way to check its syntax by running a command, before running the R script itself?
Base R has parse which will parse a script without running it.
parse("myscript.R")
The codetools package, which comes with R, has checkUsage and checkUsagePackage to check single functions and packages respectively.
There is lint() from the lint package:
lintr::lint("tets.r")
#> tets.r:1:6: style: Place a space before left parenthesis, except in a function call.
#> is.na(((NA))
#> ^
#> tets.r:1:12: error: unexpected end of input
#> is.na(((NA))
#> ^
The tested file contains only this wrong code
is.na(((NA))
You can customise what lint() checks. By default, it is quite noisy about code style (which is the main reason I use it).
From within an R console/REPL session, you can use the builtin base's parse function:
$ R
> parse("hello.r")
expression(cat("Hello, World!\n"))
> parse("broken.r")
Error in parse("broken.r") : broken.r:2:0: unexpected end of input
1: cat("Hello, World!\n"
^
The parse function throws an error in case it fails to parse. A limitation here is that it will only detect parse errors, but not for example references to undefined functions.
Directly from the command line
You can also check parsing directly from the command line by using Rscript's -e option to call parse:
$ Rscript -e 'parse("hello.r")'
expression(cat("Hello, World!\n"))
$ Rscript -e 'parse("broken.r")'
Error in parse("broken.r") : broken.r:2:0: unexpected end of input
1: cat("Hello, World!\n"
^
Execution halted
A nice result of this is that Rscript returns successfully (no exit code) when the parse works and
it returns an error code when the parse fails. So you can use your shell's || and && operators as usual or other forms of error detection (set -e).
Custom parsing script
You can also create a custom script that wraps everything nicely:
#!/bin/bash
#
# Rparse: checks whether R scripts parse successfully
#
# usage: Rscript script.r
# usage: Rscript file1.r file2.r file3.r ...
set -e
for file in "$#"
do
Rscript -e "parse(\"$file\")"
done
Place the script in a folder pointed by your $PATH variable and use it to check your R files as follows:
$ Rparse hello.r broken.r
expression(cat("Hello, World!\n"))
Error in parse("broken.r") : broken.r:2:0: unexpected end of input
1: cat("Hello, World!\n"
^
Execution halted
Here I am using bash as a reference language but there's nothing impeding alternatives to be built for other shells including Windows' ".bat" files or even an R script!
(Other answers already address the question quite nicely, but I wanted to document some additional possibilities in a more complete answer.)

JQ filter file input under windows

I actually use jq (1.5) with Windows 10 to Format different json files. I tried today to move the filters to a filter file to cut the length of my cmd commands.
I copied the filter directly from the command with all Quotations but i received an Syntax error. I tried to remove the qotations or Change them to ' but i still receive the Syntax error:
jq: error: syntax error, unexpected IDENT, expecting $end (Windows cmd shell quoting issues?) at <top-level>, line 1:
[.cruises[] | { nid: .cruise_nid, shipcategory: .ship_category, ship: .ship_title, company: .company_title, includeflight: .includes_flight, nights, waypoints: .waypoint_cities, title: .route_title}] C:\import\dreamlines_cruises.json > C:\Import\import_cruises.json
Any tips?
Regards Timo
Your jq filter as given (i.e. without quotation marks) looks fine, so let's assume you have successfully placed the text (hopefully formatted for readability :-) in a file, say format.jq
Then you would run something like this:
jq -f format.jq dreamlines_cruises.json

Have an Rscript read or take input from stdin

I see how to have an Rscript perform the operations I want when given a filename as an argument, e.g. if my Rscript is called script and contains:
#!/usr/bin/Rscript
path <- commandArgs()[1]
writeLines(readLines(path))
Then I can run from the bash command line:
Rscript script filename.Rmd --args dev='svg'
and successfully get the contents of filename.Rmd echoed back out to me. If instead of passing the above argument a filename like filename.Rmd I want to pass it text from stdin, I try modifying my script to read from stdin:
#!/usr/bin/Rscript
writeLines(file("stdin"))
but I do not know how to construct the commandline call for this case. I tried piping in the contents:
cat filename.Rmd | Rscript script --args dev='svg'
and also tried redirect:
Rscript script --args dev='svg' < filename.Rmd
and either way I get the error:
Error in writeLines(file("stdin")) : invalid 'text' argument
(I've also tried open(file("stdin"))). I'm not sure if I'm constructing the Rscript incorrectly, or the commandline argument incorrectly, or both.
You need to read text from the connection created by file("stdin") in order to pass anything useful to the text argument of writeLines(). This should work
#!/usr/bin/Rscript
writeLines(readLines(file("stdin")))

Rscript and Backticks

I need to run knit2html on the command line using Rscript. I tried the following code and it works
Rscript -e "(knitr::knit2html(text = '## good', fragment.only = TRUE))"
However, when I introduce R code chunks (or anything involving backticks), the process hangs. So the following does NOT work
Rscript -e "(knitr::knit2html(text = '## good\n `r 1 + 1`',fragment.only = T))"
For the purpose of my use, I only have access to the contents and hence can NOT pass a file to knit2html, which I know will work.
My question is how do I make this work. I know the problem is the backticks and I have tried looking at escaping them, but nothing seems to be working.
it is a shell issue.
On windows it works.
On linux You need to escape the backtick like \'
I think the reason , some shell interprets the double-quoted string once.
A related issue has been reported once here. You have to use single quotes to avoid shell expansion. I'm not sure if that applies to Windows as well, though.

Resources