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:
Why use many different utilities all piped together, when you only need two?
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
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.
/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
Quick shortcut if you know the hostname and want to save yourself one step for looking up the IP address separately.
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 "..".
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.
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.
You can use "decode()" in a similar manner:
python -c 'print "68656c6c6f".decode("hex")'
Python is always such much more readable than most shell scripting.
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.
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
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
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.
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.
Quick and dirty one-liner to get the average ping(1) time from a server.
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).
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. :)
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).
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.
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.
Simple and easy. No regex, no search and replace. Just clean, built-in tools.
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.
Requires figlet. Other than that, this should be portable enough across all the Bourne-compatible shells (sh, bash, ksh, zsh, etc).
Produces a massive number using figlet that counts down the number of seconds for any given minute interval. For example, here's a 4-minute timer:
i=$((4*60)); while [ $i -gt 0 ]; do clear; echo $i | figlet; sleep 1; i=$(($i-1)); done;
And a 1-minute timer:
i=$((1*60)); while [ $i -gt 0 ]; do clear; echo $i | figlet; sleep 1; i=$(($i-1)); done;