Monday, 21 January 2013

Linux File Handling Commands


The bash shell provides lots of commands for manipulating files on the Linux file system. Here  basic commands you will need to work with files from the CLI for all your file-handling needs.
Creating files
Every once in a while you will run into a situation where you need to create an empty file. Sometimes applications expect a log file to be present before they can write to it. In these situations, you can use the touch command to easily create an empty file:
$ touch test1
$ ls -il test1
1954793    -rw-r--r--   1     rich rich   0    Sep 1 09:35    test1
$
The touch command creates the new file you specify, and assigns your username as the file owner. Since I used the -il parameters for the ls command, the first entry in the listing shows the inode number assigned to the file. Every file on the Linux system has a unique inode number.
Notice that the file size is zero, since the touch command just created an empty file. The touch command can also be used to change the access and modification times on an existing file without changing the file contents:
$ touch test1
$ ls -l test1
-rw-r--r--                 1              rich rich   0             Sep 1 09:37             test1
$
The modification time of test1 is now updated from the original time. If you want to change only the access time, use the -a parameter. To change only the modification time, use the –m parameter. By default touch uses the current time. You can specify the time by using the –t parameter with a specific timestamp:
$ touch -t 200812251200 test1
$ ls -l test1
-rw-r--r--                 1 rich rich                0              Dec         25 2008  test1
$
Now the modification time for the file is set to a date significantly in the future from the current time.
Copying files
Copying files and directories from one location in the filesystem to another is a common practice for system administrators. The cp command provides this feature. In it’s most basic form, the cp command uses two parameters: the source object and the destination
object:
cp source destination
When both the source and destination parameters are filenames, the cp command copies the source file to a new file with the filename specified as the destination. The new file acts like a brand new file, with an updated file creation and last modified times:
$ cp test1 test2
$ ls -il
total 0
1954793   -rw-r--r--  1 rich rich  0  Dec 25 2008  test1
1954794   -rw-r--r--  1 rich rich  0  Sep 1 09:39  test2
$
The new file test2 shows a different inode number, indicating that it’s a completely new file. You’ll also notice that the modification time for the test2 file shows the time that it was created. If the destination file already exists, the cp command will prompt you to answer whether or not you want to overwrite it:
$ cp test1 test2
cp: overwrite `test2’? y
$
If you don’t answer y, the file copy will not proceed. You can also copy a file to an existing directory:
$ cp test1 dir1
$ ls -il dir1
total 0
1954887  -rw-r--r--  1  rich rich  0  Sep 6 09:42  test1
$
The new file is now under the dir1 directory, using the same filename as the original. These examples all used relative pathnames, but you can just as easily use the absolute pathname for both the source and destination objects.
To copy a file to the current directory you’re in, you can use the dot symbol:
$ cp /home/rich/dir1/test1 .
cp: overwrite `./test1’?
As with most commands, the cp command has a few command line parameters to help you out. Use the -p parameter to preserve the file access or modification times of the original file for the copied file.
$ cp -p test1 test3
$ ls -il
total 4
1954886                   drwxr-xr-x              2               rich rich  4096   Sep 1 09:42      dir1/
1954793                  -rw-r--r--                  1             rich rich   0        Dec 25 2008      test1
1954794                  -rw-r--r--                 1               rich rich   0        Sep 1 09:39      test2
1954888                  -rw-r--r--                 1              rich rich    0        Dec 25 2008     test3
$
Now, even though the test3 file is a completely new file, it has the same timestamps as the original test1 file.
The -R parameter is extremely powerful. It allows you to recursively copy the contents of an entire directory in one command:
$ cp -R dir1 dir2
$ ls -l
total 8
drwxr-xr-x               2 rich rich                4096     Sep 6 09:42                                dir1/
drwxr-xr-x               2 rich rich                4096     Sep 6 09:45                                dir2/
-rw-r--r--                                  1 rich rich                 0          Dec 25 2008              test1
-rw-r--r--                  1 rich rich                 0          Sep 6 09:39               test2
-rw-r--r--                  1 rich rich                 0          Dec 25 2008              test3
$
Now dir2 is a complete copy of dir1. You can also use wildcard characters in your cp commands:
$ cp -f test* dir2
$ ls -al dir2
total 12
drwxr-xr-x   2 rich rich 4096   Sep 6 10:55   ./
drwxr-xr-x   4 rich rich 4096   Sep 6 10:46   ../
-rw-r--r--      1 rich rich  0        Dec 25 2008  test1
-rw-r--r--      1 rich rich  0        Sep 6 10:55  test2
-rw-r--r--      1 rich rich  0        Dec 25 2008  test3
The cp Command Parameters
Parameter Description
-a           Archive files by preserving their attributes.
-b           Create a backup of each existing destination file instead of overwriting it.
-d           Preserve.
-f            Force the overwriting of existing destination files without prompting.
-i            Prompt before overwriting destination files.
-l            Create a file link instead of copying the files.
-p           Preserve file attributes if possible.
-r            Copy files recursively.
-R          Copy directories recursively.
-s           Create a symbolic link instead of copying the file.
-S          Override the backup feature.
-u          Copy the source file only if it has a newer date and time than the destination (update).
-v          Verbose mode, explaining what’s happening.
-x          Restrict the copy to the current filestytem.
Linking files
You may have noticed a couple of the parameters for the cp command referred to linking files. This is a pretty cool option available in the Linux filesystems. If you need to maintain two (or more) copies of the same file on the system, instead of having separate physical copies, you can use one physical copy and multiple virtual copies, called links. A link is a placeholder in a directory that points to the real location of the file. There are two different types of file links in Linux:
A symbolic, or soft, link
A hard link
The hard link creates a separate file that contains information about the original file and where to locate it. When you reference the hard link file, it’s just as if you’re referencing the original file:
$ cp -l test1 test4
$ ls -il
total 16
1954886      drwxr-xr-x            2 rich rich 4096   Sep 1 09:42  dir1/
1954889     drwxr-xr-x              2 rich rich 4096  Sep 1 09:45  dir2/
1954793     rw-r--r--                  2 rich rich       0  Sep 1 09:51  test1
1954794    -rw-r--r--                 1 rich rich       0  Sep 1 09:39  test2
1954888    -rw-r--r--                 1 rich rich       0  Dec 25 2008  test3
1954793    -rw-r--r--                2 rich rich        0  Sep 1 09:51  test4
$
The -l parameter created a hard link for the test1 file called test4. When I performed the file listing, you can see that the inode number of both the test1 and test4 files are the same, indicating that, in reality, they are both the same file. Also notice that the link count (the third item in the listing) now shows that both files have two links. On the other hand, the -s parameter creates a symbolic, or soft, link:
$ cp -s test1 test5
$ ls -il test*
total 16
1954793       -rw-r--r--         2 rich rich 6 Sep 1 09:51  test1
1954794       -rw-r--r--         1 rich rich 0 Sep 1 09:39  test2
1954888       -rw-r--r--         1 rich rich 0 Dec 25 2008  test3
1954793       -rw-r--r--         2 rich rich 6 Sep 1 09:51  test4
1954891        lrwxrwxrwx   1 rich rich 5 Sep 1 09:56  test5 -> test1
$
There are a couple of things to notice in the file listing, First, you’ll notice that the new test5 file has a different inode number than the test1 file, indicating that the Linux system treats it as a separate file. Second, the file size is different. A linked file needs to store only information about the source file, not the actual data in the file. The filename area of the listing shows the relationship between the two files.
Be careful when copying linked files. If you use the cp command to copy a file that’s linked to another source file, all you’re doing is making another copy of the source file. This can quickly get confusing. Instead of copying the linked file, you can create another link to the original file. You can have many links to the same file with no problems. However, you also don’t want to create soft links to other soft-linked files. This creates a chain of links that can not only be confusing
but also be easily broken, causing all sorts of problems.

