Thanks for all your error reports, I didn't forget it. I'll cleanup my guide soon. Thanks again!

Exercise 4. Bash: working with files, pwd, ls, cp, mv, rm, touch

In Linux everything is a file. But what is a file? For now it will suffice to say that it is an object which contains some information. It is usually defined like this:

A computer file is a block of arbitrary information, or resource for storing information, which is available to a computer program and is usually based on some kind of durable storage. A file is durable in the sense that it remains available for programs to use after the current program has finished. Computer files can be considered as the modern counterpart of paper documents which traditionally are kept in offices' and libraries' files, and this is the source of the term.

But this definition is too general, so let us be more specific. man stat tells us that file is an object which has the following properties additionally to information it contains:

struct stat {
   dev_t     st_dev;     /* ID of device containing file */
   ino_t     st_ino;     /* inode number */
   mode_t    st_mode;    /* protection */
   nlink_t   st_nlink;   /* number of hard links */
   uid_t     st_uid;     /* user ID of owner */
   gid_t     st_gid;     /* group ID of owner */
   dev_t     st_rdev;    /* device ID (if special file) */
   off_t     st_size;    /* total size, in bytes */
   blksize_t st_blksize; /* blocksize for file system I/O */
   blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
   time_t    st_atime;   /* time of last access */
   time_t    st_mtime;   /* time of last modification */
   time_t    st_ctime;   /* time of last status change */
};

Don not be intimidated, just remember the following properties:

  • Size, which is exactly what is says on the tin.
  • Time of last access, which is updated when you view a file.
  • Time of last modification, which is updated when you change a file.

Now you will learn how to print out your current directory, files in your directory, copy and move files.

Do this

 1: pwd
 2: ls
 3: ls -a
 4: ls -al
 5: ls -altr
 6: cp -v .bash_history{,1}
 7: cp -v .bash_history1 .bash_history2
 8: mv -v .bash_history1 .bash_history2
 9: rm -v .bash_history2
10: touch .bashrc
11: ls -al
12: ls .*

What you should see

Hello, user1!
user1@vm1:~$ pwd
/home/user1
user1@vm1:~$ ls
user1@vm1:~$ ls -a
.  ..  .bash_history  .bash_history1  .bash_logout  .bashrc  .lesshst  .profile  .profile.bak  .profile.bak1
user1@vm1:~$ ls -al
total 40
drwxr-xr-x 2 user1 user1 4096 Jun  7 13:30 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
-rw------- 1 user1 user1  308 Jun  7 13:14 .bash_history1
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun  6 21:48 .bashrc
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
user1@vm1:~$ ls -altr
total 40
-rw-r--r-- 1 user1 user1 3184 Jun  6 21:48 .bashrc
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
-rw------- 1 user1 user1  308 Jun  7 13:14 .bash_history1
drwxr-xr-x 2 user1 user1 4096 Jun  7 13:30 .
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
user1@vm1:~$ cp -v .bash_history{,1}
`.bash_history' -> `.bash_history1'
user1@vm1:~$ cp -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
user1@vm1:~$ mv -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
user1@vm1:~$ rm -v .bash_history2
removed `.bash_history2'
user1@vm1:~$ touch .bashrc
user1@vm1:~$ ls -al
total 36
drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 .
drwxr-xr-x 3 root  root  4096 Jun  6 21:49 ..
-rw------- 1 user1 user1  853 Jun  7 15:03 .bash_history
-rw-r--r-- 1 user1 user1  220 Jun  6 21:48 .bash_logout
-rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc
-rw------- 1 user1 user1   45 Jun  7 13:31 .lesshst
-rw-r--r-- 1 user1 user1  697 Jun  7 12:25 .profile
-rw-r--r-- 1 user1 user1  741 Jun  7 12:19 .profile.bak
-rw-r--r-- 1 user1 user1  741 Jun  7 13:12 .profile.bak1
user1@vm1:~$
user1@vm1:~$ ls .*
.bash_history  .bash_logout  .bashrc  .lesshst  .profile  .profile.bak  .profile.bak1
 
.:
ls.out
 
..:
user1

Explanation

  1. Prints out your current working directory, which is your home directory. Notice how this differs from ~ in user1@vm1:~, which also indicates that your are in your home directory. That is because ~ is a shortcut for your home directory.
  2. You get nothing here because there are only hidden files in your home directory. Remember, hidden files are ones which names start with a dot.
  3. Prints out all files in your home directory, because -a parameter tells ls to show all files including hidden ones.
  4. Prints out all files in your home directory in long format: permissions, owner, group, size, timestamp (normally modification time) and filename.
  5. Notice how files are now arranged by date, newest files being last. -t tells ls to sort by time, and -r tells ls to reverse the sort.
  6. Copies .bash_history to .bash_history1. It may seem cryptic to you, but explanation is really simple. Bash has a feature called brace expansion, that it has a set of rules which define how constructs like something{1,2,3} are treated. In our case .bash_history{,1} expands into two arguments, namely .bash_history and .bash_history1. Bash just takes a parameter before the brace, .bash_history in our case, and adds everything which is in braces, separated by commas, to this parameter consequentially. First addition becomes just .bash_history because first argument in braces is void, there is no first argument. Next, Bash adds 1 because that's the second argument, and voila! Resulting arguments, which are passed to cp after expansion are -v .bash_history .bash_history1.
  7. This might be obvious for you now. Copies recently created .bash_history1 to .bash_history2.
  8. Moves .bash_history1 to .bash_history2. Notice that it overwrites the destination file without asking, so there is no more .bash_history2, gone!
  9. Removes .bash_history2. Where is no warning, so beware. Also, always use -v key.
  10. Updates .bashrc timestamp to current date and time. This means that all .bashrc time attributes, st_atime, st_mtime and st_ctime are set to current date and time. You may become sure of this by typing in stat .bashrc.
  11. Prints out all files in long format again. Notice how .bashrc timestamps changed.
  12. Prints out files in you home directory in short format. Notice that you get listing of not only of /home/user1 directory, but also of /home directory itself. Do not use this construct with any command, especially rm, ever! Chances are, you will accidentally cripple your system by deleting wrong files or changes access right to them.

Extra credit

  1. Play with bash brace expansion. Start with echo test{1,2,foo,bar}. Try typing in several separate parameters with braces.
  2. Google bash brace expansion, open “Bash Reference Manual” from the search results and read the appropriate section.
  3. Try to find out how and why ls .* works.
  4. Say to yourself 10 times: “I will always use verbose option. Verbose option is commonly accessible as -v parameter”.
  5. Say to yourself 10 times: “I will always use check any hazardous command with ls”.

Discussion

Navigation

Learn Linux The Hard Way