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 atoponce from sorted by
Terminal - Commands by atoponce - 53 results
echo 0$(awk '/Pss/ {printf "+"$2}' /proc/$PID/smaps)|bc
2013-09-26 18:20:22
User: atoponce
Functions: awk echo
Tags: Linux awk echo bc proc
5

The "proportional set size" is probably the closest representation of how much active memory a process is using in the Linux virtual memory stack. This number should also closely represent the %mem found in ps(1), htop(1), and other utilities.

ip -o -4 addr show | awk -F '[ /]+' '/global/ {print $4}'
2013-04-09 16:34:39
User: atoponce
Functions: awk
1

Why use many different utilities all piped together, when you only need two?

curl --resolve subdomain.example.com:80:10.100.0.1 subdomain.example.com -I -s
2013-01-24 19:50:26
User: atoponce
Tags: curl
1

With the "--resolve" switch, you can avoid doing DNS lookups or edit the /etc/hosts file, by providing the IP address for a domain directly. Useful if you have many servers with different IP addresses behind a load balancer. Of course, you would loop it:

for IP in 10.11.0.{1..10}; do curl --resolve subdomain.example.com:80:$IP subdomain.example.com -I -s; done
expandurl() { curl -s "http://api.longurl.org/v2/expand?url=${1}&format=php" | awk -F '"' '{print $4}' }
2013-01-19 10:40:46
User: atoponce
Functions: awk
Tags: curl longurl
2

This relies on a public API from http://longurl.org. So, this has the weakness that if the service disappears, the function will break. However, it has the advantage that the shortened URL service will not be tracking your IP address and other metrics, but instead will track longurl.org. Thus, you can remain anonymous from the shortened URL services (although not anonymous from longurl.org). It does no sanity checking that you have provided an argument. If you do not provide one, "message" is displayed to STDOUT.

echo $((0x$(head -c5 /dev/random|xxd -ps)%6+1))
2012-09-21 02:16:42
User: atoponce
Functions: echo head
9

/dev/random is said to by cryptographically secure, and unpredictable, as it gathers data from external sources, influenced by human timing interactions with computers, to fill the entropy pool. As such, this is a quick way to do a true random fair-6 dice roll. Using this method, you could easily create passphrases with Diceware http://diceware.com.

for i in {1..5}; do echo -n $((0x$(head -c5 /dev/random|xxd -ps)%6+1)); done; echo
ssh-keygen -R $(dig +short host.domain.tld)
2012-01-19 15:08:50
User: atoponce
Functions: dig ssh ssh-keygen
2

Quick shortcut if you know the hostname and want to save yourself one step for looking up the IP address separately.

awk -F ':' '{print $1 | "sort";}' /etc/passwd
cp -r * .??* /dest
2011-12-16 23:41:03
User: atoponce
Functions: cp
Tags: mv rm cp
6

You could do the following, however, brace expansion with {} is not defined in POSIX, and therefore not guaranteed to work in all shells. But, if it does, it's more convenient (although it's certainly not less typing):

cp -r {*,.??*} /dest

Sometimes there are times when I need to cp(1), mv(1) or rm(1) files recursively, but don't want to traverse the previous directory by following ../../../../ etc out of the current directory. This command prevents that. The secret sauce is ".??*". The file globbing ensures that it must start with a dot, and be followed by at least two characters. So, three characters must exist in the filename, which eliminates "." and "..".

ssh user@host "tar -cf - /path/to/dir" | gzip > dir.tar.gz
2011-12-14 15:54:57
User: atoponce
Functions: gzip ssh
Tags: ssh tar gzip
6

The command uses ssh(1) to get to a remote host, uses tar(1) to archive a remote directory, prints the result to STDOUT, which is piped to gzip(1) to compress to a local file. In other words, we are archiving and compressing a remote directory to our local box.

awk 'NR >= 3 && NR <= 6' /path/to/file
2011-12-14 14:28:56
User: atoponce
Functions: awk
Tags: awk
7

This command uses awk(1) to print all lines between two known line numbers in a file. Useful for seeing output in a log file, where the line numbers are known. The above command will print all lines between, and including, lines 3 and 6.

python -c 'print "hello".encode("hex")'
2011-12-13 23:05:17
User: atoponce
Functions: python
2

You can use "decode()" in a similar manner:

python -c 'print "68656c6c6f".decode("hex")'
python -c 'print hex(1337)'
2011-12-13 22:03:10
User: atoponce
Functions: python
0

Python is always such much more readable than most shell scripting.

git rev-list --reverse HEAD | awk "/$(git log -n 1 --pretty="format:%h")/ {print NR}"
2011-11-15 21:49:32
User: atoponce
Functions: awk
Tags: git awk
-1

Git uses secure hash sums for its revision numbers. I'm sure this is fine and dandy for ultra-secure computing, but it's less than optimal for humans. Thus, this will give you sequential revision numbers in Git all the way from the first commit.

expandurl() { curl -sIL $1 | grep ^Location; }
2011-10-19 00:56:53
User: atoponce
Functions: grep
Tags: curl
5

curl(1) is more portable than wget(1) across Unices, so here is an alternative doing the same thing with greater portability. This shell function uses curl(1) to show what site a shortened URL is pointing to, even if there are many nested shortened URLs. This is a great way to test whether or not the shortened URL is sending you to a malicious site, or somewhere nasty that you don't want to visit. The sample output is from:

