Henrik Bengtsson
2015-May-18 00:13 UTC
[Rd] install.packages() / update.packages() sometimes outputs to stdout and sometimes to stderr [and menu() & readline()]
I've noticed that install.packages() [https://svn.r-project.org/R/trunk/src/library/utils/R/packages.R] and update.packages() [https://svn.r-project.org/R/trunk/src/library/utils/R/packages2.R] sometimes output to stdout and sometimes to stderr. It looks like stderr is used (e.g. via cat()) when the message is part of querying the user, e.g. update.packages <- function(lib.loc = NULL, repos = getOption("repos"), [...] cat(old[k, "Package"], ":\n", "Version", old[k, "Installed"], "installed in", old[k, "LibPath"], if(checkBuilt) paste("built under R", old[k, "Built"]), "\n", "Version", old[k, "ReposVer"], "available at", simplifyRepos(old[k, "Repository"], type)) cat("\n") answer <- substr(readline("Update (y/N/c)? "), 1L, 1L) if(answer == "c" | answer == "C") { cat("cancelled by user\n") return(invisible()) } but it is not consistently so, because some are sent to stderr (e.g. via message()), e.g. install.packages <- function(pkgs, lib, repos = getOption("repos"), [...] if(action == "interactive" && interactive()) { msg <- ngettext(sum(later & hasSrc), "Do you want to install from sources the package which needs compilation?", "Do you want to install from sources the packages which need compilation?") message(msg, domain = NA) res <- readline("y/n: ") if(res != "y") later <- later & !hasSrc } else if (action == "never") { cat(" Binaries will be installed\n") later <- later & !hasSrc } Also, as one see in the latter example, it is not only interactive user queries for which stdout is used. It's simply not consistent - at least I cannot see pattern. If these are not intended behaviors, I'm happy to provide patches. I'd prefer stderr for all user queries (see below) - but I can also see how this is something that needs considered thoughts and made an official design policy across the R base distribution. [Related to the above but could deserve it's own thread (feel free to move the below to its own thread)] utils::menu(..., graphics=FALSE) [https://svn.r-project.org/R/trunk/src/library/utils/R/menu.R] queries the user via standard output, which becomes an issue when running interactive report generators, which mostly captures stdout and makes it part of the produced artifact. Personally, I'd argue that querying the user via stderr would be a better choice in more cases. Also, it's a bit weird that base::readline(), which is used for the actual prompting of the user, is sent neither to R's stdout nor stderr, e.g.> zz <- file("all.Rout", open = "wt") > sink(zz); sink(zz, type = "message") > ans <- menu(letters[1:3], title="Select one:", graphics=FALSE)Selection: 1> sink(type = "message"); sink() > ans[1] 1> cat(readLines("all.Rout"), sep="\n")Select one: 1: a 2: b 3: c Note the only thing displayed to the user is the prompt "Selection: ", which is generated by readline(). It does however output to the system's stdout (verified on Linux and Windows), e.g. $ Rscript -e "readline('Press ENTER: ')" > stdout.log $ cat stdout.log Press ENTER: [1] "" Compare this to how it works in, for instance, bash: $ read -p "Press ENTER: " ans > stdout.log Press ENTER: $ read -p "Press ENTER: " ans > stderr.log $ cat stderr.log Press ENTER: My preference would be that menu() and readline() and other messages for querying the user would output to the same connection/stream. Again, I'd favor stderr over stdout, but possibly even a third alternative designed specifically for user queries, cf. my R-devel post '[Rd] Output to "raw console" rather than stdout/stderr?' on 2015-02-01 (https://stat.ethz.ch/pipermail/r-devel/2015-February/070578.html). Just like when using menu(..., graphics=TRUE), this would not clutter up the output to stdout (or stderr). But even without this third alternative, I argue that stderr is better than stdout. I'm happy to provide patches for this as well. Thanks, Henrik
Reasonably Related Threads
- SUGGESTION: Option to have menu() and select.list() to use stderr (or even "prompt" output)
- Output to "raw console" rather than stdout/stderr?
- Patching "update.packages" to enable updating of only a user defined subset of packages
- Output to "raw console" rather than stdout/stderr?
- attach() outputs messages to stdout - should it be stderr?