Renaming files
In the Linux world, renaming files is called moving. The mv command is available to move both files and directories to another location:
$ mv test2 test6
$ ls -il test*
1954793           -rw-r--r--         2    rich rich 6  Sep 1 09:51   test1
1954888           -rw-r--r--        1   rich rich 0  Dec 25 2008   test3
1954793           -rw-r--r--         2   rich rich 6  Sep 1 09:51   test4
1954891           lrwxrwxrwx    1 rich rich 5  Sep 1 09:56   test5 -> test1
1954794           -rw-r--r--         1   rich rich 0  Sep 1 09:39   test6
$
Notice that moving the file changed the filename but kept the same inode number and the timestamp value. Moving a file with soft links is a problem:
$ mv test1 test8
$ ls -il test*
total 16
1954888    -rw-r--r--                                 1   rich rich            0   Dec 25 2008   test3
1954793    -rw-r--r--                               2   rich rich             6   Sep 1 09:51    test4
1954891    lrwxrwxrwx           1 rich rich                                5   Sep 1 09:56    test5 -> test1
1954794   -rw-r--r--                1    rich rich             0   Sep 1 09:39   test6
1954793    -rw-r--r--                                2    rich rich            6   Sep 1 09:51   test8
[rich@test2 clsc]$ mv test8 test1
The test4 file that uses a hard link still uses the same inode number, which is perfectly fine. However, the test5 file now points to an invalid file, and it is no longer a valid link. You can also use the mv command to move directories:
$ mv dir2 dir4
The entire contents of the directory are unchanged. The only thing that changes is the name of the directory.
Deleting files
Most likely at some point in your Linux career you’ll want to be able to delete existing files.Whether it’s to clean up a filesystem or to remove a software package, there’s always opportunities to delete files.
In the Linux world, deleting is called removing. The command to remove files in the bash shell is rm. The basic form of the rm command is pretty simple:
$ rm -i test2
rm: remove `test2’? y
$ ls -l
total 16
drwxr-xr-x               2 rich rich 4096   Sep 1 09:42   dir1/
drwxr-xr-x               2 rich rich 4096   Sep 1 09:45   dir2/
-rw-r--r--                                 2 rich rich 6   Sep 1 09:51   test1
-rw-r--r--                 1 rich rich 0   Dec 25 2008  test3
-rw-r--r--                 2 rich rich 6   Sep 1 09:51   test4
lrwxrwxrwx             1 rich rich 5 Sep 1 09:56 test5 -> test1
$
Notice that the command prompts you to make sure that you’re serious about removing the file. There’s no trashcan in the bash shell. Once you remove a file it’s gone forever. Now, here’s an interesting tidbit about deleting a file that has links to it:
$ rm test1
$ ls -l
total 12
drwxr-xr-x               2 rich rich 4096   Sep 1 09:42 dir1/
drwxr-xr-x                2 rich rich 4096   Sep 1 09:45 dir2/
-rw-r--r--                 1 rich rich 0        Dec 25 2008 test3
-rw-r--r--                 1 rich rich 6         Sep 1 09:51 test4
lrwxrwxrwx             1 rich rich 5          Sep 1 09:56 test5 -> test1
$ cat test4
hello
$ cat test5
cat: test5: No such file or directory
$
I removed the test1 file, which had both a hard link with the test4 file and a soft link with the test5 file. Noticed what happened. Both of the linked files still appear, even though the test1 file is now gone (although on my color terminal the test5 filename now appears in red). When I look at the contents of the test4 file that was a hard link, it still shows the contents of the file. When I look at the contents of the test5 file that was a soft link, bash indicates that it doesn’t
exist any more. Remember that the hard link file uses the same inode number as the original file. The hard link
file maintains that inode number until you remove the last linked file, preserving the data! All the soft link file knows is that the underlying file is now gone, so it has nothing to point to. This is an important feature to remember when working with linked files. One other feature of the rm command, if you’re removing lots of files and don’t want to be bothered
with the prompt, is to use the -f parameter to force the removal. Just be careful!

1 comment:

  1. There's no difference between the §-r§ and §-R§ flags.

    ReplyDelete