Thursday, March 7, 2013

15 Linux Yum Command Examples – Install, Uninstall, Update Packages

nstalling, removing, and updating packages is a typical activity on Linux. Most of the Linux distributions provides some kind of package manager utility. For example, apt-get, dpkg, rpm, yum, etc.
On some Linux distributions, yum is the default package manager.
Yum stands for Yellowdog Updater Modified.
This article explains 15 most frequently used yum commands with examples.

1. Install a package using yum install

To install a package, do ‘yum install packagename’. This will also identify the dependencies automatically and install them.
The following example installs postgresql package.
# yum install postgresql.x86_64
Resolving Dependencies
Install       2 Package(s)
Is this ok [y/N]: y

Package(s) data still to download: 3.0 M
(1/2): postgresql-9.0.4-5.fc15.x86_64.rpm          | 2.8 MB     00:11
(2/2): postgresql-libs-9.0.4-5.fc15.x86_64.rpm    | 203 kB     00:00
------------------------------------------------------------------
Total                                        241 kB/s | 3.0 MB     00:12     

Running Transaction
  Installing : postgresql-libs-9.0.4-5.fc15.x86_64             1/2
  Installing : postgresql-9.0.4-5.fc15.x86_64                   2/2 

Complete!
By default ‘yum install’, will prompt you to accept or decline before installing the packages. If you want yum to install automatically without prompting, use -y option as shown below.
# yum -y install postgresql.x86_64

2. Uninstall a package using yum remove

To remove a package (along with all its dependencies), use ‘yum remove package’ as shown below.
# yum remove  postgresql.x86_64
Resolving Dependencies
---> Package postgresql.x86_64 0:9.0.4-5.fc15 will be erased

Is this ok [y/N]: y

Running Transaction
  Erasing    : postgresql-9.0.4-5.fc15.x86_64       1/1 

Removed:
  postgresql.x86_64 0:9.0.4-5.fc15

Complete!

3. Upgrade an existing package using yum update

If you have a older version of a package, use ‘yum update package’ to upgrade it to the latest current version. This will also identify and install all required dependencies.
# yum update postgresql.x86_64

4. Search for a package to be installed using yum search

If you don’t know the exact package name to be installed, use ‘yum search keyword’, which will search all the packages that matches the ‘keyword’ and display it.
The following examples searches the yum repository for all the packages that matches the keyword ‘firefox’ and lists the available packages.
# yum search firefox
Loaded plugins: langpacks, presto, refresh-packagekit
============== N/S Matched: firefox ======================
firefox.x86_64 : Mozilla Firefox Web browser
gnome-do-plugins-firefox.x86_64 : gnome-do-plugins for firefox
mozilla-firetray-firefox.x86_64 : System tray extension for firefox
mozilla-adblockplus.noarch : Adblocking extension for Mozilla Firefox
mozilla-noscript.noarch : JavaScript white list extension for Mozilla Firefox

Name and summary matches only, use "search all" for everything.

5. Display additional information about a package using yum info

Once you search for a package using yum search, you can use ‘yum info package’ to view additional information about the package.
The following examples displays additional information about the samba-common package.
# yum info samba-common.i686
Loaded plugins: langpacks, presto, refresh-packagekit
Available Packages
Name        : samba-common
Arch        : i686
Epoch       : 1
Version     : 3.5.11
Release     : 71.fc15.1
Size        : 9.9 M
Repo        : updates
Summary     : Files used by both Samba servers and clients
URL         : http://www.samba.org/
License     : GPLv3+ and LGPLv3+
Description : Samba-common provides files necessary for both the server and client
            : packages of Samba.

6. View all available packages using yum list

The following command will list all the packages available in the yum database.
# yum list | less

7. List only the installed packages using yum list installed

To view all the packages that are installed on your system, execute the following yum command.
# yum list installed | less

8. Which package does a file belong to? – Use yum provides

Use ‘yum provides’ if you like to know which package a particular file belongs to. For example, if you like to know the name of the package that has the /etc/sysconfig/nfs file, do the following.
# yum provides /etc/sysconfig/nfs
Loaded plugins: langpacks, presto, refresh-packagekit
1:nfs-utils-1.2.3-10.fc15.x86_64 : NFS utilities and supporting clients and
                                 : daemons for the kernel NFS server
Repo        : fedora
Matched from:
Filename    : /etc/sysconfig/nfs

1:nfs-utils-1.2.4-1.fc15.x86_64 : NFS utilities and supporting clients and
                                : daemons for the kernel NFS server
Repo        : updates
Matched from:
Filename    : /etc/sysconfig/nfs

1:nfs-utils-1.2.4-1.fc15.x86_64 : NFS utilities and supporting clients and
                                : daemons for the kernel NFS server
Repo        : installed
Matched from:
Other       : Provides-match: /etc/sysconfig/nfs

9. List available software groups using yum grouplist

In yum, several related packages are grouped together in a specific group. Instead of searching and installing all the individual packages that belongs to a specific function, you can simply install the group, which will install all the packages that belongs to the group.
To view all the available software groups execute ‘yum grouplist’ as shown below. The output is listed in three groups–Installed Groups, Installed Language Groups and Available Groups.
# yum grouplist

Installed Groups:
   Administration Tools
   Base
   Design Suite
   ....

Installed Language Groups:
   Arabic Support [ar]
   Armenian Support [hy]
   Bengali Support [bn]
   ....

Available Groups:
   Authoring and Publishing
   Books and Guides
   Clustering
   DNS Name Server
   Development Libraries
   Development Tools
   Directory Server
   Dogtag Certificate System
   ...

10. Install a specific software group using yum groupinstall

To install specific software group, use groupinstall option as shown below. In the following example, ‘DNS Name Server’ group contains bind and bind-chroot.
# yum groupinstall 'DNS Name Server'

Dependencies Resolved
Install       2 Package(s)
Is this ok [y/N]: y

Package(s) data still to download: 3.6 M
(1/2): bind-9.8.0-9.P4.fc15.x86_64.rpm             | 3.6 MB     00:15
(2/2): bind-chroot-9.8.0-9.P4.fc15.x86_64.rpm   |  69 kB     00:00
-----------------------------------------------------------------
Total               235 kB/s | 3.6 MB     00:15

Installed:
  bind-chroot.x86_64 32:9.8.0-9.P4.fc15

Dependency Installed:
  bind.x86_64 32:9.8.0-9.P4.fc15

Complete!
Note: You can also install MySQL database using yum groupinstall as we discussed earlier.

11. Upgrade an existing software group using groupupdate

If you’ve already installed a software group using yum groupinstall, and would like to upgrade it to the latest version, use ‘yum groupupdate’ as shown below.
# yum groupupdate 'Graphical Internet'

Dependencies Resolved
Upgrade       5 Package(s)
Is this ok [y/N]: y   

