Austin Group Defect Tracker

Aardvark Mark IV

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001628 [Online Pubs] Shell and Utilities Editorial Enhancement Request 2023-01-15 17:18 2023-01-22 19:29
Reporter mirabilos View Status public  
Assigned To
Priority normal Resolution Open  
Status New  
Name mirabilos
Organization MirBSD
User Reference
URL [^]
Section xargs(1)
Summary 0001628: Add -o (reopen stdin) option to xargs(1)
Description Now that 243 is accepted, I would like to request the addition of another option to xargs(1) to make it really useful. It’s a BSD thing:

     -o Reopen stdin as /dev/tty in the child process before executing
             the command. This is useful if you want xargs to run an interac-
             tive application.

I’ve been using this a *lot*, as something like…

$ git find \*.h -print0 | xargs -0o $EDITOR

… (where [^] is the tool in question), or with just a simple find, or a (git) grep -Z. I also have been able to successfully convince GNU coreutils to add precisely this (they also added a GNU --long-option but added it with -o for BSD compatibility). (I know I should use -0or but I lazily skip the -r if I know there’s at least one anyway.)
Desired Action In SYNOPSIS, change -0ptrx to -0optrx.

In DESCRIPTION, where it says the results are unspecified if the utility reads from stdin, add unless the -o flag is given.

In OPTIONS, add:

.It Fl o
Reopen stdin as
.Pa /dev/tty
in the child process before executing the command.
This is useful if you want
to run an interactive application.

In INPUT FILES, mention that -o also uses /dev/tty.

Possibly add a suitable example; do we have grep -Z yet in POSIX (it’s not in 243)? Otherwise, 'find . -name \*.h -print0 | xargs -0or $EDITOR' will probably do.
Tags No tags attached.
Attached Files

- Relationships

-  Notes
oguzismailuysal (reporter)
2023-01-15 17:57

I don't think this is a good example:

    find . -name \*.h -print0 | xargs -0or $EDITOR

xargs is not even necessary there. See:

    find . -name '*.h' -exec "$EDITOR" {} +
stephane (reporter)
2023-01-16 08:12

Note that with cmd1 | xargs -r0o cmd2 --, cmd2's stdin is /dev/tty even when that command is in a script and that script has its input redirected.

GNU xargs'

xargs -r0a <(cmd1) cmd2 --

Is better IMO as cmd2's stdin is the script's stdin, not the pipe nor /dev/null nor /dev/tty, though that needs a shell with process substitution support which is not in POSIX yet (and means the exit status of cmd1 is lost in most shells, even with the pipefail option on).

In any case, both can be done already with the current proposed spec albeit quite awkwardly:

cmd1 | xargs -r0 sh -c 'exec cmd2 -- "$@" < /dev/tty' sh

for the first

{ cmd1 3<&- | xargs -r0 sh -c 'exec cmd2 -- "$@" <&3 3<&-' sh; } <&0

for the second (where cmd1's exit status is not lost if using pipefail).
mirabilos (reporter)
2023-01-20 20:46

oguzismailuysal wrote:

> find . -name '*.h' -exec "$EDITOR" {} +

Most people I know can never remember the -exec syntax and avoid advanced use of find(1). But the aforementioned “git find” as well as various greps etc. do not offer this anyway, and it’d be good to have it for symmetry. Using find(1) is just concocting an easy-to-remember example… *especially* as you can go from there to …-print0 | while IFS= read -rd '' file; do… immediately.

stephane wrote:

> xargs -r0a <(cmd1) cmd2 --

Yuk, that’s even GNU bash-specific.

> Note that with cmd1 | xargs -r0o cmd2 --, cmd2's stdin is /dev/tty even
> when that command is in a script and that script has its input redirected.

Yes, that’s a good thing.

> quite awkwardly:

Same thing as above: nobody’s going to remember these.

IIRC the people in GNU coreutils mentioned the same but decided to implement BSD’s -o nevertheless because of its utility in making things better for users and consistent across OSes.
gbrandenrobinson (reporter)
2023-01-20 21:12

"Yuk, that’s even GNU bash-specific."

No, that goes back farther, at least to Tom Duff's rc shell, which was implemented more famously for Plan 9 from Bell Labs but also for Tenth Edition Research Unix (1989). [^]
mirabilos (reporter)
2023-01-20 21:50

I meant the use of the <(…) construct here that’s necessary to make this somewhat writabl…ish.

(But still not as good as the easily pluggable xargs solution; same argument as for -exec really, you can add xargs to inspect part of the pipeline, then put something else there instead.)
stephane (reporter)
2023-01-22 19:29
edited on: 2023-01-24 09:58

Re: Note: 0006117

> > xargs -r0a <(cmd1) cmd2 --
> Yuk, that’s even GNU bash-specific.

There's nothing bash-specific in there. Process substitution is from ksh (first documented in ksh86), and is also found with that syntax in zsh (since 1990) and bash (since 1993). In yash, <(cmd) is process redirection, /dev/fd/3 3<(cmd) there works similarly to ksh's <(cmd).

rc, es, akanga, fish also have process substitution support, though with different syntaxes.

That's quite an essential feature.

I suspect one of the reasons it was not specified by POSIX back then was because in ksh88 at the time, it only worked on systems that had /dev/fd/x support. Other shells (including recent versions of ksh93) can resort to named pipe (zsh and Byron Rakitzis's rc clone originally were only using named pipe, likely because they were developed on systems without /dev/fd)

- Issue History
Date Modified Username Field Change
2023-01-15 17:18 mirabilos New Issue
2023-01-15 17:18 mirabilos Name => mirabilos
2023-01-15 17:18 mirabilos Organization => MirBSD
2023-01-15 17:18 mirabilos URL => [^]
2023-01-15 17:18 mirabilos Section => xargs(1)
2023-01-15 17:57 oguzismailuysal Note Added: 0006111
2023-01-16 08:12 stephane Note Added: 0006112
2023-01-20 20:46 mirabilos Note Added: 0006117
2023-01-20 21:12 gbrandenrobinson Note Added: 0006119
2023-01-20 21:50 mirabilos Note Added: 0006121
2023-01-22 19:29 stephane Note Added: 0006129
2023-01-24 09:58 stephane Note Edited: 0006129

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker