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!
There's no difference between the §-r§ and §-R§ flags.
ReplyDelete