Run Rscript.exe on batch file with optional arguments - r

I run a Windows batchfile (.bat)
path_to_Rscript.exe file.R parameter1 parameter2 parameter3
on a file called file.R
In file.R, I read the arguments using
commandArgs(trailingOnly = TRUE)
ABC <- args[1]
DEF <- args[2]
GHI <- args[3]
In case there is no parameter2, calling only
path_to_Rscript.exe file.R parameter1 parameter3
how can I make sure that parameter3 is not assigned to DEF?
So far, I used %% as a placeholder, but I am not sure whether this is a common approach.
Is there a general placeholder for empty parameters?

There is no general "no arg" placeholder, it depends on the progam.
The answer is that you can't make sure p3 is not assigned to DEF without some assumptions, i.e., if you only have two arguments then they are always going to be ABC and GHI. In that case, you check for the length of commandArgs and adjust accordingly - that is a very narrow solution.
If you want to use optional positional arguments (which is generally a bad idea), they'd have to be at the end and then you really only get one for the same reason your facing now.
The best way out of this conundrum is to use docopt. If you can't use docopt, then your stuck implementing pieces of a command-line parser which is a generally solved problem.

Related

robotframework - get all the variables/arguments passed to an execution

Is there a way to access all the variables/arguments passed through the command line or variable file (-V option) during robotframework execution. I know in python the execution can access it with 'sys.args' feature.
The answer for getting the CLI arguments is inside your question - just look at the content of the sys.argv, you'll see everything that was passed to the executor:
${args}= Evaluate sys.argv sys
Log To Console ${args}
That'll return a list, where the executable itself (run.py) is the 1st member, and all arguments and their values present the in the order given during the execution:
['C:/my_directories/rf-venv/Lib/site-packages/robot/run.py', '--outputdir', 'logs', '--variable', 'USE_BROWSERSTACK:true', '--variable', 'IS_DEV_ENVIRONMENT:false', '--include', 'worky', 'suites\\test_file.robot']
You explicitly mention variable files; that one is a little bit trickier - the framework parses the files itself, and creates the variables according to its rules. You naturally can see them in the CLI args up there, and the other possibility is to use the built-in keyword Get Variables, which "Returns a dictionary containing all variables in the current scope." (quote from its documentation). Have in mind though that these are all variables - not only the passed on the command line, but also the ones defined in the suite/imported keywords etc.
You have Log Variables to see their names and values "at current scope".
There is no possibility to see the arguments passed to robot.

How to specify base directory for FUSE filesystem?

I am trying to create a FUSE filesystem called ordered-dirs using the Haskell wrapper over libfuse, HFuse. This filesystem is a "derived filesystem", i.e. it takes an existing directory (the "base directory") and produces a different view of it.
However, when I try to run my FUSE filesystem program, specifying the arguments in the ordinary mount way, I get an error:
$ ordered-dirs /home/robin/tasks/ /home/robin/to
fuse: invalid argument `/home/robin/to'
There is no way in HFuse (or in libfuse, it seems) to get the base directory (the first argument), so I had just written my own code to get it. But it's not this code that's failing - it's code within C libfuse itself - as the error message indicates.
So what is the correct way to pass the base directory to a fuse filesystem executable that uses libfuse to parse its arguments?
Surprisingly, it seems that the way to do this is to simply strip the base directory argument from the command-line arguments that are parsed to the libfuse parser, so that libfuse never sees it.
In the particular case of HFuse, this can be done by calling fuseRun instead, which allows the command-line arguments to be passed in explicitly. You can see how I've done this here - here is the relevant code (in which I've called the base directory source):
main :: IO ()
main = do
args <- getArgs
let (maybeSource, remainder) = extractSource args
source <- maybe (fail "source not specified") return maybeSource
fuseRun "ordered-dirs" remainder (orderedDirOps source) defaultExceptionHandler

Parameter file in ArgParse.jl?

Python's argparse has a simple way to read parameters from a file:
https://docs.python.org/2/library/argparse.html#fromfile-prefix-chars
Instead of passing your arguments one by one:
python script.py --arg1 val1 --arg2 val2 ...
You can say:
python script.py #args.txt
and then the arguments are read from args.txt.
Is there a way to do this in ArgParse.jl?
P.S.: If there is no "default" way of doing this, maybe I can do it by hand, by calling parse_args on a list of arguments read from a file. I know how to do this in a dirty way, but it gets messy if I want to replicate the behavior of argparse in Python, where I can pass multiple files with #, as well as arguments in the command line, and then the value of a parameter is simply the last value passed to this parameter. What's the best way of doing this?
This feature is not currently present in ArgParse.jl, although it would not be difficult to add. I have prepared a pull request.
In the interim, the following code suffices for what you need:
# faithful reproduction of Python 3.5.1 argparse.py
# partial copyright Python Software Foundation
function read_args_from_files(arg_strings, prefixes)
new_arg_strings = AbstractString[]
for arg_string in arg_strings
if isempty(arg_string) || arg_string[1] ∉ prefixes
# for regular arguments, just add them back into the list
push!(new_arg_strings, arg_string)
else
# replace arguments referencing files with the file content
open(arg_string[2:end]) do args_file
arg_strings = AbstractString[]
for arg_line in readlines(args_file)
push!(arg_strings, rstrip(arg_line, '\n'))
end
arg_strings = read_args_from_files(arg_strings, prefixes)
append!(new_arg_strings, arg_strings)
end
end
end
# return the modified argument list
return new_arg_strings
end
# preprocess args, then parse as usual
ARGS = read_args_from_files(ARGS, ['#'])
args = parse_args(ARGS, s)

Pass file name to perl from R

I want to pass file name to perl from R. For example, this system command from R to execute perl works well
system("perl file.pl name.txt")
name.txt is already existing in the R working directory. Now,
a<-"name.txt"
how to pass this to perl?
If I understand correctly I think this may work:
a <- "name.txt"
system(sprintf("perl file.pl %s", a))
Tyler's method works, but there is also this way:
a <- "name.txt"
system(paste("perl file.pl", a))
Depending on the situation, one may be more intuitive over the other.

How do I define a macro with the same name as its expansion in m4?

I am attempting to replace if with if( using GNU m4 1.4.14 and I am receiving ERROR: end of file in argument list
when trying:
define(`if', `if(')
define(`then', `){')
define(`fi', `}')
if foo then bar() fi
I have tried escaping the parentheses but that caused m4 to error after a brief period of time saying it's out of memory. Scanning through the manual, I found nothing related to this problem.
Upon changing the name of the macro to 'IF' or something other than 'if', it works as expected, which leads me to believe it's evaluating itself repeatedly.
If so, how can I define a macro that is evaluated only once? Otherwise, what should I look into to fix this?
EDIT I found a way around this issue by processing twice, once to convert if to _IF and the next to convert _IF to if(. I assume there's a better way to do this, so this is only a temporary solution in my eyes.
You need to prevent m4 from attempting to re-expanding the replacements. Do so by double quoting:
define(`if', ``if('')
define(`then', `){')
define(`fi', `}')
if foo then bar() fi

Resources