Running Transaction
  Updating   : evolution-data-server-3.0.2-1.fc15.x86_64     1/10
  Updating   : evolution-3.0.2-3.fc15.x86_64                 2/10
  Updating   : evolution-NetworkManager-3.0.2-3.fc15.x86_64  3/10
  Updating   : evolution-help-3.0.2-3.fc15.noarch            4/10
  Updating   : empathy-3.0.2-3.fc15.x86_64                   5/10
  Cleanup    : evolution-NetworkManager-3.0.1-1.fc15.x86_64  6/10
  Cleanup    : evolution-help-3.0.1-1.fc15.noarch            7/10
  Cleanup    : evolution-3.0.1-1.fc15.x86_64                 8/10
  Cleanup    : empathy-3.0.1-3.fc15.x86_64                   9/10
  Cleanup    : evolution-data-server-3.0.1-1.fc15.x86_64     10/10 

Complete!

12. Uninstall a software group using yum groupremove

To delete an existing software group use ‘yum groupremove’ as shown below.
# yum groupremove 'DNS Name Server'
Dependencies Resolved
Remove        2 Package(s)
Is this ok [y/N]: y

Running Transaction
  Erasing    : 32:bind-chroot-9.8.0-9.P4.fc15.x86_64  1/2
  Erasing    : 32:bind-9.8.0-9.P4.fc15.x86_64            2/2 

Complete!

13. Display your current yum repositories

All yum commands goes against one or more yum repositories. To view all the yum repositories that are configured in your system, do ‘yum repolist’ as shown below.
The following will display only the enabled repositories.
# yum repolist
repo id     repo name                        status
fedora      Fedora 15 - x86_64               24,085
updates     Fedora 15 - x86_64 - Updates     5,612
To display all the repositories (both enabled and disabled), use ‘yum repolist all’.
# yum repolist all
repo id                   repo name                                status
fedora                    Fedora 15 - x86_64                       enabled: 24,085
fedora-debuginfo          Fedora 15 - x86_64 - Debug               disabled
fedora-source             Fedora 15 - Source                       disabled
rawhide-debuginfo         Fedora - Rawhide - Debug                 disabled
rawhide-source            Fedora - Rawhide - Source                disabled
updates                   Fedora 15 - x86_64 - Updates             enabled:  5,612
updates-debuginfo         Fedora 15 - x86_64 - Updates - Debug     disabled
updates-source            Fedora 15 - Updates Source               disabled
updates-testing           Fedora 15 - x86_64 - Test Updates        disabled
updates-testing-debuginfo Fedora 15 - x86_64 - Test Updates Debug  disabled
updates-testing-source    Fedora 15 - Test Updates Source          disabled
To view only the disabled repositories, use ‘yum repositories disabled’.

14. Install from a disabled repositories using yum –enablerepo

By default yum installs only from the enabled repositories. For some reason if you like to install a package from a disabled repositories, use –enablerepo option in the ‘yum install’ as shown below.
# yum --enablerepo=fedora-source install vim-X11.x86_64
Dependencies Resolved
Install       1 Package(s)
Is this ok [y/N]: y

Running Transaction
  Installing : 2:vim-X11-7.3.138-1.fc15.x86_64   1/1 

Complete!

15. Execute yum commands interactively using Yum Shell

Yum provides the interactive shell to run multiple commands as shown below.
# yum shell
Setting up Yum Shell
> info samba.x86_64
Available Packages
Name        : samba
Arch        : x86_64
Epoch       : 1
Version     : 3.5.11
Release     : 71.fc15.1
Size        : 4.6 M
Repo        : updates
Summary     : Server and Client software to interoperate with Windows machines
URL         : http://www.samba.org/
License     : GPLv3+ and LGPLv3+
Description :
            : Samba is the suite of programs by which a lot of PC-related
            : machines share files, printers, and other information (such as
            : lists of available files and printers). The Windows NT, OS/2, and
            : Linux operating systems support this natively, and add-on packages
            : can enable the same thing for DOS, Windows, VMS, UNIX of all
            : kinds, MVS, and more. This package provides an SMB/CIFS server
            : that can be used to provide network services to SMB/CIFS clients.
            : Samba uses NetBIOS over TCP/IP (NetBT) protocols and does NOT
            : need the NetBEUI (Microsoft Raw NetBIOS frame) protocol.

> 
Yum can also read commands from a text file and execute it one by one. This is very helpful when you have multiple systems. Instead of executing the same command on all the systems, create a text file with those commands, and use ‘yum shell’ to execute those commands as shown below.
# cat yum_cmd.txt
repolist
info nfs-utils-lib.x86_64

# yum shell yum_cmd.txt 
repo id     repo name                        status
fedora      Fedora 15 - x86_64               24,085
updates     Fedora 15 - x86_64 - Updates     5,612

Available Packages
Name        : nfs-utils-lib
Arch        : x86_64
Version     : 1.1.5
Release     : 5.fc15
Size        : 61 k
Repo        : fedora
Summary     : Network File System Support Library
URL         : http://www.citi.umich.edu/projects/nfsv4/linux/
License     : BSD
Description : Support libraries that are needed by the commands and
            : daemons the nfs-utils rpm.

Leaving Shell

Linux Memory Management – Virtual Memory and Demand Paging

Memory management is one of the most complex activity done by Linux kernel. It has various concepts/issues associated with it.
This article is part of our on-going UNIX kernel overview series.
In the previous article of the kernel series, we discussed about the UNIX process overview, and Reentrant Kernels.
In this article we will try to touch base on virtual memory and demand paging as these are some of the important concepts related to memory management.

Virtual Memory

The concept of virtual memory is one of the very powerful aspects of memory management. Since the initial era of computers the need of memory more than the existing physical memory has been felt. Over the years, many solutions were used to overcome this issue and the most successful of them has been the concept of virtual memory.
Virtual memory makes your system appear as if it has more memory than it actually has. This may sound interesting and may prompt one to as how is this possible. So, lets understand the concept.
  • To start, we must first understand that virtual memory is a layer of memory addresses that map to physical addresses.
  • In virtual memory model, when a processor executes a program instruction, it reads the instruction from virtual memory and executes it.
  • But before executing the instruction, it first converts the virtual memory address into physical address.
  • This conversion is done based on the mapping of virtual to physical addresses that is done based on the mapping information contained in the page tables (that are maintained by OS).
The virtual and physical memory is divided into fixed length chunks known as pages. In this paged model, a virtual address can be divided into two parts :
  • An offset (Lowest 12 bits)
  • A virtual page frame number (rest of the bits)
When ever the processor encounters a virtual address, it extracts the virtual page frame number out of it. Then it translates this virtual page frame number into a physical page frame number and the offset parts helps it to go to the exact address in the physical page. This translation of addresses is done through the page tables.
Theoretically we can consider a page table to contain the following information :
  • A flag that describes whether the entry is valid or not
  • The physical page frame number as described by this entry
  • Access information regarding the page (like read-only, read-write etc)
A page table is accessed through virtual page frame number using it as offset for entries in the page table. For example, a virtual page frame number of ’2′ points to the entry ’1′ in the page table (the entry numbers begin with ’0′ ).
In the image below, VPFN stands for Virtual page frame number, and PFN indicates the physical page frame number.

It may happen that a processor goes to a processes page table entry with a virtual page frame number and finds the entry as invalid. In this case it is the processor’s responsibility to pass the control to kernel and ask it to fix the problem. Different processors pass the control in different ways but this phenomenon is known as a ‘page fault’.  But if the entry was valid then processor takes the physical page frame number, multiplies with the size of the page to get the base address of the physical page and then adds the offset to get to the exact physical address.
So now we understand that through the concept of virtual memory, each process thinks that it has all range of virtual address at its disposal and hence this concepts make the system appear as if it has more physical memory than actually available.

Demand Paging

In the previous sectioned we learned that if the processor goes to the processes page table with a virtual page frame number for which no entry was present in the table then two cases arise.
  1. Either the process has tried to access an invalid memory address
  2. The physical page corresponding to the virtual address was not loaded into physical memory
Out of the two cases above, the case 1 is the case where the process tries to memory address which it is not allowed. In this case a page fault is generated and the kernel terminates the process.
While in case ’2′, as already explained, the physical page corresponding to the virtual address is not yet loaded into physical memory. In this case also a page fault is generated and the kernel then tries to bring the required memory page into physical memory from hard disk.
Since this operation of bringing a page from hard disk into physical memory is time consuming so by this time a context switch between processes happens and some other process is brought into execution. Meanwhile the page of the earlier process is brought into physical memory and the page tables are updated and then this process is brought back into execution again from the same instruction that caused the ‘page fault’.
This is known as demand paging where all the memory pages corresponding to a process are not present in the physical memory at any given time. This saves the physical memory from clogging up with non-required memory pages while when necessary these pages can be brought into physical memory through  page fault (as explained above).

File Handling in C with Examples (fopen, fread, fwrite, fseek)

As with any OS, file handling is a core concept in Linux. Any system programmer would learn it as one of his/her initial programming assignments. This aspect of programming involves system files.

Through file handling, one can perform operations like create, modify, delete etc on system files. Here in this article I try to bring in the very basic of file handling. Hope this article will clear the top layer of this multilayer aspect.

File handling functions

In this article, we will cover the following functions that are popularly used in file handling :

fopen()

FILE *fopen(const char *path, const char *mode);
The fopen() function is used to open a file and associates an I/O stream with it. This function takes two arguments. The first argument is a pointer to a string containing name of the file to be opened while the second argument is the mode in which the file is to be opened. The mode can be :
  • ‘r’    :  Open text file for reading. The stream is positioned at the beginning of the file.
  • ‘r+’ :  Open for reading and writing. The stream is positioned at the beginning of the file.
  • ‘w’   :  Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.
  • ‘w+’ : Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
  • ‘a’    : Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.
  • ‘a+’ : Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
The fopen() function returns a FILE stream pointer on success while it returns NULL in case of a failure.

fread() and fwrite()

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
The functions fread/fwrite are used for reading/writing data from/to the file opened by fopen function. These functions accept three arguments. The first argument is a pointer to buffer used for reading/writing the data. The data read/written is in the form of ‘nmemb’ elements each ‘size’ bytes long.
In case of success, fread/fwrite return the number of bytes actually read/written from/to the stream opened by fopen function. In case of failure, a lesser number of byes (then requested to read/write) is returned.

fseek()

int fseek(FILE *stream, long offset, int whence);
The fseek() function is used to set the file position indicator for the stream to a new position. This function accepts three arguments. The first argument is the FILE stream pointer returned by the fopen() function. The second argument ‘offset’ tells the amount of bytes to seek. The third argument ‘whence’ tells from where the seek of ‘offset’ number of bytes is to be done. The available values for whence are SEEK_SET, SEEK_CUR, or SEEK_END.  These three values (in order) depict the start of the file, the current position and the end of the file.
Upon success, this function returns 0, otherwise it returns -1.

fclose()

int fclose(FILE *fp);
The fclose() function first flushes the stream opened by fopen() and then closes the underlying descriptor. Upon successful completion this function returns 0 else end of file (eof) is returned. In case of failure, if the stream is accessed further then the behavior remains undefined.

The code

#include<stdio.h>
#include<string.h>

#define SIZE 1
#define NUMELEM 5

int main(void)
{
    FILE* fd = NULL;
    char buff[100];
    memset(buff,0,sizeof(buff));

    fd = fopen("test.txt","rw+");

    if(NULL == fd)
    {
        printf("\n fopen() Error!!!\n");
        return 1;
    }

    printf("\n File opened successfully through fopen()\n");

    if(SIZE*NUMELEM != fread(buff,SIZE,NUMELEM,fd))
    {
        printf("\n fread() failed\n");
        return 1;
    }

    printf("\n Some bytes successfully read through fread()\n");

    printf("\n The bytes read are [%s]\n",buff);

    if(0 != fseek(fd,11,SEEK_CUR))
    {
        printf("\n fseek() failed\n");
        return 1;
    }

    printf("\n fseek() successful\n");

    if(SIZE*NUMELEM != fwrite(buff,SIZE,strlen(buff),fd))
    {
        printf("\n fwrite() failed\n");
        return 1;
    }

    printf("\n fwrite() successful, data written to text file\n");

    fclose(fd);

    printf("\n File stream closed through fclose()\n");

    return 0;
}
The code above assumes that you have a test file “test.txt” placed in the same location from where this executable will be run.
Initially the content in file is :
$ cat test.txt
hello everybody
Now, run the code :
$ ./fileHandling 

 File opened successfully through fopen()

 Some bytes successfully read through fread()

 The bytes read are [hello]

 fseek() successful

 fwrite() successful, data written to text file

 File stream closed through fclose()
Again check the contents of the file test.txt. As you see below, the content of the file was modified.
$ cat test.txt
hello everybody
hello

Crontab Log: How to Log the Output of My Cron Script

Question: I created a backup.sh shell script and added it to my crontab to execute it daily. How do I verify whether the backup cron script job ran successfully? Also, I have several echo statements inside my backup.sh shell script. How do I save the output of my script to a log file when it is executed as a cron job?

