moreutils is a growing collection of the unix tools that nobody thought to write long ago when unix was young.

It began when I blogged:

I'm a fan of the unix tools philosophy, but I sometimes wonder if there's much room for new tools to be added to that toolbox. I've always wanted to come up with my own general-purpose new unix tool.

Well, after lots of feedback documented in the many followups (1 2 3) in my blog, I've concluded:

Maybe the problem isn't that no-one is writing them, or that the unix toolspace is covered except for specialised tools, but that the most basic tools fall through the cracks and are never noticed by people who could benefit from them.

And so the moreutils collection was born, to stop these programs from falling through the cracks.

What's included

Probably the most general purpose tool in moreutils so far is sponge (1), which lets you do things like this:

% sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

There are lots more listed below, and I'm always interested to add more to the collection, as long as they're suitably general-purpose, and don't duplicate other well-known tools.

chronic: runs a command quietly unless it fails

combine: combine the lines in two files using boolean operations

errno: look up errno names and descriptions

ifdata: get network interface info without parsing ifconfig output

ifne: run a program if the standard input is not empty

isutf8: check if a file or standard input is utf-8

lckdo: execute a program with a lock held

mispipe: pipe two commands, returning the exit status of the first

parallel: run multiple jobs at once

pee: tee standard input to pipes

sponge: soak up standard input and write to a file

ts: timestamp standard input

vidir: edit a directory in your text editor

vipe: insert a text editor into a pipe

zrun: automatically uncompress arguments to command

Download

A Debian package as well as the source tarball for moreutils can be downloaded from packages.debian.org, or using apt. It's also in Ubuntu, and, I hear in several other Linux distributions.

The git repository can be cloned from git://git.joeyh.name/moreutils

News

version 0.64 moreutils 0.64 released with these changes parallel: fix typo in usage message.

Makefile: Propagate compiler and linker flags when building is_utf8.

ts: Fix parsing of ISO-8601 dates. Thanks, David Laban.

parallel: Allow compiling with uClibc-ng, which does not have getloadavg. Thanks, Rosen Penev

version 0.63 moreutils 0.63 released with these changes vipe: Clean up temp file even when it exits with an error. Thanks, Stig Palmquist.

ts: Fix ts -m %.s to not output negative microseconds. Thanks, Dima Kogan

sponge: Fix bug in -a mode that doubled original content of file when the temp file is located on a different filesystem.

version 0.62 moreutils 0.62 released with these changes ts: Add -m option to use monotonic clock. Thanks, Ben Leinweber

ts: Added %.T format like %T but with hi-res. Thanks, Matt Koscica

pee: Ignore SIGPIPE and write errors caused by the command not consuming all its input. Closes: #697052 Thanks, Ole Jørgen Brønner

chronic: document return value semantics of -e option. Closes: #867167 Thanks, Daniel Shahaf

vidir: reword man page to more explicit mention 'file' args. Closes: #885221 Thanks, Daniel Shahaf

pee: Don't buffer input, bringing behavior into line with tee. Thanks, Sauerbeck Tilman

TODO

pee should support non-blocking i/o to write to the pipes to allow concurrent processing of the data by the programs. Alternatively, switch to fountain http://hea-www.cfa.harvard.edu/~dj/tmp/fountain-1.0.2.tar.gz. Alternatively, make sponge buffer to stdout if no file is given, and use it to buffer the data from pee. Although this will be less efficient and will not work as well for very large streams unless sponge avoids buffering the whole contents in memory in this case.

Tools under consideration

Here are some that are under consideration but have not yet been included. Feel free to suggest others. I also welcome feedback on which of these to include.

dirempty/exists It's too hard to tell if a directory is empty in shell. Also, while test -e works ok for a single file, it fails if you want to see if a wildcard matches anything. Suggested in bug #385069, see bug for my comments.

cattail Allows catting a file that's still changing (ie, being downloaded) to a program. The new bits of the file will continue to be fed to the program until the download is done. Submitted by Justin Azoff, with code. However, it has to use heuristics to guess when the download (or whatever) is done. The current heuristic, 10 seconds w/o growth, wouldn't work very well for me on dialup. Using inotify is probably the best approach. fsniper is a less general-purpose tool that uses inotify to detect when a file is closed.

phoenix Respawns a process unless a user really wants to quit. Suggested in bug #382428 Doesn't seem general enough.

haschanged Run it once to store a file's hash, and the second time it'll check whether the file has changed. http://blog.steve.org.uk/the_traffic_is_waiting_outside.html

tmp puts stdin into a temp file and passes it to the specified program ex: zcat file.bmp.gz | tmp zxgv Alternative: pip

connect connect 'cmd1' op 'cmd2' ... -- connects fd's of commands together, etc In the same spirit as 'pee', but much more powerful. If done very simply, this is handy for writing coprocesses as pipelines that need to communicate back and forth. You can do SOME of this with a great shell, like bash or zsh; you can do almost all the rest with a bunch of mkfifo commands plus simple redirection, but with added complexity and a lot of manual steps. This command could be even more powerful if you gave it essentially a "netlist" of fd's to connect. I'm sure the command line syntax could be improved, but you get the idea. Very very complex example just to illustrate: connect 'cmd1' '<> #0:3>4' 'cmd2' '3>' \ 'cmd3' '3<>3 #0:0>' 'cmd4' '3>#1:5' * specs specify connections between adjacent cmds * qualified specs (w/ '#') allow more complex connections * Some sane defaults, but can be overridden * stdin goes to first process that doesn't redirect it * stdout comes from everyone that doesn't redirect it * stderr comes from everyone that doesn't redirect it * cmd1's stdout -> cmd2's stdin * cmd2's stdout -> cmd1's stdin * fd3 -> cmd2's fd4 * cmd2's fd3 -> cmd3's stdin * cmd3's fd3 -> cmd4's fd3 * cmd4's fd3 -> cmd3's fd3 * stdin -> cmd4 * cmd4's fd3 -> cmd1's fd5 * stdout <- all w/o redirected stdout (in this case, cmd3) * stderr <- all w/o redirected stderr (in this case, all) If you think this is a good idea, let me know. I have a basic connect command, but it only does two commands. However, I'll be happy to code this up if there is interest. (In fact, I think I may anyway, so I don't keep doing stuff like this ad-hoc all the time). -- from Wesley J. Landaker Should be possible to roll mispipe up into this by adding a way to flag which command(s) exit status to return.



Rejected tools

(Some of these rejections may be reconsidered later.)