expandurl http://t.co/LDWqmtDM
expandurl() { wget -S $1 2>&1 | grep ^Location; }
2011-10-18 18:50:54
User: atoponce
Functions: grep wget
Tags: wget
0

This shell function uses wget(1) to show what site a shortened URL is pointing to, even if there are many nested shortened URLs. This is a great way to test whether or not the shortened URL is sending you to a malicious site, or somewhere nasty that you don't want to visit. The sample output is from:

expandurl http://t.co/LDWqmtDM
rsync -a /etc /destination
2011-10-18 13:07:55
User: atoponce
Functions: rsync
Tags: rsync
7

Yes, rsync(1) supports local directories. And, should anything change, it's trivial to run the command again, and grab only the changes, instead of the full directory.

python -c'for i in range(1,101):print"FizzBuzz"[i*i%3*4:8--i**4%5]or i'
2011-10-12 21:15:35
User: atoponce
Functions: python
5

A common programming question for interviewers to ask potential job candidates is to code "FizzBuzz". That is, if a number is divisible by 3, then it should display "Fizz". If a number is divisible by 5, it should display "Buzz". If it is divisible by both, then it should display "FizzBuzz". Otherwise, display the current number between 1 and 100.

ping -qc 10 server.tld | awk -F/ '/^rtt/ {print $5}'
2011-10-12 21:07:06
User: atoponce
Functions: awk ping
Tags: awk ping
-4

Quick and dirty one-liner to get the average ping(1) time from a server.

command -v bash
2011-09-26 10:17:41
User: atoponce
Functions: command
Tags: which command
4

it is generally advised to avoid using which(1) whenever possible. which(1) is usually a csh(1) script, or sometimes a compiled binary. It's output is highly variable from operating system to operating system, so platform independent scripts could become quite complicated with the logic. On HP-UX 10.20, for example, it prints "no bash in /path /path /path ..."; on OpenBSD 4.1, it prints "bash: Command not found."; on Debian (3.1 through 5.0 at least) and SuSE, it prints nothing at all; on Red Hat 5.2, it prints "which: no bash in (/path:/path:...)"; on Red Hat 6.2, it writes the same message, but on standard error instead of standard output; and on Gentoo, it writes something on stderr. And given all these differences, it's still variable based on your shell. This is why POSIX is king. See http://mywiki.wooledge.org/BashFAQ/081 for more ways on avoiding which(1).

zcat /usr/share/man/man1/man.1.gz | nroff -man | less
2011-09-07 01:13:57
User: atoponce
Functions: zcat
Tags: man less zcat nroff
0

As odd as this may be, I know of servers where the man(1) command is not installed, and there is not enough room on / to install it. However, zcat(1), nroff(1) and less(1) are. This is a way to read those documents without the proper tool to do so, as sad as this may seem. :)

gpg --gen-random --armor 1 30
2011-07-20 15:32:49
User: atoponce
Functions: gpg
10

According to the gpg(1) manual:

--gen-random 0|1|2 count

Emit count random bytes of the given quality level 0, 1 or 2. If count is not given or zero, an endless sequence of random bytes will be emitted. If used with --armor the output will be base64 encoded. PLEASE, don't use this command unless you know what you are doing; it may remove precious entropy from the system!

If your entropy pool is critical for various operations on your system, then using this command is not recommended to generate a secure password. With that said, regenerating entropy is as simple as:

du -s /

This is a quick way to generate a strong, base64 encoded, secure password of arbitrary length, using your entropy pool (example above shows a 30-character long password).

ssh-keygen -l -f ~/.ssh/known_hosts
2010-12-05 04:03:07
User: atoponce
Functions: ssh ssh-keygen
Tags: ssh
10

Will return the SSH server key information for each host you have in your ~/.ssh/known_hosts file, including key size, key fingerprint, key IP address or domain name, and key type.

gqG
2010-11-08 04:05:24
User: atoponce
Tags: vim
2

This is assuming that you're editing some file that has not been wrapped at 80 columns, and you want it to be wrapped. While in Vim, enter ex mode, and set the textwidth to 80 columns:

:set textwidth=80

Then, press:

gg

to get to the top of the file, and:

gqG

to wrap every line from the top to the bottom of the file at 80 characters.

Of course, this will lose any indentation blocks you've setup if typing up some source code, or doing type setting. You can make modifications to this command as needed, as 'gq' is the formatting command you want, then you could send the formatting to a specific line in the file, rather than to the end of the file.

gq49G

Will apply the format from your current cursor location to the 49th row. And so on.

ifconfig eth0 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1
2010-06-26 22:36:21
User: atoponce
Functions: cut grep ifconfig
Tags: ifconfig
2

Simple and easy. No regex, no search and replace. Just clean, built-in tools.

locate -S
2010-06-25 14:39:49
User: atoponce
Functions: locate
7

To start, you first need to make sure updatedb has been run/updatedb, and initialized the db:

su -l root -c updatedb

This locate command is provided through the mlocate package, installed by default on most GNU/Linux distributions. It's available on the BSDs as well. Not sure about support for proprietary UNIX systems. The output is self-explanatory- it provides an overview of how many directories and files are on your system.