Answer: Let us say that you’ve added the backup.sh to your crontab as shown below to execute it at midnight every day.
$ crontab -e
59 23 * * * /home/john/bin/backup.sh
To verify whether the this job got executed successfully or not, check the /var/log/cron file, which contains information about all the cron jobs that gets executed in your system. As you see from the following output, john’s cron job got executed succesfully.
$ tail /var/log/cron
Oct  8 22:00:00 dev-db crond[18340]: (root) CMD (/bin/sh /home/root/bin/system_check &)
Oct  8 23:00:00 dev-db crond[20348]: (oracle) CMD (/bin/sh /home/oracle/bin/cleanup.sh &)
Oct  8 23:59:00 dev-db crond[20399]: (john) CMD (/bin/sh /home/john/bin/backup.sh &)
Cron log contains the following information:
  • Timestamp – The date and time when the cron job was executed
  • Hostname – The hostname of the server (For example, dev-db)
  • The cron deamon name and the PID. For example, crond[20399]
  • Username – The username under which this cron job got executed. For example, john.
  • CMD – Anything following this is the real command that got executed at that time.
If there are any echo statements inside the backup.sh, you might want to log those into a file. In general, if the backup.sh cron script throws any output (including errors), you might want to log those to a log file. To do this, modify the crontab entry and add the output and error redirection as shown below.
$ crontab -e
59 23 * * * /home/john/bin/backup.sh > /home/john/logs/backup.log 2>&1
In the above:
  • > /home/john/logs/backup.log indicates that the standard output of the backup.sh script will be redirected to the backup.log file.
  • 2>&1 indicates that the standard error (2>) is redirected to the same file descriptor that is pointed by standard output (&1).
  • So, both standard output and error will be redirected to /home/john/logs/backup.log

How to Change GRUB Splash Image, Background, Font Color on Your Linux

On Debian Lenny (and previous versions of Debian), you might have got tired of seeing a blue box with black background for GRUB when the Linux was booting up. But starting from Debian Squeeze, GRUB adds a background image which looks good (better than the boring background colors).
This article explains how to change the GRUB background image. The steps mentioned below were tested on Debian Squeeze with grub-1.98. But these steps should also work on other similar Linux distros.

Choosing a GRUB Background Image

GRUB 2 can use PNG, JPG/JPEG and TGA images for the background. The image must meet the following specifications:
  • JPG/JPEG images must be 8-bit (256 color)
  • Images should be non-indexed, RGB
By default, if desktop-base package is installed, images conforming to the above specification will be located in /usr/share/images/desktop-base/ directory.

Order of Search for GRUB Splash Images

In grub-1.98, the splash image to be displayed will be searched in the following order.
  1. GRUB_BACKGROUND line in /etc/default/grub
  2. First image found in /boot/grub/ ( more images found, it will be taken alphanumerically )
  3. The image specified in /usr/share/desktop-base/grub_background.sh
  4. The file listed in the WALLPAPER line in /etc/grub.d/05_debian_theme
So you can use any of the above in the order of priority to make GRUB display your own images. The following is the content of /etc/default/grub file on my system.
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""

GRUB_BACKGROUND="/usr/share/images/desktop-base/moreblue-orbit-splash.png"
Once changes has been done using any of the above methods, make sure you execute update-grub command as shown below.
# update-grub
Generating grub.cfg ...
Found background: /usr/share/images/desktop-base/moreblue-orbit-splash.png
Found background image: /usr/share/images/desktop-base/moreblue-orbit-splash.png
Found linux image: /boot/vmlinuz-2.6.32-5-amd64
Found initrd image: /boot/initrd.img-2.6.32-5-amd64
done
Now, when you boot your machine, you will see the customized image in GRUB.
Talking about GRUB, you also might want to password protect your GRUB as we discussed earlier.

Change GRUB Front and Menu Colors

Now we have placed our own image in GRUB. But it will still display the menu and its entries in the default color.
The following are the 3 main GRUB color setting that you can change.
  • menu_color_highlight => The color of the highlighted menu entry and its background within the menu box
  • menu_color_normal => The color of non-selected menu entry and its background within the menu box
  • color_normal => The color of text and background outside the menu box
The syntax for specifying the color is as follows:
menu_color_highlight=fg-color/bg-color
The following colors are supported by grub:
black
blue
brown
cyan
dark-gray
green
light-cyan
light-blue
light-green
light-gray
light-magenta
light-red
magenta
red
white
yellow
Now to change the colors, open “/etc/grub.d/05_debian_theme” and find the following line:
        if [ -z "${2}" ] && [ -z "${3}" ]; then
                echo "  true"
        fi
and, replace them with the following:
if [ -z "${2}" ] && [ -z "${3}" ]; then
    # echo "  true"
    echo "    set color_highlight=red/green"
    echo "    set color_normal=light-cyan/black"
fi
Don’t change the “black” present in color_normal. If changed, the image will not be transparent in the area where the menu is displayed.
After this change, execute “update-grub”, and reboot your system. You will notice the change in the font colors displayed. After making the above mentioned changes on my system, the GRUB screen looked like the following:

Experiment with GRUB Colors

When you are not sure of what colors to choose, and you would like to experiment, then you can do it from the grub command-line itself.
  1. When the grub menu appears, press any key to stop the countdown
  2. Press ‘C’ to get into GRUB command line, and experiment as you wish
  3. grub> set color_highlight=red/green
    grub> set color_normal=light-cyan/black
  4. Now press “ESC”, to see the effect of your changes. If not satisfied, follow the steps once again and try different combinations.

Linux Touch Command Examples (How to Change File Timestamp)

Every file in Linux is associated with timestamps, which specifies the last access time, last modification time and last change time.
Whenever we create a new file, or modify an existing file or its attributes, these timestamps will be updated automatically.
Touch command is used to change these timestamps (access time, modification time, and change time of a file).

1. Create an Empty File using touch

You can create an empty file using touch command. The following example will create a zero byte new file named tgs.txt.
$ touch tgs.txt
You can also use -c option to avoid creating new files. If you use -c option, and if a file doesn’t exists, touch will not create the file.
$ touch -c a.txt
Commands like ls command and find command uses these timestamp information for listing and finding files.
You can also create more than 1 files from a single touch command. The following example will create 4 files named a, b, c, and d.
$ touch a b c d

2. Change File’s Access Time using -a

We can change the access time of a file using -a option. By default it will take the current system time and update the atime field.
Before touch command is executed:
$ stat tgs.txt

  File: `tgs.txt'
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 801h/2049d Inode: 394283      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/lakshmanan)   Gid: ( 1000/lakshmanan)
Access: 2012-10-18 23:58:21.663514407 +0530
Modify: 2012-10-18 23:58:21.663514407 +0530
Change: 2012-10-18 23:58:21.663514407 +0530
$ touch -a tgs.txt
After the above touch command (Please note that the access time is changed):
$ stat tgs.txt

  File: `tgs.txt'
  Size: 0          Blocks: 0          IO Block: 4096   regular empty file
Device: 801h/2049d Inode: 394283      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/lakshmanan)   Gid: ( 1000/lakshmanan)
Access: 2012-10-19 00:08:23.559514525 +0530
Modify: 2012-10-18 23:58:21.663514407 +0530
Change: 2012-10-19 00:08:23.559514525 +0530

