[R] getopt does not work as expected!

Juergen Rose rose at rz.uni-potsdam.de
Wed Mar 28 14:08:39 CEST 2012


I have the following script (also attached):

#!/usr/bin/Rscript

spec=matrix(c(
  'verbose', 'v', 1, "integer",
  'help'   , 'h', 0, "logical"
  ),ncol=4, byrow=TRUE)
spec.dim=dim(spec)
spec.opt.long=spec[,1]
spec.opt.short=spec[,2]
spec.opt.l <- spec.dim[1]

infile <- "test.dat"
args=commandArgs(TRUE);    l=length(args)
self = commandArgs()[1];

usage <- function() {
  print(sprintf("Usage: %s [--verbose|-v] [--help,-h]
[infile.dat]"),self)
  print(sprintf("                       default infile.dat = '%
s'",infile))
}

library('getopt')

opt = getopt(spec,debug=TRUE);
if ( !is.null(opt$help) ) {
  ## get the script name (only works when invoked with Rscript).
  usage()
  print("------   before 'q(status=0)' ------")
  q(status=0);
}

if ( is.null(opt$verbose ) ) { opt$verbose = 0 }
if ( is.na(opt$verbose ) ) { opt$verbose = 0 }

print(sprintf("%s:  do something with %s!",self,infile))


If I run this script from the command line, I get the output:

rose at moose:/home_moose/rose/Txt/src/Test/R(24)$ ./getopt_test.R 
[1] "/usr/lib64/R/bin/exec/R: do something with test.dat!"

Why is commandArgs()[1] = "/usr/lib64/R/bin/exec/R" and not
"getopt_test.R" as described by the help (?getopt)?

rose at moose:/home_moose/rose/Txt/src/Test/R(25)$ ./getopt_test.R -h
[1] "processing -h"
[1] "  short option: -h"
[1] "Usage: getopt_test.R [--verbose|-v] [--help,-h] [infile.dat]"
[1] "                       default infile.dat = 'test.dat'"
[1] "------   before 'q(status=0)' ------"
rose at moose:/home_moose/rose/Txt/src/Test/R(26)$ ./getopt_test.R --help
[1] "processing --help"
[1] "  long option: --help"
[1] "    dangling flag"
[1] "Usage: getopt_test.R [--verbose|-v] [--help,-h] [infile.dat]"
[1] "                       default infile.dat = 'test.dat'"
[1] "------   before 'q(status=0)' ------"
rose at moose:/home_moose/rose/Txt/src/Test/R(27)$ ./getopt_test.R -b
[1] "processing -b"
[1] "  short option: -b"
Fehler in getopt(spec, debug = TRUE) : short flag "b" is invalid
Ausführung angehalten

Last three commands worked as expected.

rose at moose:/home_moose/rose/Txt/src/Test/R(28)$ ./getopt_test.R --b
[1] "processing --b"
[1] "  long option: --b"
[1] "    dangling flag"
Fehler in getopt(spec, debug = TRUE) : flag "b" requires an argument
Ausführung angehalten

That the command stopped is OK, but I expected the error message like
"long flag "b" is invalid".

rose at moose:/home_moose/rose/Txt/src/Test/R(29)$ ./getopt_test.R bla.dat
[1] "processing bla.dat"
Fehler in getopt(spec, debug = TRUE) : 
  "bla.dat" is not a valid option, or does not support an argument
Ausführung angehalten

This behaviour I don't like at all. Why getopt does not distinguish
beetween options starting with alt least one hyphen and normal arguments
starting without hyphen? How it is possible to handle such a situation?
Have I myself to split the arguments into two lists, one with hyphen and
one without hyphen, and then pass only this list with hyphen to getopt?
Or is there a better solution?

Regards Juergen

-------------- next part --------------
#!/usr/bin/Rscript

spec=matrix(c(
  'verbose', 'v', 1, "integer",
  'help'   , 'h', 0, "logical"
  ),ncol=4, byrow=TRUE)
spec.dim=dim(spec)
spec.opt.long=spec[,1]
spec.opt.short=spec[,2]
spec.opt.l <- spec.dim[1]

infile <- "test.dat"
args=commandArgs(TRUE);    l=length(args)
self = commandArgs()[1];

usage <- function() {
  print(sprintf("Usage: getopt_test.R [--verbose|-v] [--help,-h] [infile.dat]"))
  print(sprintf("                       default infile.dat = '%s'",infile))
}

library('getopt')

opt = getopt(spec,debug=TRUE);
#opt = getopt(spec);
#print(opt,usage=TRUE)

## help was asked for.
if ( !is.null(opt$help) ) {
  ## get the script name (only works when invoked with Rscript).
  self = commandArgs()[1];
  ## print a friendly message and exit with a non-zero error code
  usage()
  print("------   before 'q(status=0)' ------")
  q(status=0);
}

## set some reasonable defaults for the options that are needed,
## but were not specified.
if ( is.null(opt$verbose ) ) { opt$verbose = 0 }
if ( is.na(opt$verbose ) ) { opt$verbose = 0 }

print(sprintf("%s: do something with %s!",self,infile))




More information about the R-help mailing list