[Rd] Output pipes to TTY hang
Tomas Kalibera
tom@@@k@||ber@ @end|ng |rom gm@||@com
Mon May 20 12:20:37 CEST 2024
On 5/20/24 07:36, Zafer Barutcuoglu wrote:
> Hi,
>
> I am seeing this on Linux as well as MacOS: Opening any output pipe from R 4.4.0 to TTY programs like "less"/"more" hangs, SIGINT-proof:
>> $ R/4.4.0/bin/Rscript -e 'pipe("less", "w")'
>> $ R/4.4.0/bin/Rscript -e 'cat("test", file="|less")
>> $ R/4.4.0/bin/Rscript -e 'cat("test", file="|more")
> R 4.3.3 and earlier have been working fine:
>> $ R/4.3.3/bin/Rscript -e 'pipe("less", "w")'
>> $ R/4.3.3/bin/Rscript -e 'cat("test", file="|less")
>> $ R/4.3.3/bin/Rscript -e 'cat("test", file="|more")
I've tried the first example and it doesn't work for me even in R 4.3.3
on Linux, so I can't easily test what changed the behavior for you, but
it was very likely a bugfix for PR#17764. Now the pipe() uses a special
process group to protect the processes (assumed to be background) from
the terminal.
If you are interested in the details behind this, see the bug report
discussion or the blog post (below), and the source code.
A perhaps slightly over-simplified description is that tasks executed
via pipe() and (file="|") and system(wait="FALSE") are background tasks,
which should not be interruptible e.g. by Ctrl+C. This was fixed in R
4.4, which required significant changes of the underlying implementation.
To support the very rare case when a task executed via
system(wait="FALSE") should receive signals from a console, because it
is to logically implement an interactive task using background tasks,
there is now an argument "receive.console.signals", which can be used to
override this. This is used by the R's parallel package to implement
interactive computation on a cluster.
Your use case seems to be running an interactive task using pipe().
Currently, there is no argument of pipe() to allow this as we didn't
anticipate anyone would actually be doing this - and, on my system, it
doesn't work even in R 4.3.3.
I assume the examples above are narrowed down cases to reproduce the
change in behavior. If there was a plausible, realistic example that
would indicate the need to add such argument to pipe(), it could be
considered, but perhaps it would be more natural to use
system(wait=FALSE,receive.console.signals=TRUE), anyway?
Best
Tomas
https://blog.r-project.org/2023/05/23/not-interrupting-background-tasks-with-ctrl-c/index.html
https://bugs.r-project.org/show_bug.cgi?id=17764
>
> R 4.4.0 also works fine with non-TTY output pipes:
>> $ R/4.4.0/bin/Rscript -e 'pipe("cat", "w")'
>> $ R/4.4.0/bin/Rscript -e 'cat("test", file="|cat")
>> $ R/4.4.0/bin/Rscript -e 'cat("Hi!\n", file="|tr i o")'
>> $ R/4.4.0/bin/Rscript -e 'cat("Hi!\n", file="|sed -e s/i/o/")'
> For what it's worth, input pipes from less/more to R 4.4.0 do not hang, but are not always the same as before either. These are the same:
>> $ R/4.3.3/bin/Rscript -e 'con <- pipe("less --version", "r"); readLines(con); close(con)'
>> [1] "less (GNU regular expressions)" "Copyright (C) Mark Nudelman" ...
>> $ R/4.4.0/bin/Rscript -e 'con <- pipe("less --version", "r"); readLines(con); close(con)'
>> [1] "less (GNU regular expressions)" "Copyright (C) Mark Nudelman" ...
> But these are not (again, on both Linux and MacOS):
>> $ R/4.3.3/bin/Rscript -e 'con <- pipe("less", "r"); readLines(con); close(con)'
>> [1] "Missing filename (\"less --help\" for help)"
>> $ R/4.4.0/bin/Rscript -e 'con <- pipe("less", "r"); readLines(con); close(con)'
>> character(0)
>
> I did not see anything related here or in release notes or bugzilla. Is this a bug or something else?
>
> Best,
> --
> Zafer
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list