3. Change File’s Modification Time using -m

You can change the modification time of a file using -m option.
$ touch -m *.o
The above method can be used to change the mtime of all obj files, when using make utility.
NOTE: It is not possible to change the ctime using touch command

4. Explicitly Setting Access and Modification time using -t and -d

Instead of taking the current time-stamp, you can explicitly specify the time using -t and -d options.
The format for specifying -t is [[CC]YY]MMDDhhmm[.SS]
$ touch -t [[CC]YY]MMDDhhmm[.SS]
The following explains the above format:
  • CC – Specifies the first two digits of the year
  • YY – Specifies the last two digits of the year. If the value of the YY is between 70 and 99, the value of the CC digits is assumed to be 19. If the value of the YY is between 00 and 37, the value of the CC digits is assumed to be 20. It is not possible to set the date beyond January 18, 2038.
  • MM – Specifies the month
  • DD – Specifies the date
  • hh – Specifies the hour
  • mm – Specifies the minute
  • SS – Specifies the seconds
For example:
$ touch -a -m -t 203801181205.09 tgs.txt
Verify the above change using stat command:
$ stat tgs.txt
  File: `tgs.txt'
  Size: 3          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d Inode: 394283      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/lakshmanan)   Gid: ( 1000/lakshmanan)
Access: 2038-01-18 12:05:09.000000000 +0530
Modify: 2038-01-18 12:05:09.000000000 +0530
Change: 2012-10-19 00:40:58.763514502 +0530
You can also use a string to change the time
Another example:
$ touch -d "2012-10-19 12:12:12.000000000 +0530" tgs.txt
For developers, touch command will be really helpful when you are working with Makefiles

5. Copy the Time-stamp from Another File using -r

You can also take a file as a reference, and update the time for other files, so that both file will hold the same time.
The following touch command example will update the time-stamp of file a.txt with the time-stamp of tgs.txt file.
$ touch a.txt -r tgs.txt

Linux TR Command Examples

tr is an UNIX utility for translating, or deleting, or squeezing repeated characters. It will read from STDIN and write to STDOUT.
tr stands for translate.

Syntax

The syntax of tr command is:
$ tr [OPTION] SET1 [SET2]

Translation

If both the SET1 and SET2 are specified and ‘-d’ OPTION is not specified, then tr command will replace each characters in SET1 with each character in same position in SET2.

1. Convert lower case to upper case

The following tr command is used to convert the lower case to upper case
$ tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
thegeekstuff
THEGEEKSTUFF
The following command will also convert lower case to upper case
$ tr [:lower:] [:upper:]
thegeekstuff
THEGEEKSTUFF
You can also use ranges in tr. The following command uses ranges to convert lower to upper case.
$ tr a-z A-Z
thegeekstuff
THEGEEKSTUFF

2. Translate braces into parenthesis

You can also translate from and to a file. In this example we will translate braces in a file with parenthesis.
$ tr '{}' '()' < inputfile > outputfile
The above command will read each character from “inputfile”, translate if it is a brace, and write the output in “outputfile”.

3. Translate white-space to tabs

The following command will translate all the white-space to tabs
$ echo "This is for testing" | tr [:space:] '\t'
This is for testing

4. Squeeze repetition of characters using -s

In Example 3, we see how to translate space with tabs. But if there are two are more spaces present continuously, then the previous command will translate each spaces to a tab as follows.
$ echo "This   is   for testing" | tr [:space:] '\t'
This   is   for testing
We can use -s option to squeeze the repetition of characters.
$ echo "This   is   for testing" | tr -s [:space:] '\t'
This is for testing
Similarly you can convert multiple continuous spaces with a single space
$ echo "This  is  for testing" | tr -s [:space:] ' '
This is for testing

5. Delete specified characters using -d option

tr can also be used to remove particular characters using -d option.
$ echo "the geek stuff" | tr -d 't'
he geek suff
To remove all the digits from the string, use
$ echo "my username is 432234" | tr -d [:digit:]
my username is
Also, if you like to delete lines from file, you can use sed d command.

6. Complement the sets using -c option

You can complement the SET1 using -c option. For example, to remove all characters except digits, you can use the following.
$ echo "my username is 432234" | tr -cd [:digit:]
432234

7. Remove all non-printable character from a file

The following command can be used to remove all non-printable characters from a file.
$ tr -cd [:print:] < file.txt

8. Join all the lines in a file into a single line

The below command will translate all newlines into spaces and make the result as a single line.
$ tr -s '\n' ' ' < file.txt

How to Mount and Unmount Filesystem / Partition in Linux (Mount/Umount Command Examples)

Once you insert new hard disks into your system, you’ll typically use utilities like fdisk or parted to create partitions. Once you create a partition, you’ll use mkfs command to create ext2, ext3, or ext4 partition.
Once you create a partition, you should use mount command to mount the partition into a mount point (a directory), to start using the filesystem.
This tutorial explains everything you need to know about both mount and umount command with 15 practical examples.

The general mount command syntax to mount a device:
mount -t type device destination_dir

1. Mount a CD-ROM

The device file for CD would exist under /dev directory. For example, a CD-ROM device will be mounted as shown below.
# mount -t iso9660 -o ro /dev/cdrom /mnt
In the above example, the option “-o ro” indicates that the cdrom should be mounted with read-only access. Also, make sure that the destination directory (in the above example, /mnt) exist before you execute the mount command.

2. View All Mounts

After you execute mount a partition or filesystem, execute the mount command without any arguments to view all the mounts.
In the example below, after mounting the USB drive on a system, the output of mount looks like the below. As seen below, the USB device (i.e:/dev/sdb) is mounted on /media/myusb, which is displayed as the last line in the mount command.
# mount
/dev/sda5 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda6 on /mydata type ext2 (rw)
/dev/sda7 on /backup type vfat (rw)
gvfs-fuse-daemon on /home/bala/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=bala)
/dev/sdb on /media/myusb type vfat (rw,nosuid,nodev,uid=1000,gid=1000,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks)
You can also use df command to view all the mount points.
# df
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sda5      195069136 128345036  56958520  70% /
udev             2008336         4   2008332   1% /dev
tmpfs             806244       928    805316   1% /run
none                5120         0      5120   0% /run/lock
none             2015604       228   2015376   1% /run/shm
/dev/sda6       17729076    176200  16657596   2% /mydata
/dev/sda7       11707200    573312  11133888   5% /backup
/dev/sdb         3910656   2807160   1103496  72% /media/myusb

3. Mount all the filesystem mentioned in /etc/fstab

The filesystems listed in /etc/fstab gets mounted during booting process. After booting, system administrator may unmount some of the partitions for various reasons. If you want all the filesystems to be mounted as specified in /etc/fstab, use -a option with mount as shown below:
Example /etc/fstab file entries:
# cat /etc/fstab
#
proc            /proc           proc    nodev,noexec,nosuid 0       0
# / was on /dev/sda5 during installation
/dev/sda5 /               ext4    errors=remount-ro 0       1
# /mydata was on /dev/sda6 during installation
/dev/sda6 /mydata         ext2    defaults        0       2
# /backup was on /dev/sda7 during installation
/dev/sda7 /backup         vfat    defaults        0       3
Execute mount command with -a option to mount all the /etc/fstab entries.
# mount -a

# mount
/dev/sda5 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda6 on /mydata type ext2 (rw)
/dev/sda7 on /backup type vfat (rw)
gvfs-fuse-daemon on /home/bala/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=bala)
The same -a option can be used with umount to unmount all the filesystems mentioned in /etc/mtab
# umount -a
umount: /run/shm: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /run: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /dev: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
Some filesystem are not unmounted as its busy or currently in use. Note that the files /etc/mtab and /proc/mounts contents would be similar.

4. Mount only a specific filesystem from /etc/fstab

When you pass only the directory name to mount, it looks for mount point entries, if not found, then search continuous for a device in /etc/fstab and gets mounted.
# mount | grep /mydata

# cat /etc/fstab | grep mydata
##########/mydata was on /dev/sda6 during installation##########
 /dev/sda6 /mydata         ext2    defaults        0       2
As seen above, /mydata directory is not a mountpoint, but it is present in /etc/fstab.
# mount /mydata

# mount | grep /mydata
/dev/sda6 on /mydata type ext2 (rw)
If you execute the same again, you would get the error message as follows:
# mount /mydata
mount: /dev/sda6 already mounted or /mydata busy
mount: according to mtab, /dev/sda6 is already mounted on /mydata
Here you may also pass the device name instead of directory name (to be picked up from /etc/fstab file).
# mount /dev/sda6
Note that the files /etc/mtab and /proc/mounts contents would be similar.

5. View all mounted partitions of specific type

It is possible to list only the specific type of filesystem mounted using the option -l with -t as shown below:
# mount -l -t ext2
/dev/sda6 on /mydata type ext2 (rw)

# mount -l -t ext4
/dev/sda5 on / type ext4 (rw,errors=remount-ro)
As seen above, /dev/sda6 is the only ext2 partition and /dev/sda5 is the only ext4 partition accordingly.

6. Mount a Floppy Disk

The device file for floppy disk would exist under /dev directory. For example, a floppy disk will be mounted as shown below.
# mount /dev/fd0 /mnt
# cd /mnt
After the successful mount, you would be able to access the contents of the floppy disk. Once you are done with it, use umount before you physically remove the floppy disk from the system.
# umount /mnt

7. Bind mount points to a new directory

The mountpoint can be binded to a new directory. So that you would be able to access the contents of a filesystem via more than one mountpoints at the same time.
Use -B option with olddir and newdir to be binded as follows,
# mount -B /mydata /mnt
Now the bind is done and you might verify it as follows,
# mount | grep /mydata
/dev/sda6 on /mydata type ext2 (rw)
/mydata on /mnt type none (rw,bind)
As seen above the bind is done properly. So when you do modification in filesystem in one place, you can see those reflection of it in other mount point as shown below:
# cd /mydata
# ls
test
# mkdir dir1
# mkdir dir2
# ls
test    dir1    dir2
# cd /mnt
# ls
test    dir1    dir2

8. Access contents from new mount point

Mount allows you to access the contents of a mount point from a new mount point. Its nothing but move a mounted tree to another place.
In the example below, the mount point /mydata will be accessed from /mnt using the option -M as shown below:
# mount -M /mydata /mnt/
Once its done, you cant use the old mount point as its moved to a new mount point and this can be verified as shown below:
# mount | grep /mydata
# mount | grep /mnt
/dev/sda6 on /mnt type ext2 (rw)

9. Mount without writing entry into /etc/mtab

During read only mount of /etc/, the /etc/mtab file entries cannot be modified by mount command. However, mount can be done without writing into /etc/mtab by using the option -n as follows,
# mount -n /dev/sda6 /mydata
You cannot see any entry for this /mydata in mount command output and as well from /etc/mtab file as follows:
# mount | grep /mydata
# cat /etc/mtab | grep /mydata
Access the contents of a mounted directory /mydata:
# cd /mydata
# ls
dir1  dir2  test

10. Mount filesystem with read or read/write access

To mount partition as read only, use -r option which is synonym to -o ro.
# mount /dev/sda6 /mydata -r
# mount  | grep /mydata
/dev/sda6 on /mydata type ext4 (ro)
ext3 and ext4 filesystem would still allow you to do write operation when the filesystem is dirty. So, you may have to use “ro,noload” to prevent these kind of write operation.
# mount /dev/sda6 /mydata -t ext4 -o ro -o noload
# mount | grep /mydata
/dev/sda6 on /mydata type ext4 (ro,noload)
To mount a partition with read/write access, use -w option which is same as “-o rw” (i.e : default).

11. Remount the mounted filesystem

In order to mount the already mounted filesystem, use remount option and its normally used to remount the filesystem with read/write access when its previously mounted with read access.
The /mydata mount point is going to be remounted with read/write access from read access as shown below:
# mount | grep /mydata
/dev/sda6 on /mydata type ext4 (ro,noload)
# mount -o remount,rw /mydata
# mount | grep /mydata
/dev/sda6 on /mydata type ext4 (rw)

12. Mount an iso image into a directory

The iso image can be mounted as shown below:
# mount -t iso9660 -o loop pdf_collections.iso /mnt
# cd /mnt
# ls
perl/    php/    mysql/

13. Unmount more than one mount points

Umount allows you to unmount more than mount point in a single execution of umount of command as follows:
# umount /mydata  /backup
# mount | grep /mydata
# mount | grep /backup

14. Lazy unmount of a filesystem

This is a special option in umount, in case you want to unmount a partition after disk operations are done. You can issue command umount -l with that partition and the unmount will be done after the disk operations gets finished.
For instance, consider a scenario that a task (i.e: script or any other command) is doing a copy operation on a disk and at the same time you are allowed to issue a unmount with -l, so that unmount would be done once the copy is over (i.e: the disk operation).
# umount /mydata -l

15. Forcefully unmount a filesystem

umount provides the option to forcefully unmount a filesystem with option -f when the device is busy as shown below:
# umount -f /mnt
If this doesn’t work for you, then you can go for lazy unmount.
Meanwhile, you can also have a look at ps command output that which process is presently using the mountpoint as shown below:
# ps ajx | grep /mydata
 2540  3037  3037  2468 pts/2     3037 D+       0   0:00 cp -r /home/geekstuff/ProjectData/ /mydata
You can also execute fuser command to find out which process is holding the directory for operations.
# fuser -cu /mydata
/mydata:              3087(root)
It gives you the process id with username (nothing but the owner of the process). If you know what that process is, you may want to stop that process and then try the umount again.

How to Count Number of Lines in a File in Linux (wc and nl Command Examples)

Linux commands wc and nl will help you to identify the number of words, lines, bytes, etc, in a file. This tutorial explains how to use these two very useful command with various examples.

The basic text file that will be used in examples throughout this article is shown below :
$ cat sort.txt
UK
Australia
Newzealand
Brazil
America

Linux nl Command Examples

The nl utility in Linux is used to number lines of a file.
Here is the syntax and description from man page :
SYNOPSIS
nl [OPTION]… [FILE]…
DESCRIPTION
Write each FILE to standard output, with line numbers added. With no FILE, or when FILE is -, read standard input.

1. A basic example

Here is a basic example that explains how nl command can be used to number lines of a file.
$ cat sort.txt
UK
Australia
Newzealand
Brazil
America

$ nl sort.txt
     1 UK
     2 Australia
     3 Newzealand
     4 Brazil
     5 America
So we see that using nl command, all the lines of file sort.txt got numbered.

2. Increment line numbers with any value using -i option

The option -i can be used to override the default increment of 1 in line numbers.
Here is an example where we have used -i to increase the line number increment to 5 :
$ nl -i5 sort.txt
     1 UK
     6 Australia
    11 Newzealand
    16 Brazil
    21 America
Instead of the default 1,2,3… the line numbers are now displayed in increments of 5 (i.e 1,6,11…)

3. Add string after line numbers using -s option

By default, the nl command adds only line numbers. But, through -s option, any string can be added that can act as a separator between line numbers and the line text.
Here is an example:
$ nl -s. sort.txt
     1.UK
     2.Australia
     3.Newzealand
     4.Brazil
     5.America
So we see that the character ‘.’ was added after line numbers.

4. Use a different column for line numbers using -w option

Columns for line number display can be changed using -w option.
Here is an example :
$ nl -w1 sort.txt
1 UK
2 Australia
3 Newzealand
4 Brazil
5 America

$ nl -w2 sort.txt
 1 UK
 2 Australia
 3 Newzealand
 4 Brazil
 5 America

$ nl -w3 sort.txt
  1 UK
  2 Australia
  3 Newzealand
  4 Brazil
  5 America

$ nl -w4 sort.txt
   1 UK
   2 Australia
   3 Newzealand
   4 Brazil
   5 America

$ nl -w5 sort.txt
    1 UK
    2 Australia
    3 Newzealand
    4 Brazil
    5 America

$ nl -w6 sort.txt
     1 UK
     2 Australia
     3 Newzealand
     4 Brazil
     5 America
The exhaustive output above gives a good idea as to how the display column for line numbers can be changed.

5. Use STYLE for numbering lines using -b option

Various STYLEs are available for line numbering. From the man page :
STYLE is one of:
  • a – number all lines
  • t – number only nonempty lines
  • n – number no lines
  • pBRE – number only lines that contain a match for the basic regular expression, BRE
In the example below, I have used a regular expression ‘pA’ as a STYLE with option -b. This regular expression matches the lines beginning with ‘A’ and so nl command numbers only those lines.
$ nl -bpA sort.txt
       UK
     1 Australia
       Newzealand
       Brazil
     2 America
So we see that only the lines beginning with ‘A’ were numbered.

6. Use different FORMAT for inserting line numbers using -n options

There are various FORMATs available for inserting line numbers. From the man page :
FORMAT is one of:
  • ln – left justified, no leading zeros
  • rn – right justified, no leading zeros
  • rz – right justified, leading zeros
Here is an example that demonstrated all the above formats:
$ nl -nln sort.txt
1      UK
2      Australia
3      Newzealand
4      Brazil
5      America

$ nl -nrn sort.txt
     1 UK
     2 Australia
     3 Newzealand
     4 Brazil
     5 America

$ nl -nrz sort.txt
000001 UK
000002 Australia
000003 Newzealand
000004 Brazil
000005 America
Please note that you can also use sed command to count the number of lines in a file.

Linux wc Command Examples

The wc utility in Linux is used print information like number of newlines, words, byte counts of a file.
Here is the syntax and description from man page :
SYNOPSIS
wc [OPTION]… [FILE]…
wc [OPTION]… –files0-from=F
DESCRIPTION
Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified. With no FILE, or
when FILE is -, read standard input. A word is a non-zero-length sequence of characters delimited by white space.

1. A basic example

Here is a basic example of Linux wc command :
$ cat sort.txt
UK
Australia
Newzealand
Brazil
America

$ wc sort.txt
 5  5 41 sort.txt
The three numbers produced in output correspond to number of lines, number of words and number of bytes. These three numbers are followed by name of the file.

2. Display word count through -w option

The word count of a file can be displayed explicitly through -w option.
Here is an example :
$ wc -w sort.txt
5 sort.txt
So we see that number of words were printed followed by the file name.

3. Display length of longest line through -L option

The wc command provides an option -L that can be used to display the length of longest line in the file.
Here is an example :
$ wc -L sort.txt
10 sort.txt
So we see that length of the longest line (‘Newzealand’ in our case) was displayed in the output.

4. Display number of newlines through -l option

The wc command provides an option -l through which number of newlines can be displayed in the output.
Here is an example :
$ wc -l sort.txt
5 sort.txt
So we see that there were 5 newlines in the file sort.txt

5. Display number of bytes through -c option

Total number of bytes in a file can be displayed by using -c option of the wc command.
Here is an example :
$ wc -c sort.txt
41 sort.txt

How to Copy Files in Linux and Unix?

cp is one of the basic command in Unix. You already know that it is used to copy one or more files or directories from source to destination.
While this tutorial is for beginners, it is also helpful for everybody to quickly review various cp command options using some practical examples.
Even if you are using cp command all the times, probably one or more examples explained below might be new to you.

The general form of copy command:
cp [option] source destination

1. Copy a file or directory from source to destination

To copy a file, you need to pass source and destination to the copy command. The following example copies the file from project/readme.txt to projectbackup/readme-new.txt
$ cp project/readme.txt projectbackup/readme-new.txt

$ cd projectbackup/

$ ls
readme-new.txt
If you want to copy a file from one folder to another with the same name, just the destination directory name is good enough as shown below.
$ cp project/readme.txt projectbackup/

$ cd projectbackup/

$ ls
readme.txt
A directory (and all its content) can be copied from source to destination with the recursive option -r as shown below:
$ ls project
src/  bin/  doc/  lib/  test/  readme.txt  LICENSE

$ cp -r project/ backup/

$ ls backup
src/  bin/  doc/  lib/  test/  readme.txt  LICENSE

2. Copy multiple files or directories

You can copy more than one file from source to destination as shown below:
$ cd src/
$ cp global.c main.c parse.c /home/thegeekstuff/projectbackup/src/
If the source files has a common pattern, use wild-cards as shown below. In this example, all c extension files gets copied to /home/thegeekstuff/projectbackup/src/ directory.
$ cp *.c /home/thegeekstuff/projectbackup/src/
Copy multiple directories as shown below.
$ cd project/

$ cp -r src/ bin/ /home/thegeekstuff/projectbackup/

3. Backup before copying into a destination

In case if the destination file is already present with the same name, then cp allows you to backup the destination file before overwriting it.
In this example, the readme.txt exists in both project/ and projectbackup/ directory, and while copying it from project/ to projectbackup/, the existing readme.txt is backed up as shown below:
$ cd projectbackup

$ ls -l readme.txt
-rw-r--r-- 1 bala geek 1038 Jan  8 13:15 readme.txt

$ cd ../project 

$ ls -l readme.txt
-rw-r--r-- 1 bala geek 1020 Jan  8 12:25 readme.txt

$ cp --backup readme.txt  /home/thegeekstuff/projectbackup/
The existing file has been moved to readme.txt~ and the new file copied as readme.txt as shown below.
$ cd /home/thegeekstuff/projectbackup/
$ ls -l
-rw-r--r-- 1 bala geek 1020 Jan  8 13:36 readme.txt
-rw-r--r-- 1 bala geek 1038 Jan  8 13:15 readme.txt~
Talking about backup, it is important for you to understand how rsync command works to backup files effectively.

4. Preserve the links while copying

When you execute the cp command, if the source is a link file, then the actual file gets copied and not the link file. In case if you only want to copy the link as it is, specify option -d as shown below:
The following shows that without option -d, it will copy the file (and not the link):
$ cd project/bin

$ ls -l startup.sh
lrwxrwxrwx 1 root root 18 Jan  8 13:59 startup.sh -> ../test/startup.sh

$ cp startup.sh /home/thegeekstuff/projectbackup/bin/

$ cd /home/thegeekstuff/projectbackup/bin/

$ ls -l
-rw-r--r--  1 root root       102 Jan  8 14:02 startup.sh
To preserve the link while copying, do the following:
$ cd project/bin

$ cp -d startup.sh /home/thegeekstuff/projectbackup/bin/

$ ls -l startup.sh
lrwxrwxrwx 1 root root 18 Jan  8 14:10 startup.sh -> ../test/startup.sh

5. Don’t overwrite an existing file

If you want to copy only when the destination file doesn’t exist, use option -n as shown below. This won’t overwrite the existing file, and cp command will return with success exit code as shown below:
$ cd projectbackup

$ ls -l readme.txt
-rw-r--r-- 1 bala geek 1038 Jan  8 13:15 readme.txt

$ cd ../project 

$ ls -l readme.txt
-rw-r--r-- 1 bala geek 1020 Jan  8 12:25 readme.txt

$ cp -n readme.txt /home/thegeekstuff/projectbackup/bin/

$ echo $?
0
As you see below, the destination file didn’t get overwritten.
$ cd projectbackup

$ ls -l readme.txt
-rw-r--r-- 1 bala geek 1038 Jan  8 13:15 readme.txt

6. Confirm before overwriting (interactive mode)

When you use -i option, it will ask for confirmation before overwriting a file as shown below.
$ cp -i readme.txt /home/thegeekstuff/projectbackup/
cp: overwrite `/home/thegeekstuff/projectbackup/readme.txt'? y

7. Create hard link to a file (instead of copying)

When you execute cp command, it is possible to create a hard link of the file (instead of copying the file). The following example creates the hard link for sample.txt file into directory test/,
$ ls -li sample.txt
10883362 -rw-r--r-- 2 bala geek   1038 Jan  9 18:40 sample.txt

$ cp -l sample.txt test/ 

$ ls -li test/sample.txt
10883362 -rw-r--r-- 2 bala geek   1038 Jan  9 18:40 test/sample.txt
As seen above, the test/sample.txt is a hard linked file to sample.txt file and the inode of both files are the same.

8. Create Soft link to a file or directory (instead of copying)

When you execute cp command, it is possible to create a soft link to a file or directory. In the following example, a symbolic link gets created for libFS.so.6.0.0 as libFS.so,
# cd /usr/lib/

# ls -l libFS.so.6.0.0
-rw-r--r-- 1 root root 42808 Nov 19  2010 libFS.so.6.0.0

# cp -s libFS.so.6.0.0 libFS.so

# ls -l libFS.so
lrwxrwxrwx 1 root root 14 Jan  9 20:18 libFS.so -> libFS.so.6.0.0

9. Preserve attributes of file or directory while copying

Using -p option, you can preserve the properties of a file or directory as shown below:
$ ls -l sample.txt
-rw-r--r-- 2 bala geek   1038 Jan  9 18:40 sample.txt

