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 tagged for from sorted by
Terminal - Commands tagged for - 37 results
for i in {1..256};do p=" $i";echo -e "${p: -3} \\0$(($i/64*100+$i%64/8*10+$i%8))";done|cat -t|column -c120
2014-04-04 16:54:53
User: AskApache
Functions: cat column echo
6

Prints out an ascii chart using builtin bash! Then formats using cat -t and column.

The best part is:

echo -e "${p: -3} \\0$(( $i/64*100 + $i%64/8*10 + $i%8 ))";

From: http://www.askapache.com/linux/ascii-codes-and-reference.html

for times in $(seq 10) ; do puppet agent -t && break ; done
2013-04-03 14:24:36
User: funollet
Functions: break seq times
-1

The example runs 'puppet' in a loop for 10 times, but exits the loop before if it returns 0 (that means "no changes on last run" for puppet).

for i in `find -name '*_test.rb'` ; do mv $i ${i%%_test.rb}_spec.rb ; done
2012-10-09 14:08:38
User: olopopo
Functions: mv
0

Renames all files ending in "_test.rb" to "_spec.rb"

for i in /var/spool/cron/tabs/*; do echo ${i##*/}; sed 's/^/\t/' $i; echo; done
2012-07-12 08:07:20
User: harpo
Functions: echo sed
1

This is flatcaps tweaked command to make it work on SLES 11.2

for i in /var/spool/cron/*; do echo ${i##*/}; sed 's/^/\t/' $i; echo; done
hourglass(){ trap 'tput cnorm' 0 1 2 15 RETURN;local s=$(($SECONDS +$1));(tput civis;while (($SECONDS<$s));do for f in '|' '\' '-' '/';do echo -n "$f";sleep .2s;echo -n $'\b';done;done;);}
2012-06-21 05:40:22
User: AskApache
Functions: echo sleep tput trap
14

Displays an animated hourglass for x amount of seconds

testt(){ o=abcdefghLkprsStuwxOGN;echo $@;for((i=0;i<${#o};i++));do c=${o:$i:1};test -$c $1 && help test | sed "/^ *-$c/!d;1q;s/^[^T]*/-$c /;s/ if/ -/";done; }
2012-02-21 16:54:53
User: AskApache
Functions: echo sed test
2

Applies each file operator using the built-in test.

testt /home/askapache/.sq

/home/askapache/.sq

-a True - file exists.

-d True - file is a directory.

-e True - file exists.

-r True - file is readable by you.

-s True - file exists and is not empty.

-w True - the file is writable by you.

-x True - the file is executable by you.

-O True - the file is effectively owned by you.

-G True - the file is effectively owned by your group.

-N True - the file has been modified since it was last read.

Full Function:

testt ()

{

local dp;

until [ -z "${1:-}" ]; do

dp="$1";

[[ ! -a "$1" ]] && dp="$PWD/$dp";

command ls -w $((${COLUMNS:-80}-20)) -lA --color=tty -d "$dp";

[[ -d "$dp" ]] && find "$dp" -mount -depth -wholename "$dp" -printf '%.5m %10M %#15s %#9u %-9g %#5U %-5G %Am/%Ad/%AY %Cm/%Cd/%CY %Tm/%Td/%TY [%Y] %p\n' -a -quit 2> /dev/null;

for f in a b c d e f g h L k p r s S t u w x O G N;

do

test -$f "$dp" && help test | sed "/-$f F/!d" | sed -e 's#^[\t ]*-\([a-zA-Z]\{1\}\) F[A-Z]*[\t ]* True if#-\1 "'$dp'" #g';

done;

shift;

done

}

for line in `cat $file`; do firefox -new-tab "$line" & 2>/dev/null; sleep 1; done
2011-11-12 13:47:24
User: hamsolo474
Functions: sleep
2

this will open a new tab in firefox for every line in a file

the sleep is removable but i found that if you have a large list of urls 50+, and no sleep, it will try to open all the urls at once and this will cause them all to load a lot slower, also depending on the ram of your system sleep gives you a chance to close the tabs before they overload your ram, removing & >2/dev/null will yield unpredictable results.

for /F %i in (url_list.txt) do Firefox.exe -new-tab "%i"
2011-09-09 02:17:16
0

Firefox.exe needs to be in the path

To enhance: add a sleep...

url_list contains urls:

D:\>type url_list.txt

http://yahoo.com

google.com

http://fr.news.yahoo.com

rf() { for i in "$@"; do mv "$i" "$(pwgen 8 1).${i##*.}"; done }
2011-06-22 07:45:23
User: flatcap
Functions: mv
1

Give files a random name (don't ask why :-)

The function will rename files but maintain their extensions.

BUG: If a file doesn't have an extension it will end up with a dot at the end of the name.

The parameter '8' for pwgen controls the length of filenames - eight random characters.

domain=google.com; for ns in $(whois $domain | awk -F: '/Name Server/{print $2}'); do echo ">>> Nameservers for $domain from $a <<<"; dig @$ns $domain ns +short; echo; done;
2011-05-08 04:46:34
User: laebshade
Functions: awk dig echo whois
1

Change the $domain variable to whichever domain you wish to query.

Works with the majority of whois info; for some that won't, you may have to compromise:

domain=google.com; for a in $(whois $domain | grep "Domain servers in listed order:" --after 3 | grep -v "Domain servers in listed order:"); do echo ">>> Nameservers for $domain from $a

Note that this doesn't work as well as the first one; if they have more than 3 nameservers, it won't hit them all.

As the summary states, this can be useful for making sure the whois nameservers for a domain match the nameserver records (NS records) from the nameservers themselves.

for i in {21..79};do echo -e "\x$i";done | tr " " "\n" | shuf | tr -d "\n"
MIN=10;for ((i=MIN*60;i>=0;i--));do echo -ne "\r$(date -d"0+$i sec" +%H:%M:%S)";sleep 1;done
2011-02-20 11:56:28
User: flatcap
Functions: echo sleep
11

Countdown clock - Counts down from $MIN minutes to zero.

I let the date command do the maths.

This version doesn't use seq.

svnradd() { for i in $1/*;do if [ -e "$i" ];then if [ -d "$i" ];then svn add $i;svnradd $i;else svn add $i;fi; fi;done }
2011-02-16 03:33:57
User: lkjoel
0

This will recursively add files/directories in SVN.

Usage:

svnradd yourfile

or

svnradd yourdirectory

then:

svn commit

Notice: It might not work properly, and not all files could get added.

Since there is a limit on characters, I couldn't add failure/success notices.

If you want failure/success notices, download Terminal Enhancements (http://tenhancements.tk/ )

It is included on Base Features

for _a in {A..Z} {a..z};do _z=\${!${_a}*};for _i in `eval echo "${_z}"`;do echo -e "$_i: ${!_i}";done;done|cat -Tsv
2

This uses some tricks I found while reading the bash man page to enumerate and display all the current environment variables, including those not listed by the 'env' command which according to the bash docs are more for internal use by BASH. The main trick is the way bash will list all environment variable names when performing expansion on ${!A*}. Then the eval builtin makes it work in a loop.

I created a function for this and use it instead of env. (by aliasing env).

This is the function that given any parameters lists the variables that start with it. So 'aae B' would list all env variables starting wit B. And 'aae {A..Z} {a..z}' would list all variables starting with any letter of the alphabet. And 'aae TERM' would list all variables starting with TERM.

aae(){ local __a __i __z;for __a in "$@";do __z=\${!${__a}*};for __i in `eval echo "${__z}"`;do echo -e "$__i: ${!__i}";done;done; }

And my printenv replacement is:

alias env='aae {A..Z} {a..z} "_"|sort|cat -v 2>&1 | sed "s/\\^\\[/\\\\033/g"'

From: http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

for p in `ps L|cut -d' ' -f1`;do echo -e "`tput clear;read -p$p -n1 p`";ps wwo pid:6,user:8,comm:10,$p kpid -A;done
2

While going through the source code for the well known ps command, I read about some interesting things.. Namely, that there are a bunch of different fields that ps can try and enumerate for you. These are fields I was not able to find in the man pages, documentation, only in the source.

Here is a longer function that goes through each of the formats recognized by the ps on your machine, executes it, and then prompts you whether you would like to add it or not. Adding it simply adds it to an array that is then printed when you ctrl-c or at the end of the function run. This lets you save your favorite ones and then see the command to put in your .bash_profile like mine at : http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

Note that I had to do the exec method below in order to pause with read.

t ()

{

local r l a P f=/tmp/ps c='command ps wwo pid:6,user:8,vsize:8,comm:20' IFS=' ';

trap 'exec 66

exec 66 $f && command ps L | tr -s ' ' >&$f;

while read -u66 l >&/dev/null; do

a=${l/% */};

$c,$a k -${a//%/} -A;

yn "Add $a" && P[$SECONDS]=$a;

done

}

( x=`tput op` y=`printf %$((${COLUMNS}-6))s`;for i in {0..256};do o=00$i;echo -e ${o:${#o}-3:3} `tput setaf $i;tput setab $i`${y// /=}$x;done; )
6

This is super fast and an easy way to test your terminal for 256 color support. Unlike alot of info about changing colors in the terminal, this uses the ncurses termcap/terminfo database to determine the escape codes used to generate the colors for a specific TERM. That means you can switch your terminal and then run this to check the real output.

tset xterm-256color

at any rate that is some super lean code!

Here it is in function form to stick in your .bash_profile

aa_256 ()

{

( x=`tput op` y=`printf %$((${COLUMNS}-6))s`;

for i in {0..256};

do

o=00$i;

echo -e ${o:${#o}-3:3} `tput setaf $i;tput setab $i`${y// /=}$x;

done )

}

From my bash_profile: http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

while [[ COUNTER -le 10 && IFS=':' ]]; do for LINE in $(cat /tmp/list); do some_command(s) $LINE; done; COUNTER=$((COUNTER+1)); done
2010-09-01 15:09:59
User: slashdot
Functions: cat
0

At times I find that I need to loop through a file where each value that I need to do something with is not on a separate line, but rather separated with a ":" or a ";". In this instance, I create a loop within which I define 'IFS' to be something other than a whitespace character. In this example, I iterate through a file which only has one line, and several fields separated with ":". The counter helps me define how many times I want to repeat the loop.

for i in *; do echo '"'$i'"'; done
for f in t1.bmp t2.jpg t3.tga; do echo ${f%.*}.png; done
2010-07-09 00:38:53
User: zed
Functions: echo
7

The above is just a prove of concept based around the nested bash substitution. This could be useful in situations where you're in a directory with many filetypes but you only want to convert a few.

for f in *.bmp *.jpg *.tga; do convert $f ${f%.*}.png; done

or you can use ls | egrep to get more specific... but be warned, files with spaces will cause a ruckus with expansion but the bash for loop uses a space delimited list.

for f in $(ls | egrep "bmp$|jpg$|tga$"); do convert $f ${f%.*}.png; done

I'm guessing some people will still prefer doing it the sed way but I thought the concept of this one was pretty neat. It will help me remember bash substitutions a little better :-P

finit "1 2 3" 3 2 1 | while fnext i ; do echo $i; done;
2010-06-17 10:20:49
User: mechmind
Functions: echo
Tags: echo for counter
2

For this hack you need following function:

finit() { count=$#; current=1; for i in "$@" ; do echo $current $count; echo $i; current=$((current + 1)); done; }

and alias:

alias fnext='read cur total && echo -n "[$cur/$total] " && read'

Inspired by CMake progress counters.

alias dateh='date --help|sed -n "/^ *%%/,/^ *%Z/p"|while read l;do F=${l/% */}; date +%$F:"|'"'"'${F//%n/ }'"'"'|${l#* }";done|sed "s/\ *|\ */|/g" |column -s "|" -t'
21

If you have used bash for any scripting, you've used the date command alot. It's perfect for using as a way to create filename's dynamically within aliases,functions, and commands like below.. This is actually an update to my first alias, since a few commenters (below) had good observations on what was wrong with my first command.

# creating a date-based ssh-key for askapache.github.com

ssh-keygen -f ~/.ssh/`date +git-$USER@$HOSTNAME-%m-%d-%g` -C 'webmaster@askapache.com' # /home/gpl/.ssh/git-gplnet@askapache.github.com-04-22-10

# create a tar+gzip backup of the current directory

tar -czf $(date +$HOME/.backups/%m-%d-%g-%R-`sed -u 's/\//#/g' <<< $PWD`.tgz) . # tar -czf /home/gpl/.backups/04-22-10-01:13-#home#gpl#.rr#src.tgz .

I personally find myself having to reference

date --help

quite a bit as a result. So this nice alias saves me a lot of time. This is one bdash mofo. Works in sh and bash (posix), but will likely need to be changed for other shells due to the parameter substitution going on.. Just extend the sed command, I prefer sed to pretty much everything anyways.. but it's always preferable to put in the extra effort to go for as much builtin use as you can. Otherwise it's not a top one-liner, it's a lazyboy recliner.

Here's the old version:

alias dateh='date --help|sed "/^ *%%/,/^ *%Z/!d;s/ \+/ /g"|while read l;do date "+ %${l/% */}_${l/% */}_${l#* }";done|column -s_ -t'

This trick from my [ http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html bash_profile ]

for i in `ls ~/.mozilla/firefox/*/Cache`; do file $i | grep -i mpeg | awk '{print $1}' | sed s/.$//; done
2010-04-11 23:14:18
User: TuxOtaku
Functions: awk file grep sed
4

Ever gone to a site that has an MP3 embedded into a pesky flash player, but no download link? Well, this one-liner will yank the names of those tunes straight out of FF's cache in a nice, easy to read list. What you do with them after that is *ahem* no concern of mine. ;)

for f in $(ls *.xml.skippy); do mv $f `echo $f | sed 's|.skippy||'`; done
2009-11-19 21:36:26
User: argherna
Functions: ls mv sed
Tags: sed ls mv for
-2

For this example, all files in the current directory that end in '.xml.skippy' will have the '.skippy' removed from their names.

seg() { for b in $(echo $1); do for x in $(seq 10); do echo $b.$x; done; done }