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 bash from sorted by
Terminal - Commands tagged bash - 707 results
sortwc () { local L;while read -r L;do builtin printf "${#L}@%s\n" "$L";done|sort -n|sed -u 's/^[^@]*@//'; }
2010-05-20 20:13:52
User: AskApache
Functions: printf read sed sort
2

This provides a way to sort output based on the length of the line, so that shorter lines appear before longer lines. It's an addon to the sort that I've wanted for years, sometimes it's very useful. Taken from my http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

command ps wwo pid,user,group,vsize:8,size:8,sz:6,rss:6,pmem:7,pcpu:7,time:7,wchan,sched=,stat,flags,comm,args k -vsz -A|sed -u '/^ *PID/d;10q'
2

I've wanted this for a long time, finally just sat down and came up with it. This shows you the sorted output of ps in a pretty format perfect for cron or startup scripts. You can sort by changing the k -vsz to k -pmem for example to sort by memory instead.

If you want a function, here's one from my http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html

aa_top_ps(){ local T N=${1:-10};T=${2:-vsz}; ps wwo pid,user,group,vsize:8,size:8,sz:6,rss:6,pmem:7,pcpu:7,time:7,wchan,sched=,stat,flags,comm,args k -${T} -A|sed -u "/^ *PID/d;${N}q"; }
for i in $(find ~/.config/chromium/*/Extensions -name 'manifest.json'); do n=$(grep -hIr name $i| cut -f4 -d '"'| sort);u="https://chrome.google.com/extensions/detail/";ue=$(basename $(dirname $(dirname $i))); echo -e "$n:\n$u$ue\n" ; done
2010-05-18 15:16:36
User: new_user
Functions: cut find grep
2

Gives you a list for all installed chrome (chromium) extensions with URL to the page of the extension.

With this you can easy add a new Bookmark folder called "extensions" add every URL to that folder, so it will be synced and you can access the names from every computer you are logged in.

------------------------------------------------------------------------------------------------------------------

Only tested with chromium, for chrome you maybe have to change the find $PATH.

!:-
2010-05-15 15:12:47
User: new_user
Tags: bash edit
61
/usr/sbin/ab2 -f TLS1 -S -n 1000 -c 100 -t 2 http://www.google.com/

then

!:- http://www.commandlinefu.com/

is the same as

/usr/sbin/ab2 -f TLS1 -S -n 1000 -c 100 -t 2 http://www.commandlinefu.com/
tail -n2000 /var/www/domains/*/*/logs/access_log | awk '{print $1}' | sort | uniq -c | sort -n | awk '{ if ($1 > 20)print $1,$2}'
(for i in `find . -maxdepth 2 -name .svn | sed 's/.svn$//'`; do echo $i; svn info $i; done ) | egrep '^.\/|^URL'
2010-05-09 11:54:37
User: jespere
Functions: echo egrep info sed
0

If you have lots of subversion working copies in one directory and want to see in which repositories they are stored, this will do the trick. Can be convenient if you need to move to a new subversion server.

changing_assets = `s3cmd sync --dry-run -P -M --exclude=*.php --delete-removed #{preprod_release_dir}/web/ #{s3_bucket} | grep -E 'delete:|upload:' | awk '{print $2}' | sed s_#{preprod_release_dir}/web__`
2010-05-07 16:03:42
User: trivoallan
Functions: awk grep sed sync
2

Can be useful to granulary flush files in a CDN after they've been changed in the S3 bucket.

s3cmd ls s3://bucket.example.com | s3cmd del `awk '{print $4}'`
shopt -s extglob; for f in *.ttf *.TTF; do g=$(showttf "$f" 2>/dev/null | grep -A1 "language=0.*FullName" | tail -1 | rev | cut -f1 | rev); g=${g##+( )}; mv -i "$f" "$g".ttf; done
2

Just a quick hack to give reasonable filenames to TrueType and OpenType fonts.

I'd accumulated a big bunch of bizarrely and inconsistently named font files in my ~/.fonts directory. I wanted to copy some, but not all, of them over to my new machine, but I had no idea what many of them were. This script renames .ttf files based on the name embedded inside the font. It will also work for .otf files, but make sure you change the mv part so it gives them the proper extension.

REQUIREMENTS: Bash (for extended pattern globbing), showttf (Debian has it in the fontforge-extras package), GNU grep (for context), and rev (because it's hilarious).

BUGS: Well, like I said, this is a quick hack. It grew piece by piece on the command line. I only needed to do this once and spent hardly any time on it, so it's a bit goofy. For example, I find 'rev | cut -f1 | rev' pleasantly amusing --- it seems so clearly wrong, and yet it works to print the last argument. I think flexibility in expressiveness like this is part of the beauty of Unix shell scripting. One-off tasks can be be written quickly, built-up as a person is "thinking aloud" at the command line. That's why Unix is such a huge boost to productivity: it allows each person to think their own way instead of enforcing some "right way".

On a tangent: One of the things I wish commandlinefu would show is the command line HISTORY of the person as they developed the script. I think it's that conversation between programmer and computer, as the pipeline is built piece-by-piece, that is the more valuable lesson than any canned script.

for dir in $(find -type d ! -name CVS); do for file in $(find $dir -maxdepth 1 -type f); do rm $file; cvs delete $file; done; done
2010-04-27 16:03:33
User: ubersoldat
Functions: cvs dir file find rm
Tags: bash cvs delete rm
1

This will search all directories and ignore the CVS ones. Then it will search all files in the resulting directories and act on them.

G=$(stty -g);stty rows $((${LINES:-50}/2));top -n1; stty $G;unset G
3

One of my favorite ways to impress newbies (and old hats) to the power of the shell, is to give them an incredibly colorful and amazing version of the top command that runs once upon login, just like running fortune on login. It's pretty sweet believe me, just add this one-liner to your ~/.bash_profile -- and of course you can set the height to be anything, from 1 line to 1000!

G=$(stty -g);stty rows $((${LINES:-50}/2));top -n1; stty $G;unset G

Doesn't take more than the below toprc file I've added below, and you get all 4 top windows showing output at the same time.. each with a different color scheme, and each showing different info. Each window would normally take up 1/4th of your screen when run like that - TOP is designed as a full screen program. But here's where you might learn something new today on this great site.. By using the stty command to change the terminals internal understanding of the size of your terminal window, you force top to also think that way as well.

# save the correct settings to G var.

G=$(stty -g)

# change the number of rows to half the actual amount, or 50 otherwise

stty rows $((${LINES:-50}/2))

# run top non-interactively for 1 second, the output stays on the screen (half at least)

top -n1

# reset the terminal back to the correct values, and clean up after yourself

stty $G;unset G

This trick from my [ http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html bash_profile ], though the online version will be updated soon. Just think what else you could run like this!

Note 1: I had to edit the toprc file out due to this site can't handle that (uploads/including code). So you can grab it from [ http://www.askapache.com/linux-unix/bash-power-prompt.html my site ]

Note 2: I had to come back and edit again because the links weren't being correctly parsed

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 ]

shmore(){ local l L M="`echo;tput setab 4&&tput setaf 7` --- SHMore --- `tput sgr0`";L=2;while read l;do echo "${l}";((L++));[[ "$L" == "${LINES:-80}" ]]&&{ L=2;read -p"$M" -u1;echo;};done;}
2010-04-21 00:40:37
User: AskApache
Functions: echo read
6
SH
cat mod_log_config.c | shmore

or

shmore < mod_log_config.c

Most pagers like less, more, most, and others require additional processes to be loaded, additional cpu time used, and if that wasn't bad enough, most of them modify the output in ways that can be undesirable.

What I wanted was a "more" pager that was basically the same as running:

cat file

Without modifying the output and without additional processes being created, cpu used, etc. Normally if you want to scroll the output of cat file without modifying the output I would have to scroll back my terminal or screen buffer because less modifies the output.

After looking over many examples ranging from builtin cat functions created for csh, zsh, ksh, sh, and bash from the 80's, 90s, and more recent examples shipped with bash 4, and after much trial and error, I finally came up with something that satisifed my objective. It automatically adjusts to the size of your terminal window by using the LINES variable (or 80 lines if that is empty) so

This is a great function that will work as long as your shell works, so it will work just find if you are booted in single user mode and your /usr/bin directory is missing (where less and other pagers can be). Using builtins like this is fantastic and is comparable to how busybox works, as long as your shell works this will work.

One caveat/note: I always have access to a color terminal, and I always setup both the termcap and the terminfo packages for color terminals (and/or ncurses and slang), so for that reason I stuck the

tput setab 4; tput setaf 7

command at the beginning of the function, so it only runs 1 time, and that causes the -- SHMore -- prompt to have a blue background and bright white text.

This is one of hundreds of functions I have in my http://www.askapache.com/linux-unix/bash_profile-functions-advanced-shell.html">.bash_profile at http://www.askapache.com/">AskApache.com, but actually won't be included till the next update.

If you can improve this in any way at all please let me know, I would be very grateful! ( Like one thing I want is to be able to continue to the next screen by pressing any key instead of now having to press enter to continue)

APP=wine; if [ $(sudo apt-get --print-uris -y install $APP | sed -ne 's/^After this operation, \([0-9]\{1,\}\).*MB.*/\1/p') -gt 50 ]; then gnometris 2>/dev/null & sudo apt-get install $APP; else sudo apt-get install $APP; fi
2010-04-18 19:32:26
User: rkulla
Functions: install sed sudo
2

Change the APP variable's value to whatever you want to install. Depending on how fast your machine is, you'll want to adjust the value 50 to something else. You might also want to play a different game than Gnometris - just make sure it's a GUI game.

cat file1 ... fileN > combinedFile;
2010-04-17 01:00:04
User: GinoMan2440
Functions: cat
Tags: cat bash Linux
-4

the last person who posted used the most roundabout way to concatinate files, there's a reason there's a "conCATinate" command... Using this method, you also get to choose the order of the files, below another person just did *.txt > combined.txt which is fine but the order depends on the implementation of "cat" which is probably alphabetical order of filenames.

mplayer -playlist <(find $PWD -type f)
2010-04-17 00:20:08
User: rkulla
Functions: find
0

Press > or < to go to the next or previous track. Space to toggle play/pause, etc.

It creates a temp file descriptor. To see where the file descriptor gets created type: echo <(echo foo)

This works better than running find first, then piping to mplayer with xargs or something, because that won't let you use keyboard shortcuts.

cat *.txt >output.txt
ls | grep *.txt | while read file; do cat $file >> ./output.txt; done;
alias head='head -n $((${LINES:-`tput lines 2>/dev/null||echo -n 12`} - 2))'
26

Run the alias command, then issue

ps aux | head

and resize your terminal window (putty/console/hyperterm/xterm/etc) then issue the same command and you'll understand.

${LINES:-`tput lines 2>/dev/null||echo -n 12`}

Insructs the shell that if LINES is not set or null to use the output from `tput lines` ( ncurses based terminal access ) to get the number of lines in your terminal. But furthermore, in case that doesn't work either, it will default to using the deafault of 12 (-2 = 10).

The default for HEAD is to output the first 10 lines, this alias changes the default to output the first x lines instead, where x is the number of lines currently displayed on your terminal - 2. The -2 is there so that the top line displayed is the command you ran that used HEAD, ie the prompt.

Depending on whether your PS1 and/or PROMPT_COMMAND output more than 1 line (mine is 3) you will want to increase from -2. So with my prompt being the following, I need -7, or - 5 if I only want to display the commandline at the top. ( http://www.askapache.com/linux-unix/bash-power-prompt.html )

275MB/748MB

[7995:7993 - 0:186] 06:26:49 Thu Apr 08 [askapache@n1-backbone5:/dev/pts/0 +1] ~

In most shells the LINES variable is created automatically at login and updated when the terminal is resized (28 linux, 23/20 others for SIGWINCH) to contain the number of vertical lines that can fit in your terminal window. Because the alias doesn't hard-code the current LINES but relys on the $LINES variable, this is a dynamic alias that will always work on a tty device.

hb(){ sed "s/\($*\)/`tput setaf 2;tput setab 0;tput blink`\1`tput sgr0`/gI"; }
2010-04-07 08:45:26
User: AskApache
Functions: sed
-2
hb(){ sed "s/\($*\)/`tput setaf 2;tput setab 0;tput blink`\1`tput sgr0`/gI"; }

hb blinks, hc does a reverse color with background.. both very nice.

hc(){ sed "s/\($*\)/`tput setaf 0;tput setab 6`\1`tput sgr0`/gI"; }

Run this:

command ps -Hacl -F S -A f | hc ".*$PPID.*" | hb ".*$$.*"

Your welcome ;)

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

date +%A | cut -c $(( $(date +%A | wc -c) - 1 ))
2010-04-07 00:23:15
User: DaveQB
Functions: cut date wc
Tags: bash echo cut date wc
0

A command to find out what the day ends in. Can be edited slightly to find out what "any" output ends in.

NB: I haven't tested with weird and wonderful output.

function ends_in_y() { case $(date +%A) in *y ) true ;; * ) false ;; esac } ; ends_in_y && echo ok
2010-04-06 22:18:52
Functions: date echo false true
-1

The shell has perfectly adequate pattern matching for simple expressions.

function ends_in_y() { if [ `date +%A | sed -e 's/\(^.*\)\(.$\)/\2/'` == "y" ]; then echo 1; else echo 0; fi }
2010-04-06 20:14:34
User: allrightname
Functions: echo sed
-3

For those days when you need to know if something is happening because the day ends in "y".

du -cks * | sort -rn | while read size fname; do for unit in k M G T P E Z Y; do if [ $size -lt 1024 ]; then echo -e "${size}${unit}\t${fname}"; break; fi; size=$((size/1024)); done; done