File handling

In this section, you will learn about handling files for reading and writing. In Chapter 8, Automating Decision Making in Scripts, you will learn about checking various attributes of files along with decision making constructs, such as if, case, and similar.

Introducing file handling

The exec command is very interesting. Whenever we run any command in shell, the new subshell or process gets created, and the command runs in this newly created process. When we run any command as argument to the exec command, exec will replace the current shell with the command to be executed. It does not create or spawn a new process to run the command.

Using exec to assign file descriptor (fd) to file

In the Bash shell environment, every process has three files opened by default. These are standard input, display, and error. The file descriptors associated with them are 0, 1, and 2 respectively. In the Bash shell, we can assign the file descriptor to any input or output file. These are called file descriptors.

The syntax for declaring output.txt as output is as follows:

exec fd > output.txt

This command will declare the number fd as an output file descriptor.

The syntax for closing the file is as follows:

exec fd<&-

To close fd, which is 5, enter the following:

exec 5<&-

We will try to understand these concepts by writing scripts.

Understanding the opening, writing, and closing of a file

Let's understand the opening, closing, and writing of a file.

Write a Shell script file_01.sh, shown as follows:

#!/bin/bash
# We will open file for writing purpose
# We are assigning descriptor number 3 for file sample_out.txt
exec 3> sample_out.txt

# We are sending output of command "echo" to sample_out.txt file
echo "This is a test message for sample_out.txt file" >&3

# Run command date & store output in file sample_out.txt
date >&3

# Closing file with file descriptor 3
exec 3<&-

Save the file, give the permission to execute, and run the script as follows:

$ chmod u+x file_01.sh
$ ./file_01.sh
$ cat sample_out.txt

Output:

This is a test message for sample_out.txt file
Tue Sep 29 23:19:22 IST 2015

Understanding reading from a file

Let's write script to read from a file:

Write the script file_02.sh, shown as follows:

#!/bin/bash
# We will open file sample_input.txt for reading purpose.
# We are assigning descriptor 3 to the file.
exec 3< sample_input.txt

cat <&3
# Closing file
exec 3<&-

Save the file, give the permission to execute, and run the script as follows:

$ chmod u+x file_02.sh

We will create the sample_input.txt file as follows:

$ echo "Hello to All" > sample_input.txt

Run the script and check the result:

$ ./file_02.sh

Output:

Hello to All

Understanding reading and writing to a file

In the earlier examples, we opened the file either for reading or writing. Now, we will see how to open the file for reading and writing purposes:

exec fd<> fileName

If the file descriptor number is not specified, then 0 will be used in its place. The file will be created if it does not exist. This procedure is useful to update files.

Let's understand following script.

Write the Shell script file_03.sh as follows:

#!/bin/bash
file_name="sample_out.txt"
# We are assing fd number 3 to file.
# We will be doing read and write operations on file
exec 3<> $file_name

# Writing to file
echo """
 Do not dwell in the past,
 do not dream of the future,
 concentrate the mind on the present moment. - Buddha
""" >&3
# closing file with fd number 3
exec 3>&-

Using command read on file descriptor (fd)

We can use command read to get data from a file to store it in variables. The procedure for using the read command to get text from a file is as follows:

read -u fd variable1 variable2 ... variableN

Reading from one file and writing to another file

Now, we will see how to read from one file and write to another. Let's write script file_04.sh as follows:

#!/bin/bash
# We are assigning descriptor 3 to in_file.txt
exec 3< in_file.txt
# We are assigning descriptor 4 to out_file.txt
exec 4> out_file.txt

# We are reading first line of input.txt
read -u 3 line

echo $line

echo "Writing content of in_file.txt to out_file.txt"
echo  "Line 1 - $line " >&4

# Closing both the files
exec 3<&-
exec 4<&-

Save the file, give the permission to execute, and run the script as follows:

$ chmod u+x file_04.sh
$ echo "Sun is at the center of Solar System." > in_file.txt
$ cat in_file.txt

Output:

Sun is at the center of Solar System.
$ ./file_04.sh

Output:

Sun is at the center of Solar System.
Writing content of in_file.txt to out_file.txt
$ cat out_file.txt

Output:

Line 1 - Sun is at the center of Solar System.

In this example, we read the complete line in the variable line and we used the same variable to write it to another file.

Let's write one more script file_05.sh to get the hostname and addresses:

#!/bin/sh

cp /etc/hosts hosts2

grep -v '^#' hosts2 > hosts3

exec 3< hosts3    # opening hosts3 as input file

exec 4> hostsfinal  # opening hostsfinal as output file

read <& 3 address1 name_1 extra_info
read <& 3 address2 name_2 extra_info

echo $name_1 $address1 >& 4
echo $name_2 $address2 >& 4

exec 3<&-      # Closing hosts3
exec 4<&-      # Closing hostsfinal

In this script, we used the variables address1, name_1, extra_info, address2, and name_2 to store useful information.

Displaying the file descriptor information from the /proc folder

We will write the script to display the actual file descriptors associated with the file.

Let's write the script file_06.sh, shown as follows:

#!/bin/bash
# we are assigning file descriptor 3 to input file test.txt
exec 3< test.txt
# we are assigning file descriptor 4 to output.txt
exec 4> output.txt
# we are using read command to read line from file
read -u 3 line
echo "Process id of current process is $$"
my_pid=$$
echo "Currently following files are opened by $0 script :"
ls -l /proc/$my_pid/fd

# We are closing both files test.txt and output.txt
exec 3<&-
exec 4>&-

File handling – reading line by line

You will learn how to use the while loop and the read command to read a file line by line. You will learn more about the while loop in the upcoming chapters.

Let's write the script file_07.sh, shown as follows:

#!/bin/bash
echo "Enter the name of file for reading"
read file_name
exec<$file_name
while read var_line
do
  echo $var_line
done

For executing the preceding script, we will need to create a file with some text in it. Then, we will pass this file name for reading purposes.

Executing the command and storing the results in a file

The following is the syntax for storing the output of a command in a file:

Command >& fd
./script >& fd

The following is the illustrative example script file_08.sh:

#!/bin/bash
exec 4> output.txt
cat /proc/cpuinfo  >&4
exec 3<&-

Save the file, give the permission to execute, and run the script as follows:

$ chmod u+x file_08.sh
$ ./file_08.sh

Output:

Executing the command and storing the results in a file

In this example, we have executed the command cat /proc/cpuinfo and we have stored the output in file output.txt.

Summarizing usage of the exec command

The following is the summary of the exec command for using various file handling-related operations:

Command

What it does

exec command

This command will replace shell and execute it. Therefore, it will not return to its original shell, which started it.

exec > data.txt

This opens data.txt for writing standard output.

exec < data.txt

This opens data.txt for reading standard input.

exec 3< data.txt

This opens data.txt for reading with descriptor 3.

sort <&3

This will sort data.txt file

exec 4>data.txt

This opens data.txt for writing with descriptor 4.

ll >&4

The output of ll is redirected to data.txt.

exec 6<&5

This makes fd 6 a copy of fd 5

exec 4<&–

This closes fd 4.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset