Hide

What's this?

commandlinefu.com is the place to record those command-line gems that you return to again and again.

Delete that bloated snippets file you've been using and share your personal repository with the world. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.


If you have a new feature suggestion or find a bug, please get in touch via http://commandlinefu.uservoice.com/

Get involved!

You can sign-in using OpenID credentials, or register a traditional username and password.

First-time OpenID users will be automatically assigned a username which can be changed after signing in.

Hide

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.

» http://twitter.com/commandlinefu
» http://twitter.com/commandlinefu3
» http://twitter.com/commandlinefu10

Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for:

Hide

News

2011-03-12 - Confoo 2011 presentation
Slides are available from the commandlinefu presentation at Confoo 2011: http://presentations.codeinthehole.com/confoo2011/
2011-01-04 - Moderation now required for new commands
To try and put and end to the spamming, new commands require moderation before they will appear on the site.
2010-12-27 - Apologies for not banning the trolls sooner
Have been away from the interwebs over Christmas. Will be more vigilant henceforth.
2010-09-24 - OAuth and pagination problems fixed
Apologies for the delay in getting Twitter's OAuth supported. Annoying pagination gremlin also fixed.
Hide

Tags

Hide

Functions

Commands by bhepple from sorted by
Terminal - Commands by bhepple - 13 results
wait
2010-01-15 04:03:11
User: bhepple
Functions: wait
0

If you really _must_ use a loop, this is better than parsing the output of 'ps':

PID=$! ;while kill -0 $PID &>/dev/null; do sleep 1; done

kill -0 $PID returns 0 if the process still exists; otherwise 1

vman(){ T=/tmp/$$.pdf;man -t $1 |ps2pdf - >$T; xpdf $T; rm -f $T; }
2010-01-07 01:15:38
User: bhepple
Functions: rm
1

You're a developer - but it doesn't mean you have to slum it! Why not spice up your man page lookups by using a decent PDF viewer. I use 'xpdf' - maybe you prefer acroread, whatever, it's just as fast as plain dull ASCII on today's machines and you can still search for stuff - that's the main reason I use PDF and not PS.

LC_ALL=C man -c man
2010-01-07 00:59:09
User: bhepple
Functions: man
1

Often you find some tty programs are messed up and confused about character encoding - 'man' is a common problem and sometimes displays weird characters for apostrophes, hyphens etc etc. Another class of programs that suffer from this are those that try to use the line drawing characters - eg RedHat's tty system admin functions such as system-config-firewall-tui system-config-network-tui etc.

Adding 'LC_ALL=C' fixes most of these problems (as long as you want English! Perhaps speakers of other languages can add a comment here).

For bonus points, I've added the '-c' option to the man command so that it ignores it's cache and re-computes the man page using the C locale.

isatty(){ test -t $1; }
2010-01-06 06:50:01
User: bhepple
Functions: test
3

Oddly, the isatty(3) glibc C call doesn't have a direct analogue as a command 'isatty(1)'. All is not lost as you can use test(1).

For example, your script might be run from a tty or from a GUI menu item but it needs to get user-input or give feedback. Now your script can test STDIN with 'isatty 0' or STDOUT with 'isatty 1' and use xmessage(1) if the tty is not available.

The other way to test for this is with 'tty -s' - but that's only for STDIN.

silent(){ $@ > /dev/null 2>&1; }; alias shh=silent
2010-01-04 01:01:03
User: bhepple
Functions: alias
8

Sometimes I just want to run a command quietly but all that keyboard shifting makes my fingers hurt. This little function does the job eg.:

if shh type less; then PAGER=less; fi
function ..(){ for ((j=${1:-1},i=0;i<j;i++));do builtin cd ..;done;}
2010-01-02 08:36:12
User: bhepple
Functions: cd
Tags: cd
3

Instead of typing "cd ../../.." you can type ".. 3". For extremely lazy typists, you can add this alias:

alias ...=".. 2" ....=".. 3"

- so now you can write just .... !!!

NB the .. function needs to be "source"d or included in your startup scripts, perhaps .bashrc.

xlaunch(){ T=/tmp/$$;sh -c "$@" >$T.1 2>$T.2;S=$?;[ $S -ne 0 ]&&{ echo -e "'$@' failed with error $S\nSTDERR:\n$(cat $T.2)\nSTDOUT:\n$(cat $T.1)\n"|xmessage -file -;};rm -f $T.1 $T.2;}
2009-12-31 06:59:56
User: bhepple
Functions: echo
Tags: X
1

When you run an X program from a terminal you can see any errors. But when it's run from another X program (eg from a menu item, from your fluxbox 'keys' file etc) it might just die and you see nothing (except perhaps in .xsession-errors). Instead, launch it via this command and you'll see the termination status, stderr and stdout.

eg: "xlaunch firefox" or "xlaunch 'echo stdout; echo stderr >&2; false'":

'echo stdout; echo stderr >&2; false' failed with error 1

STDERR:

stderr

STDOUT:

stdout

find dir -size -1024k -type f -print0 | du --files0-from - -bc
2009-12-29 01:33:55
User: bhepple
Functions: dir du find
Tags: size sum
2

The original didn't use -print0 which fails on weird file names eg with spaces.

The original parsed the output of 'ls -l' which is always a bad idea.

parse_rpm() { RPM=$1;B=${RPM##*/};B=${B%.rpm};A=${B##*.};B=${B%.*};R=${B##*-};B=${B%-*};V=${B##*-};B=${B%-*};N=$B;echo "$N $V $R $A"; }
2009-12-19 20:07:26
User: bhepple
Tags: rpm
0

parse_rpm xorg-x11-fonts-ISO8859-1-75dpi-7.1-2.1.el5.noarch.rpm

xorg-x11-fonts-ISO8859-1-75dpi 7.1 2.1.el5 noarch

It's a little tricky because RPM names can contain '-' and the name, version and release number can contain '.' This is one or two orders of magnitude faster than using rpm itself:

rpm -qp --queryformat '%{N} %{V} %{R} %{ARCH}\n' $RPM
startx -- /usr/bin/Xephyr :2
2009-11-25 07:27:39
User: bhepple
4

You might have Xnest (older) rather than Xephyr.

You can experiment with other desktops eg:

startx /usr/bin/start-kde -- /usr/bin/Xephyr :2

You can start X on a remote machine (although I'd recommend vnc for anything slower than a LAN):

startx /usr/bin/ssh -X gnome-session -- /usr/bin/Xephyr :2

Or just start another X session locally talking to the remote backend:

rdp() { ssh $1 sh -c 'PATH=$PATH:/usr/local/bin; x11vnc -q -rfbauth ~/.vnc/passwd -display :0' & sleep 4; vncviewer $1:0 & }
2009-11-25 07:21:02
User: bhepple
Functions: sh sleep ssh
1

If the remote doesn't export its desktop (eg fluxbox, blackbox etc) then you need to run a x11vnc server there and a vncviewer at the local end. This command does the lot for you - it assumes that you can 'ssh' to the box without a password and that x11vnc is installed at the remote end.

process-getopt
2009-11-25 06:48:37
User: bhepple
Tags: bash getopt
1

This will make your bash scripts better!!

process-getopt is a wrapper around getopt(1) for bash that lets you define command line options (eg -h, --help) and descriptions through a single function call. These definitions are then used in runtime processing of command line options as well as in generating help and man pages. It also saves a little time in coding and in producing nicely formatted documentation. It is quite similar to GNU's argp in glibc for compiled languages and OptionParse for python.

See: Linux Gazette article 162: http://tldp.org/LDP/LGNET/162/hepple.html,

http://sourceforge.net/projects/process-getopt, http://bhepple.freeshell.org/oddmuse/wiki.cgi/process-getopt

map ^A !}fmt
2009-11-25 03:38:52
User: bhepple
1

That goes into your $HOME/.exrc file.

" Nice macro to reformat lines:

map ^A !}fmt

Note that the ^A has to be input by typing ^V^A.