Ich habe gerade eine schöne Datenstruktur und Verarbeitungskette zusammengestellt, um dieses Schaltverhalten zu erzeugen. Es werden keine Bibliotheken benötigt. Ich bin mir sicher, dass es mehrfach implementiert wurde, und bin auf diesen Thread gestoßen, der nach Beispielen gesucht hat - dachte, ich würde mitmachen.
Ich brauchte nicht einmal besonders Flags (das einzige Flag hier ist ein Debug-Modus, der eine Variable erstellt, auf die ich als Bedingung für das Starten einer Downstream-Funktion prüfe if (!exists(debug.mode)) {...} else {print(variables)})
. Die folgenden lapply
Anweisungen zur Flag-Prüfung ergeben Folgendes:
if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args)
wo args
wird die Variable aus Befehlszeilenargumenten eingelesen (ein Zeichenvektor, der äquivalent zu istc('--debug','--help')
wenn Sie diese beispielsweise angeben)?
Es ist für jedes andere Flag wiederverwendbar und Sie vermeiden alle Wiederholungen und keine Bibliotheken, also keine Abhängigkeiten:
args <- commandArgs(TRUE)
flag.details <- list(
"debug" = list(
def = "Print variables rather than executing function XYZ...",
flag = "--debug",
output = "debug.mode <- T"),
"help" = list(
def = "Display flag definitions",
flag = c("-h","--help"),
output = "cat(help.prompt)") )
flag.conditions <- lapply(flag.details, function(x) {
paste0(paste0('"',x$flag,'"'), sep = " %in% args", collapse = " || ")
})
flag.truth.table <- unlist(lapply(flag.conditions, function(x) {
if (eval(parse(text = x))) {
return(T)
} else return(F)
}))
help.prompts <- lapply(names(flag.truth.table), function(x){
# joins 2-space-separatated flags with a tab-space to the flag description
paste0(c(paste0(flag.details[x][[1]][['flag']], collapse=" "),
flag.details[x][[1]][['def']]), collapse="\t")
} )
help.prompt <- paste(c(unlist(help.prompts),''),collapse="\n\n")
# The following lines handle the flags, running the corresponding 'output' entry in flag.details for any supplied
flag.output <- unlist(lapply(names(flag.truth.table), function(x){
if (flag.truth.table[x]) return(flag.details[x][[1]][['output']])
}))
eval(parse(text = flag.output))
Beachten Sie, dass flag.details
hier die Befehle als Zeichenfolgen gespeichert und dann mit ausgewertet werdeneval(parse(text = '...'))
. Optparse ist natürlich für jedes ernsthafte Skript wünschenswert, aber Code mit minimaler Funktionalität ist manchmal auch gut.
Beispielausgabe:
$ Rscript check_mail.Rscript --help
--debug Gibt Variablen aus, anstatt die Funktion XYZ auszuführen ...
-h --help Flag-Definitionen anzeigen