Parallel Shells with Xargs
linuxjournal.com
linuxjournal.com
for file in *pdf *azw3; do calibre-convert $file $file.epub; done
vs find . -name \*pdf -o -name \*azw3 -print0 | xargs -I {} calibre-convert {} {}.epub
Something about the former is more natural for my brain to produce. If I want to parallelize, for shell loops my muscle memory very quickly converts the above to for file in *pdf *azw3; do calibre-convert $file $file.epub & done; wait
... but if I have a million files my machine is going to have a bad day, whereas the xargs version is easy to limit to N parallel invocations.I'd really like a shell that lets me define my own sugared versions of shell grammar. I imagine writing a 'forp' that would let me do
forp $(nproc) file in ...; do ...; done
and the shell would run up to $(nproc) invocations in parallel. Anybody know of such a shell? (Don't say eshell.) ... | xargs -I{} bash -c "if [ $(stat --printf %Y {}) -gt 1234567890 ]; then do_something; else do_something_else; fi"
whereas if you're building your command with just a shell loop, when things start to get complicated you can `fc` into your $EDITOR, with pretty-print (with newlines) and syntax highlighting or whatever else you want.I bet one could coerce emacs into doing something reasonable for syntax highlighting inside a quoted `xargs sh -c "..."` but ugh
I'm not sure whether I'd move the actual branching in because of the balancing issue, that is point where my hairs stand up. Perhaps, this is where it all falls apart.
What?!? How have I never heard about this command? Thank you so much for telling me about it! This will be so much better than my current practice of manually copying unwieldy shell commands into a temporary file and running them there.
It takes whatever command you're working on at the shell prompt and opens it with your $EDITOR (or $VISUAL if you have that defined separately for some reason). When you save and quit your editor, the shell runs the edited command.
Nevertheless, I find xargs useful enough that I bite this bullet and have gotten very familiar with bash's quoting rules and how to work with them.
zargs -P $(nproc) -i ***(#i).(pdf|azw3) -- calibre-convert \{\} \{\}.epub
We're firing up nproc tasks, matching case-insensitive .pdf or and .azw3 at any depth, and then batch processing them. zargs is documented in zshcontrib(1).It doesn't feel that different to your imagined syntax to me, quite whether that matches your mental model better is for you to decide though.
Not only does this approach provide confidence before pulling the trigger, but the list of commands may be retained forever for reference / example. It's also clearer and doesn't get the reader mystified by "shell wizardry", as some people are wont to be.
In the first revisions, 1003.1 specified "Core Services" (mostly the C language stuff), and 1003.2 specified "Shell and Utilities". But when the Austin Group formed in 1997, they decided to roll the shell and utilities in to 1003.1. There no longer is a .2; it's been deprecated by 1003.1-2001 and all revisions since then.
This reminds me of the stagnation of CMD.EXE, the origins of which appear to lie with OS/2.
While I haven't read the latest standards, the only way to specifically address the userland is with "POSIX.2" (which is how the wiki does it).
If there is a better way to say it, then the wiki should be updated.
"ksh is intended to conform to the Shell Language Standard developed by the IEEE POSIX 1003.2 Shell and Utilities Language Committee."
What term better describes the purview of that committee (alone) than POSIX.2?
In 1997, that committee (the 1003.2 committee) merged with several other committees (including the 1003.1 committee) to form a unified committee called the "Austin Group". The Austin Group publishes a their work as a combined 1003.1; there is no longer a separate 1003.2 standard or committee.
There are still several other separate "1003.x" standards+committees for languages other than C and Shell that did not become part of the Austin Group (such as 1003.5 for the POSIX Ada interface). But 1003.2 is no longer one of those separate standards+committees.
If Korn were to write that sentence today, he might instead write "ksh is intended to conform to the Shell Language Standard developed by the Austin Group and published as IEEE POSIX 1003.1 Volume 3."
If I was to write another article, "Breaking the chains of POSIX," where do you think I should focus?
POSIX job control was a soft target, and I had imagined my next focus to be the "local" keyword in shell functions.
Do you have suggestion on a better weakness in POSIX to encourage improvement?
Microsoft's powershell is evolving, and the POSIX shell is ossified. I think the POSIX shell standard must evolve to remain competitive.
If you agree, where should this improvement be encouraged?
Yes, the C API is specified in IEEE 1003.1 volume 2 ("System Interfaces", abbreviated as "XSH"), and since 2001 the userland behavior is specified in IEEE 1003.1 volume 3 ("Shell and Utilities", abbreviated as "XCU").
(Volume 1 is "Base Definitions"/"XBD" and volume 4 is "Rationale"/"XRAT").
> the only way to specifically address the userland is with "POSIX.2"
The way to specifically address the shell and utilities is to refer to the volume within POSIX.1; you can do this by number ("Volume 3"), by name ("the Shell and Utilities volume"), or by abbreviation ("XCU").
> If there is a better way to say it, then the wiki should be updated.
Yes it should. Which wiki are you referring to?
https://en.wikipedia.org/wiki/POSIX#Parts_before_1997
In all the others, it is combined with the C API, and other OS standards.