$ cp -p sample.txt test/ 

$ ls -l test/sample.txt
-rw-r--r-- 2 bala geek   1038 Jan  9 18:40 test/sample.txt
It is also possible to preserve only the required properties like mode, ownership, timestamps, etc.,
The following example preserves the mode of a file while copying it:
$ cp --preserve=mode sample.txt test/

10. Copy only when source file is newer than the destination or missing

Copy doesn’t take much time for a small file, but it may take considerable amount of time when a huge file is copied. So, while copying a big file, you may want to make sure you do it only when the source file is newer than the destination file, or when the destination file is missing using the option -u as shown below.
In this example, the two files LICENSE and readme.txt will be copied from project/ to projectbackup/. However, the LICENSE file already exists in projectbackup/ directory and that is newer than the one in the project/ directory.
$ cd project/

$ ls -l LICENSE readme.txt
-rw-r--r-- 1 bala geek 108 Jan  8 13:14 LICENSE
-rw-r--r-- 1 bala geek 32 Jan  8 13:16 readme.txt

$ cd /home/thegeekstuff/projectbackup/

$ ls -l LICENSE readme.txt
ls: cannot access readme.txt: No such file or directory
-rw-r--r-- 1 root root 112 Jan  9 20:31 LICENSE
So, in this example, there is no need to copy LICENSE file again to projectbackup/ directory. This is automatically taken care by cp command, if you use -u option as shown below. In the below example, only readme.txt file got copied as indicated by the time-stamp on the file.
$ cp -u -v LICENSE readme.txt  /home/thegeekstuff/projectbackup/
`readme.txt' -> `/home/thegeekstuff/projectbackup/readme.txt'

$ cd /home/thegeekstuff/projectbackup/

$ ls -l LICENSE readme.txt
-rw-r--r-- 1 bala geek  112 Jan  9 20:31 LICENSE
-rw-r--r-- 1 bala geek   32 Jan  9 22:17 readme.txt