As you start spending more and more time working on Linux command
line, you tend to learn some cool tricks that make your life easy and
save you lot of time. I have been working on Linux command line for many
years now and I have learned a lot of Linux command line tricks. Here
in this article, I will discuss some Linux command line tricks that I
find worth using in my day to day command line activities.
NOTE – All the examples in this article are tested on bash shell.
TIP – Did you know sudo works with wives too?! *lulz*
Very usefully Linux command line tricks…
1. How to delete files with leading or trailing spaces?
You might find yourself struggling with deleting files with leading or trailing spaces through ‘rm’ command on Linux command line.For example :
So we see that rm command says that this file does not exist. But you are pretty confident that file with such name exists. Then the only thing could be that this file name would be having leading or trailing spaces.$ rm tempFile rm: cannot remove `tempFile': No such file or directory
You can use double quotes to avoid this problem :
The above command worked in my case.$ rm "tempFile "
Note that if you do not want to use double quotes then ‘\ ‘ can be used. Here is an example :
Remember to add a space after back slash.$ rm tempFile\
2. How to delete files with names beginning with hyphen (-) ?
Sometimes you may find yourself stuck with a situation like this :You have to delete a file named -1mpFile.out
But, when you try using rm command, following error is produced :$ ls -1mpFile.out CPPfile.o libCfile.so mylinuxbook_new prog split
Even if you use double quotes, you get the following error :$ rm -1mpFile.out rm: invalid option -- '1' Try `rm ./-1mpFile.out' to remove the file `-1mpFile.out'. Try `rm --help' for more information.
So, rm command considers the hyphen ‘-’ as an indicator that some command line option will follow and so it treats ’1mpFile.out’ as an option. Hence the error.$ rm "-1mpFile.out" rm: invalid option -- '1' Try `rm ./-1mpFile.out' to remove the file `-1mpFile.out'. Try `rm --help' for more information.
Now, to tell ‘rm’ that the word beginning with hyphen is file name, you need to pass double hyphen (–) first. Here is an example :
So this should remove the file successfully.$ rm -- -1mpFile.out
Since this problem is generic ie you will observe this problem even while creating this file using ‘touch’ command etc. Double hyphen can be used with other commands too for the same purpose.
Here is another example of double hyphen but this time with touch and ls commands :
So we can safely use double hyphen (–) in a generic sense with different Linux commands.$ touch -1mpFile.out touch: invalid option -- '1' Try `touch --help' for more information. $ touch -- -1mpFile.out$ ls — -1mpFile.out -1mpFile.out
3. How to delete all files in a directory except some (with particular extensions) ?
Suppose you have a directory with lot of files and you want to delete all the files except some of them (with particular file extensions). This can be done in following way :Here is a directory containing lot of files :
Now, you want to delete all the files except .c and .py files.$ ls a.out Cfile.c file.c macro.c my_printf.c orig_file.orig stacksmash.c bfrovrflw.c cmd.c firstPYProgram.py main.c new_printf.c orig_file.rej test_strace.c bufrovrflw.c env.c helloworld.c my_fopen.c new.txt prog.c virtual_func.c
Here is what you can do :
So you can see that files with all other extensions got deleted.$ rm !(*.c|*.py) $ ls bfrovrflw.c Cfile.c env.c firstPYProgram.py macro.c my_fopen.c new_printf.c stacksmash.c virtual_func.c bufrovrflw.c cmd.c file.c helloworld.c main.c my_printf.c prog.c test_strace.c
4. How to create customized backup using touch and find commands?
Touch command in association with find command can be used to create customized backups.Suppose you want to create a backup of files that you created or changed in a directory between 9am and 5pm. For this, the very first step is to create two files temp1 and temp2 with timestamps as 9am and 5pm respectively.
These commands will create two files temp1 and temp2 with access and modification timestamps as 9am and 5pm respectively.$ touch -d "9am" temp1 $ touch -d "5pm" temp2
Let’s cross check these by using stat command:
So we see that timestamps was as expected. Now move to the directory where you want to create the backup of files. Here are the contents of the directory in my case :$ stat temp1 File: `temp1' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 806h/2054d Inode: 528534 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/stun) Gid: ( 1000/stun) Access: 2013-04-29 09:00:00.000000000 +0100 Modify: 2013-04-29 09:00:00.000000000 +0100 Change: 2013-04-29 16:06:05.982909491 +0100 Birth: - $ stat temp2 File: `temp2' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 806h/2054d Inode: 529476 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/stun) Gid: ( 1000/stun) Access: 2013-04-29 12:00:00.000000000 +0100 Modify: 2013-04-29 12:00:00.000000000 +0100 Change: 2013-04-29 16:06:12.090939793 +0100 Birth: -
Now, I create a directory named ‘bkup’ and run the following command :$ ls bfrovrflw.c Cfile.c env.c firstPYProgram.py macro.c my_fopen.c new_printf.c stacksmash.c virtual_func.c bufrovrflw.c cmd.c file.c helloworld.c main.c my_printf.c prog.c test_strace.c
The -newer and ! -newer options in command above will first find all the files with modification time between 9am and 5pm. Then the -exec option makes sure that the cp command is run for every result (‘{}’) of find command and the file is copied to ./bkup/ folder. The terminating ‘;‘ is the indication that cp command terminates here.$ find . -newer ../temp1 ! -newer ../temp2 -exec cp '{}' ./bkup/ ';'
Now, if you see the ‘bkup’ directroy, you’ll find all the backed up files there. Here is what I saw in my case :
As all the files were created between 9am and 5pm so all of them were backed up.$ cd bkup/ $ ls bfrovrflw.c Cfile.c env.c firstPYProgram.py macro.c my_fopen.c new_printf.c stacksmash.c virtual_func.c bufrovrflw.c cmd.c file.c helloworld.c main.c my_printf.c prog.c test_strace.c
5. Why rm command fails with error ‘Argument list too long’?
This usually happens when you have a directory containing huge number of files. When you do a rm -rf over it, you get something like :This issue can be resolved using following command (please switch over to the desired directory before running this command):-bash: /bin/rm: Argument list too long
The find command above will supply input to rm command in batches that it can process. This is one of the fastest method to delete files.find * -xdev -exec rm -f '{}' ';'
6. How to search for all the files in a directory containing a particular string?
This can be easily achieved using grep command.Here are a couple of examples :
If it is desired to view the lines where the string is used in the file, then ‘find’ command can be used with ‘xargs’ and ‘grep’ command in the following way :$ grep -l "printf" *.c bfrovrflw.c bufrovrflw.c Cfile.c cmd.c env.c file.c helloworld.c macro.c main.c my_fopen.c my_printf.c new_printf.c prog.c stacksmash.c test_strace.c $ grep -l "buff" *.c bfrovrflw.c
So we see that even the lines containing the string “buff” were displayed in the output.$ find ./ -name "*.c" | xargs grep "buff" ./bfrovrflw.c: char buff[15]; ./bfrovrflw.c: gets(buff); ./bfrovrflw.c: if(strcmp(buff, "MyLinuxBook"))
7. How to Empty a file using ‘>’ operator ?
Suppose you want to empty a file from command line.Here is how easily you can do it :
This will delete all the contents of the file ‘logfile’ and empty it.$ > [complete file path]For example :
$ > ./logfile
8. How to search man pages for a particular string?
You might have used Linux man pages to understand more about a command, function etc. But, what if you want to know which man pages discuss about a particular topic. For example, what if I want to know that which man pages discuss about ‘login’?Well, there exists an option -k through which you can do this. Here is an example :
So we see that all the man pages that discuss about ‘login’ were displayed in the output.$ man -k login access.conf (5) - the login access control table file add-shell (8) - add shells to the list of valid login shells chsh (1) - change login shell faillog (5) - login failure logging file faillog (8) - display faillog records or set login failure limits getlogin (3) - get username getlogin_r (3) - get username gnome-session-properties (1) - Configure applications to start on login hotot (7) - lightweight & opensource microbloging client issue (5) - prelogin message and identification file lastlog (8) - reports the most recent login of all users or of a given user login (1) - begin session on the system login (3) - write utmp and wtmp entries login.defs (5) - shadow password suite configuration login_tty (3) - tty utility functions logname (1) - print user's login name ... ... ...
9. How to redirect stderr output messages to a file?
It so happens mostly that standard commands/programs/services stream normal log messages to stdout while error log messages to stderr stream. Now, if you just do something like :$ [some-command] > logfileThen only the messages that were directed to stdout would be redirected to the file ‘logfile’ but no message that was directed to stderr would be redirected to the file.
Here is an example :
So we see that this time the error was redirected to the file successfully. Please note that 2>&1 combines both stdout and stderr streams to stdout stream only.$ touch new > /home/stun/derp_test/logfile touch: cannot touch `new': Permission denied $ cat /home/stun/derp_test/logfile $So we see that error was not redirected to the log file.
Now, to correct this, do something like :
$ touch new > /home/stun/derp_test/logfile 2>&1 $ cat /home/stun/derp_test/logfile touch: cannot touch `new': Permission denied
10. How to follow multiple log files on the go?
If it is required to follow multiple log files as they are being updated then this can be done through tail command.Suppose I want to monitor two log files ‘logfile’ and ‘logfile1′ simultaneously then I will use the tail command as follows :
So you can see that dynamic updates to these log files can easily be monitored through tail command.$ tail -f logfile logfile1 ==> logfile <== ==> logfile1 <== ==> logfile <== hi ==> logfile1 <== hello
11. How to make a command not to show up in the output of ‘history’ command?
Well, sometimes you would want to run a command but do not want it to appear in the output of Linux history command.You can achieve this by inserting a space before you type the command on prompt.
Here is an example :
Note that there is a space between ‘$’ and ‘df’.$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda6 29640780 6174904 21960188 22% / udev 1536752 4 1536748 1% /dev tmpfs 617620 892 616728 1% /run none 5120 0 5120 0% /run/lock none 1544040 156 1543884 1% /run/shm
Now, let’s confirm whether this command appears in the output of ‘history’ :
The df command was not captured in the output of history command.$ history | grep df 1633 ls *.pdf 1634 mv LinuxCommandsPart1.pdf LinuxCommandsPart1 2245 history | grep df
12. How to simulate on-screen typing just like you see in movies?
Well, to simulate typing just like you see in movies, use ‘pv’ command.Try this out :
Check the output for yourself.echo "You can simulate on-screen typing just like in the movies" | pv -qL 10
13. How to escape the aliased version of a command?
The alias command, as we all know is used to create aliases of the commands that act as short cuts and save time.For example, I have created alias of ls command such that whenever I execute ls, its ‘ls -lart’ that gets executed.
Now, if I ever intend to escape the alias and want to execute only ls, then I can do this by beginning the command with a backslash ie ‘\’.$ alias ls='ls -lart'
Here is an example :
So we see that the original ls command was executed.$ \ls 1 CPPfile.o libCPPfile.so mylinuxbook_new prog.c stacksmash.c
NOTE – If you want to suppress an alias for a whole login session, you can use ‘unalias’ command for that.
14. How to make efficient use of Linux command line history using !! and ! ?
Double exclamation ie ‘!!’ represents the last run command on the shell. Here is an example :$ uname -a Linux stun-Inspiron-1525 3.2.0-36-generic-pae #57-Ubuntu SMP Tue Jan 8 22:01:06 UTC 2013 i686 i686 i386 GNU/Linux $ !! uname -a Linux stun-Inspiron-1525 3.2.0-36-generic-pae #57-Ubuntu SMP Tue Jan 8 22:01:06 UTC 2013 i686 i686 i386 GNU/LinuxSo what best can we do with !! ?
Well, firstly, you can extend the command easily. Here is an example :
Also, it so happens many times that you run a command and you get an error that the command requires root privileges. Then you press the ‘up arrow’ key + home key + write ‘sudo’ . Well all this can be avoided using !!. Here is an example :$ !! | grep Linux uname -a | grep Linux Linux stun-Inspiron-1525 3.2.0-36-generic-pae #57-Ubuntu SMP Tue Jan 8 22:01:06 UTC 2013 i686 i686 i386 GNU/Linux
Sometimes you would like to append a command to existing shell script or would like to create a new shell script, then you can use ‘!!’ to the task easily. Here is an example :$ touch new_binary touch: cannot touch `new_binary': Permission denied $ sudo !! sudo touch new_binary [sudo] password for stun: $ ls new_binary new_binary
$ ls -lart /home/stun/derp_test/*.py -rw-rw-r-- 1 stun stun 50 Mar 1 00:23 /home/stun/derp_test/firstPYProgram.py
So we see that this way !! proves to be easy and time saving. Now, lets come to single exclamation ie ‘!’ . Unlike double exclamation ie ‘!!’, through single exclamation ‘!’, we can access any previously run command that exists in command line history. Here are some examples : Use serial number from output of history command to run a particular command$ echo !! > script.sh echo ls -lart /home/stun/derp_test/*.py > script.sh $ cat script.sh ls -lart /home/stun/derp_test/firstPYProgram.py
$ history ... ... ... 2039 uname -a | grep Linux 2040 dmesg 2041 clear 2042 cd bin 2043 clear 2044 pwd 2045 touch new_binary 2046 sudo touch new_binary 2047 ls new_binary 2048 history $ !2039 uname -a | grep Linux Linux stun-Inspiron-1525 3.2.0-36-generic-pae #57-Ubuntu SMP Tue Jan 8 22:01:06 UTC 2013 i686 i686 i386 GNU/LinuxSo we see that command number 2039 was run through single exclamation ‘!’ without having to type or copy paste the command again.
You can use negative integer values with ‘!’ to run second last command, third last command, fourth last command…and so on.
Here is an example :
$history ... ... ... 2049 ! 2039 2050 uname -a | grep Linux 2051 history $ !-2 uname -a | grep Linux Linux stun-Inspiron-1525 3.2.0-36-generic-pae #57-Ubuntu SMP Tue Jan 8 22:01:06 UTC 2013 i686 i686 i386 GNU/LinuxRun a new command with argument of previous command
Here is an example :
So we see that ‘!$’ can be used to fetch argument from previous command and use it with the current command.$ ls /home/stun/derp_test/*.py /home/stun/derp_test/firstPYProgram.py $ ls -lart !$ ls -lart /home/stun/derp_test/*.py -rw-rw-r-- 1 stun stun 50 Mar 1 00:23 /home/stun/derp_test/firstPYProgram.py
In case of two arguments, use carrot ‘!^’ to access first argument Here is an example :
$ ls /home/stun/derp_test/*.py /home/stun/derp_test/*.txt /home/stun/derp_test/file.txt /home/stun/derp_test/output.txt /home/stun/derp_test/sort.txt /home/stun/derp_test/firstPYProgram.py /home/stun/derp_test/sort1.txt /home/stun/derp_test/test.txt /home/stun/derp_test/input.txt /home/stun/derp_test/sort2.txt
So we see that through ‘!^’ we can access the first argument of the previous run command. To access the any other argument (of previous run command) in current command, ‘![prev command name]:[argument number]‘ can be used. Here is an example :$ ls -lart !^ ls -lart /home/stun/derp_test/*.py -rw-rw-r-- 1 stun stun 50 Mar 1 00:23 /home/stun/derp_test/firstPYProgram.py
So this way, the second argument (of the previous command) was accessed. To access all the arguments of a previously run command, use ‘!*’ Here is an example :$ ls !ls:2 ls /home/stun/derp_test/*.txt /home/stun/derp_test/file.txt /home/stun/derp_test/sort1.txt /home/stun/derp_test/test.txt /home/stun/derp_test/input.txt /home/stun/derp_test/sort2.txt /home/stun/derp_test/output.txt /home/stun/derp_test/sort.txt
Use ‘![keyword]‘ to run the last command starting with [keyword] Here is an example :$ ls -lart !* ls -lart /home/stun/derp_test/*.py /home/stun/derp_test/*.txt -r--r--r-- 1 stun stun 50 Oct 24 2012 /home/stun/derp_test/output.txt -r--r--r-- 1 stun stun 7 Nov 10 13:46 /home/stun/derp_test/input.txt -r--r--r-- 1 stun stun 8 Dec 7 20:38 /home/stun/derp_test/sort1.txt -r--r--r-- 1 stun stun 8 Dec 7 20:39 /home/stun/derp_test/sort2.txt -r--r--r-- 1 stun stun 14 Dec 14 20:45 /home/stun/derp_test/file.txt -r--r--r-- 1 stun stun 41 Jan 23 20:42 /home/stun/derp_test/sort.txt -rw-rw-r-- 1 stun stun 50 Mar 1 00:23 /home/stun/derp_test/firstPYProgram.py -rw-rw-r-- 1 stun stun 0 Mar 10 15:31 /home/stun/derp_test/test.txt
So we see that the last ls command was executed. This way you can just write the first keyword of the command (which is command name usually) and you do not need to write the complete command. Single exclamation ‘!’ will do it for you.$ !ls ls -lart /home/stun/derp_test/*.py -rw-rw-r-- 1 stun stun 50 Mar 1 00:23 /home/stun/derp_test/firstPYProgram.py
15. How to switch between directories efficiently?
Working on Linux command line means switching between lot of directories. You are in a directory ‘A’, then you move to directory ‘B’. Now you want to come back to directory ‘A’. Typing the complete directory path for ‘A’ can be cumbersome sometimes. For this you can use ‘cd -’ short cut. Here is an example :$ pwd /home/stun $ cd /usr/local/bin/ $ cd - /home/stunSo we see that it’s easy to switch between two directories using cd- .
But, ‘cd -’ resolves only a partial problem. It can only switch you back to last directory only. What if you switch between multiple directories and then want to come back to the first or some other desired directory? I mean, suppose you are in a directory ‘A’, then you switch to directories ‘B’ -> ‘C’ -> ‘D’ -> ‘E’ and then you want to again go back to directory ‘A’.
Well, for this, you can use the combination of ‘pushd’ and ‘popd’.
Here is an example :
$ pwd /home/stun $ pushd /home/stun ~ ~ $ cd /usr $ cd /tmp $ cd /proc $ popd ~ $ pwd /home/stunAs you can see, first you pass the desired directory (to which you want to come back eventually) as argument to ‘pushd’ and then through ‘popd’ you can actually trigger a directory switch to that directory from anywhere on the command prompt.
Anyhow that’s for now, be free to comment and tip me more commands you think are useful i’ve could add to this “guide”.
0 comments:
Post a Comment