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/
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.
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
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:
The tag function takes a tag name as its first argument, then a list of files which take that tag. The directory $HOME/tags/tagname will then hold symbolic links to each of the tagged files. This function was inspired by tmsu (found at https://bitbucket.org/oniony/tmsu/wiki/Home).
Example:
tag dog airedale.txt .shizturc weimeraner.pl
This will create $HOME/tags/dog which contains symbolic links to airedale.txt .shizturc and weimeraner.pl
Takes a directory name as an argument (defaults to current directory if no arguments are given). Prints the newest file in the directory.
The first argument is the interpreter for your script, the second argument is the name of the script to create.
This gives a very rough estimate of how many pages your text files will print on. Assumes 60 lines per page, and does not take long lines into account.
This is a quick and dirty way of creating key/value pairs in bash. Not as flexible as an associative array, but often powerful enough to be useful. For example, if I want to rename sets of files in a way that I can't do with wildcards, I'll create something like 'rename-me.txt'
filename_with_no_pattern:aa.txt\n
AnotherPieceOfText:ab.txt\n
/deeply/nested/file/with/no/pattern.txt:ac.txt\n
Then I'll traverse rename-me.txt with a read loop
cat rename-me.txt | while read line;
do
old=${line%:*};
new=${line#*:};
mv $old $new;
done
the --time-style argument to 'ls' takes several possible modifiers: full-iso, long-iso, iso, locale, +FORMAT.
The +FORMAT modifier uses the same syntax as date +FORMAT.
--time-style=+"%Y-%m-%d %H:%M:%S" strikes a happy medium between accuracy and verbosity:
ls -lart --time-style=long-iso
doesn't show time down to the nearest second,
ls -lart --time-style=full-iso
displays time to 10E-9 second resolution, but with no significant digits past the full seconds, also showing the timezone:
-rw-r--r-- 1 bchittenden bchittenden 0 2011-02-10 12:07:55.000000000 -0500 bar
This shell function takes a single argument, which is used as the base name of the .wav, .timing and .session files created. To create a screencast:
screencast test
type and talk ...
then type 'exit' or to exit the screencast.
test.wav will contain the audio from your screencast.
test.session will contain text and control characters needed to paint the screen
test.timing will contain timing information needed to synch individual keystrokes in test.session with the audio.
to play back:
aplay test.wav & scriptreplay test.{timing,session}
NOTE: because the shell function uses the variable "$!", and bash likes to expand '!' during history expansion, you will need to turn off bash's history before you enter the shell function.
This can be achieved using the command
set +H
This is one of those 'nothing' shell functions ...which I use all the time.
If the command contains spaces, it must be quoted, e.g.
vimcmd 'svn diff' /tmp/svndiff.out
If I want to keep the output of the command that I'm running, I use vimcmd. If I don't need to keep the output, I use this:
vim <( ... my command ... )
Robust means of moving all files up by a directory. Will handle dot files, filenames containing spaces, and filenames with almost any printable characters. Will not handle filenames containing a single-quote (but if you are moving those, it's time to go yell at whoever created them in the first place).
QR codes are those funny square 2d bar codes that everyone seems to be pointing their smart phones at.
Try the following...
qrurl http://xkcd.com
Then open qr.*.png in your favorite image viewer.
Point your the bar code reader on your smart phone at the code, and you'll shortly be reading xkcd on your phone.
URLs are not the only thing that can be encoded by QR codes... short texts (to around 2K) can be encoded this way, although this function doesn't do any URL encoding, so unless you want to do that by hand it won't be useful for that.
This command is useful if you want to copy the output of a series of commands to a file, for example if you want to pastebin the output from 'uname -a', 'lspci -vvv' and 'lsmod' for video driver trouble-shooting on your favorite Linux forum.
'log' takes all the following arguments as a command to execute, with STDOUT sent to /var/log/user.log. The command is echoed to the log before it is executed.
The advantages of using logger (as opposed to appending output from commands to a file) are 1) commands are always appended to the logs... you don't have to worry about clobbering your log file accidentally by using '>' rather than '>>' 2) logs are automatically cleaned up by logrotate.
The following functions allow you to mark the start and end of a section of /var/log/user.log.
startlog() { export LOGMARK=$(date +%Y.%m.%d_%H:%M:%S); echo "$LOGMARK.START" | logger -t $USER; }
then
endlog() { echo "$LOGMARK.END" | logger -t $USER; }
printlog will print all lines between $LOGMARK.START and $LOGMARK.END, removing everything that is prepended to each line by logger.
printlog() { sudo sed -n -e "/$LOGMARK.START/,/$LOGMARK.END/p" /var/log/user.log| sed "s/.*$USER: //"; }
The following command should dump just about all the information that you could possibly want about your linux configuration into the clipboard.
startlog; for cmd in 'uname -a' 'cat /etc/issue' 'dmesg' 'lsusb' 'lspci' 'sudo lshw' 'lsmod'; do log $cmd; done; endlog; printlog | xsel --clipboard
This is ready for a trip to http://pastebin.com/, and you don't have to worry about leaving temporary files lying around cluttering up $HOME.
Caveats: I'm sure that startlog, endlog, and printlog could use some cleanup and error checking... there are unchecked dependencies between printlog and endlog, as well as between endlog and startlog.
It might be useful for 'log' to send stderr to logger as well.
Use this if you're using vi editing mode.
Example use :
sudo vim /root/bin/ ##uh... autocomplete doesn't work... dd sudo ls /root/bin
##ah! that's the name of the file!
<p> sudo vim /root/bin/ ##resume here! Thanks readline!
By default, perltidy will create a file with the extension '.tdy'.
Fdiff will run the command given by the first argument against the input files given as the second and third arguments, and diff the results.
It will use 'diff' as the default diff program, but this can be changed by setting $DIFFCMD, e.g.
export DIFFCMD=vimdiff;
fdiff zcat 0716_0020005.raw.gz 0716_0030005.raw.gz
...
This function will work under bash, but requires the use of command substitution, which is not available under a strict ANSI shell.
A null operation with the name 'comment', allowing comments to be written to HISTFILE. Prepending '#' to a command will *not* write the command to the history file, although it will be available for the current session, thus '#' is not useful for keeping track of comments past the current session.
the '!' command in vi spawns a shell, then pipes all of the specified lines in the buffer through the command specified after '!', replacing all input lines with the result of the command.
You can record, then replay a series of keystrokes in vim. In command mode 'q', then a letter [a-zA-Z] starts macro recording mode. Enter a series of vim commands. When done, enter command mode again, and press 'q' to stop recording.
To replay, enter command mode, then press @{letter}
While editing a source file in vim, or using vimdiff to compare two or more files, the ':TOhtml' command can be used to export each buffer as an html file, including syntax highlighting and vimdiff colorization. If you are in insert mode in vim, you will have to type
:TOhtml
This will open a new buffer filled with html, which you can then save.
This function is used to sort selected lines of a text file to the end of that file. Especially useful in cases where human intervention is necessary to sort out parts of a file. Let's say that you have a text file which contains the words
rough
slimy
red
fluff
dough
For whatever reason, you want to sort all words rhyming with 'tough' to the bottom of the file, and all words denoting colors to the top, while keeping the order of the rest of the file intact.
'$EDITOR' will open, showing all of the lines in the given file, numbered with '0' padding. Adding a '~' to the beginning of the line will cause the line to sort to the end of the file, adding '!' will cause it to sort to the beginning.
First argument: string to put a box around.
Second argument: character to use for box (default is '=')
Same as command #4948, but shorter, and without the utility function.
The function 'box' takes either one or two arguments. The first argument is a line of text to be boxed, the second argument (optional) is a character to use to draw the box. By default, the drawing character will be '='.
The function 'n()' is a helper function used to draw the upper and lower lines of the box, its arguments are a length, and an character to print. (I used 'n' because 'line', 'ln' and 'l' are all commonly used)
underline() will print $1, followed by a series of '=' characters the width of $1. An optional second argument can be used to replace '=' with a given character.
This function is useful for breaking lots of data emitted in a for loop into sections which are easier to parse visually. Let's say that 'xxxx' is a very common pattern occurring in a group of CSV files.
You could run
grep xxxx *.csv
This would print the name of each csv file before each matching line, but the output would be hard to parse visually.
for i in *.csv; do printf "\n"; underline $i; grep "xxxx" $i; done
Will break the output into sections separated by the name of the file, underlined.
For those who hate navigating info pages, a shell function which will dump the contents to stdout, then page it through less, thus acting like 'man'.