In this article I’d like to explain the top one-liners from the commandlinefu.com. It’s a user-driven website where people get to choose the best and most useful shell one-liners.
But before I do that, I want to take the opportunity and link to a few of my articles that I wrote some time ago on working efficiently in the command line:
- Working efficiently in bash with vi keyboard shortcuts.
- Working efficiently in bash with emacs keyboard shortcuts.
- The definitive guide to bash command line history.
- Fun article on set operations in the shell.
#1. Run the last command as root
$ sudo !!We all know what the
sudo
command does - it runs the command as another user, in this case, it runs the command as superuser because no other user was specified. But what’s really interesting is the bang-bang !!
part of the command. It’s called the event designator. An event designator references a command in shell’s history. In this case the event designator references the previous command. Writing !!
is the same as writing !-1
. The -1
refers to the last command. You can generalize it, and write !-n
to refer to the n-th previous command. To view all your previous commands, type history
.I wrote about event designators in much more detail in my article “The Definitive Guide to Bash Command Line History.” The article also comes with a printable cheat sheet for working with the history.
#2. Serve the current directory at http://localhost:8000/
$ python -m SimpleHTTPServerThis one-liner starts a web server on port 8000 with the contents of current directory on all the interfaces (address 0.0.0.0), not just localhost. If you have “
index.html
” or “index.htm
” files, it will serve those, otherwise it will list the contents of the currently working directory.It works because python comes with a standard module called
SimpleHTTPServer
. The -m
argument makes python to search for a module named SimpleHTTPServer.py
in all the possible system locations (listed in sys.path
and $PYTHONPATH
shell variable). Once found, it executes it as a script. If you look at the source code of this module, you’ll find that this module tests if it’s run as a script if __name__ == '__main__'
, and if it is, it runs the test()
method that makes it run a web server in the current directory.To use a different port, specify it as the next argument:
$ python -m SimpleHTTPServer 8080This command runs a HTTP server on all local interfaces on port 8080.
#3. Save a file you edited in vim without the needed permissions
:w !sudo tee %This happens to me way too often. I open a system config file in vim and edit it just to find out that I don’t have permissions to save it. This one-liner saves the day. Instead of writing the while to a temporary file
:w /tmp/foobar
and then moving the temporary file to the right destination mv /tmp/foobar /etc/service.conf
, you now just type the one-liner above in vim and it will save the file.Here is how it works, if you look at the vim documentation (by typing
:he :w
in vim), you’ll find the reference to the command :w !{cmd}
that says that vim runs {cmd}
and passes it the contents of the file as standard input. In this one-liner the {cmd}
part is the sudo tee %
command. It runs tee %
as superuser. But wait, what is %
? Well, it’s a read-only register in vim that contains the filename of the current file! Therefore the command that vim executes becomes tee current_filename
, with the current directory being whatever the current_file
is in. Now what does tee
do? The tee
command takes standard input and write it to a file! Rephrasing, it takes the contents of the file edited in vim, and writes it to the file (while being root)! All done!#4. Change to the previous working directory
cd -Everyone knows this, right? The dash “
-
” is short for “previous working directory.” The previous working directory is defined by $OLDPWD
shell variable. After you use the cd
command, it sets the $OLDPWD
environment variable, and then, if you type the short version cd -
, it effectively becomes cd $OLDPWD
and changes to the previous directory.Don’t forget that if you wish to change to directory named “
-
“, you have to escape the future arguments by double dashes:cd -- -This
cd
s to directory named “-
“.#5. Run the previous shell command but replace string “foo” with “bar”
^foo^bar^This is another event designator. This one is for quick substitution. It replaces
foo
with bar
and repeats the last command. It’s actually a shortcut for !!:s/foo/bar/
. This one-liner applies the s
modifier to the !!
event designator. As we learned from one-liner #1, the !!
event designator stands for the previous command. Now the s
modifier stands for substitute (greetings to sed) and it substitutes the first word with the second word.Not that this one-liner replaces just the first word in the previous command. To replace all words, add the
g
modifer (g
for global):!!:gs/foo/barAgain, see my article “The Definitive Guide to Bash Command Line History.” I explain all this stuff in great detail.
#6. Quickly backup or copy a file
cp filename{,.bak}This one-liner copies the file named
filename
to a file named filename.bak
. Here is how it works. It uses brace expansion to construct a list of arguments for the cp
command. Brace expansion is a mechanism by which arbitrary strings may be generated. In this one-liner filename{,.bak}
gets brace expanded to filename filename.bak
and puts in place of the brace expression. The command becomes cp filename filename.bak
and file gets copied.Talking more about brace expansion, you can do all kinds of combinatorics with it. Here is a fun application:
echo {a,b,c}{a,b,c}{a,b,c}It generates all the possible strings 3-letter from the set
{a, b, c}
:aaa aab aac aba abb abc aca acb acc baa bab bac bba bbb bbc bca bcb bcc caa cab cac cba cbb cbc cca ccb cccAnd here is how to generate all the possible 2-letter strings from the set of
{a, b, c}
:$ echo {{a,b,c}{a,b,c}}It produces:
aa ab ac ba bb bc ca cb ccIf you liked this, you may also like my article where I defined a bunch of set operations (such as intersection, union, symmetry, powerset, etc) by using just shell commands. The article is called “Set Operations in the Unix Shell.” (And since I have sets in the shell, I will soon write articles on on “Combinatorics in the Shell” and “Algebra in the Shell“. Fun topics to explore. Perhaps even “Topology in the Shell” :))
#7. mtr - traceroute and ping combined
mtr google.comMTR, bettern known as “Matt’s Traceroute” combines both
traceroute
and ping
command. After each successful hop, it sends a ping request to the found machine, this way it produces output of both traceroute
and ping
to better understand the quality of link. If it finds out a packet took an alternative route, it displays it, and by default it keeps updating the statistics so you knew what was going on in real time.#8. Find the last command that begins with “whatever,” but avoid running it
!whatever:pAnother use of event designators. The
!whatever
designator searches the shell history for the most recently executed command that starts with whatever
. But instead of executing it, it prints it. The :p
modifier makes it print instead of executing.Once again, see my article “The Definitive Guide to Bash Command Line History.” I explain all this stuff in great detail.
#9. Copy your public-key to remote-machine for public-key authentication
ssh-copy-id remote-machineThis one-liner copies your public-key, that you generated with
ssh-keygen
(either SSHv1 file identity.pub or SSHv2 file id_rsa.pub) to the remote-machine
and places it in ~/.ssh/authorized_keys
directory. This ensures that the next time you try to log into that machine, public-key authentication (commonly referred to as “passwordless authentication.”) will be used instead of the regular password authentication.If you wished to do it yourself, you’d have to take the following steps:
your-machine$ scp ~/.ssh/identity.pub remote-machine your-machine$ ssh remote-machine remote-machine$ cat identity.pub > ~/.ssh/authorized_keysThis one-liner saves a great deal of typing.
#10. Capture video of a linux desktop
ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpgA pure coincidence, I have done so much video processing with ffmpeg that I know what most of this command does without looking much in the manual.
The ffmpeg generally can be descibed as a command that takes a bunch of options and the last option is the output file. In this case the options are
-f x11grab -s wxga -r 25 -i :0.0 -sameq
and the output file is /tmp/out.mpg
.Here is what the options mean:
-f x11grab
makes ffmpeg to set the input video format as x11grab. The X11 framebuffer has a specific format it presents data in and it makes ffmpeg to decode it correctly.-s wxga
makes ffmpeg to set the size of the video to wxga which is shortcut for 1366×768. This is a strange resolution to use, I’d just write-s 800x600
.-r 25
sets the framerate of the video to 25fps. Also a strange thing to do because 25fps is the default.-i :0.0
sets the video input file to X11 display 0.0 at localhost.-sameq
preserves the quality of input stream. It’s unreasonable, the file will be too big. A reasonable thing to do is to set it to 250kbit/s via-b 250kbit/s
for YouTube video quality, or 500kbit/s for a better quality.
-i :0.0
to -i host:0.0
.If you’re interested in ffmpeg, here are my other articles on ffmpeg that I wrote while ago:
- How to Extract Audio Tracks from YouTube Videos
- Converting YouTube Flash Videos to a Better Format with ffmpeg
Have fun. See ya!
No comments:
Post a Comment