Shell Script

10 Data Expression

트리스탄1234 2022. 8. 13. 15:09
728x90
반응형

 

1. Understanding Inputs and Outputs

So far, the data output has been sent to the monitor or sent to a file. But sometimes, you may want to send specific data to the monitor and send specific data to a file. Now, let's see how to use that in a scraipt.

standard file descriptor

Linux systems treat all objects as files. Both output and input are processed as files. This file descriptor is a non-negative integer and a maximum of 9 file descriptors can be opened in one session. In the bash shell, the first three file descriptors are reserved. (No. 0, No. 1, No. 2)

 

STDIN

The standard input file descriptor refers to standard input to the shell. Since the default input to the shell is keyboard, the shell receives and processes keyboard input values ​​from the STDIN file. Using an input redirect (<) causes standard input to be replaced with the file mentioned on the keyboard. The table below describes the standard file descriptor.

STDERR

The shell processes messages through the STDERR file descriptor. STDERR points to the location where error messages are printed. Basically it sends to the monitor the same as stdout. However, if necessary, you can redirect the output to another location.

 

edirecting errors

As shown in the table above, the file descriptor of stderr is #2. Then, if only error is redirected, this number can be used to redirect as follows.

$ ls -al tttfile 2>rrr
$ cat rrr
ls: 'tttfile'에 접근할 수 없습니다: 그런 파일이나 디렉터리가 없습니다
$

 

2. Redirecting output from script

The STDOUT and STDERR file descriptors allow multiple locations of command output within a script.

■ Temporarily redirect each line to a temporary location

■ Permanently redirect the results of all commands to another location within the script. ​

temporary redirect

When redirecting a specific message to STDERR, you must use the & symbol. Let's take a look at the example below.

#! /bin/bash
#Temporarily redirecting STDERR messages
echo "this is an error" >&2 ==> Redirect messages displayed as echo to stderr
echo "this is normal output"

 

If you run it, it is no different from the general output statement. The reason is that by default STDERR is the same as the output location of STDOUT.

$ ./test6
this is an error


this is normal output

 

If you redirect STDERR when executing the script as shown below, you can see that only the error value is saved in another file.

$ ./test6 2> test7
this is normal output
$ cat test7
this is an error
$
반응형

 

permanent redirect

If there is a lot of data to be redirected, it is very cumbersome to redirect through echo for every line. There is an exec command as a command to make this easier. Let's take a look at the script and execution results below.

#! /bin/bash
# permanent redirect
exec 1>test9 ===> All executions of this script via the exec command are set to test9.
echo "test test test"
echo "hello test hello"
echo "redirect redirec redirect"

If you run the script
$ ./test8
$ cat test9
test test test
hello test hello
redirect redirec redirect

3. Redirecting input from script

The usage method is the same as STDOUT and STDERR above. Let's take a look through the script as below

#! /bin/bash
#Testing input redirects
exec 0<testinput ==>Get data input from testinput file
count=1

while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done

If you run it
$ ./testredirect
Line #1:
Line #2: seoul is beautiful city
Line #3: daegu is so hot
Line #4: busan is beautiful beach city
Line #5:
Line #6:
$

 

4. Using custom redirects

As mentioned above, there are a total of 9 file descriptors available in the shell. Among them, 3 are standard file descriptors, and the rest (No. 3 to No. 8) can be used by the user by designating them arbitrarily. Let's look at an example using a custom redirect through the example below.

 

output redirect

#! /bin/bash
#Using custom file descriptors
exec 3>test20 ==>File descriptor 3 is inside the test20 file.


echo "this is test to display monitor" ==>Output to the monitor that is STDOUT
echo "and this is belongs to file" >&3 ==>Save as test20, file descriptor 3
echo "this is diaplyed in monitor" ==> output to monitor

if run this
$ ./test10
this is test to display monitor
this is diaplyed in monitor
$ cat test20
and this is belongs to file
$

Redirect to user file descriptor

#!/bin/bash
# storing STDOUT, then coming back to it
exec 3>&1 ===>Redirect file descriptor 3 to stdout 1
exec 1>test14out ===> Redirect standard output to file test14out
echo "This should store in the output file" ==>Save to file as standard output is to a file
echo "along with this line."
exec 1>&3 ==>Redirect standard output to file descriptor 3 (monitor)
echo "Now things should be back to normal"

if run this
$ ./test14
Now things should be back to normal
$ cat test14out
This should store in the output file
along with this line.
$

 

Redirecting input

#!/bin/bash
# redirecting input file descriptors
exec 6<&0 ==> standard input to file descriptor #6
exec 0< testfile ==> Reading standard input from a file
count=1
while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
exec 0<&6 ==>File descriptor #6 (keyboard) to standard input #0
read -p "Are you done now? " answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, this is the end.";;
esac

if run this
$ ./test15
Line #1: This is the first line.
Line #2: This is the second line.
Line #3: This is the third line.
Are you done now? y
Goodbye
$

 

Using read/write file descriptors

#!/bin/bash
# testing input/output file descriptor
exec 3<> testfile ==>Specifying testfile to receive input output via file descriptor 3
read line <&3 ==>Read the first line from the file.
echo "Read: $line" ==> 읽어 들인 첫번째 라인을 STDOUT을 통해 모니터로 출력
echo "This is a test line" >&3 ==> Save the output of echo statement to testfile as file
descriptor 3

$ cat testfile
This is the first line.
This is the second line.
This is the third line.

if run this
$ ./test16
Read: This is the first line.
$ cat testfile
This is the first line.
This is a test line
ine.
This is the third line.
$

 

close file descriptor

If you create an input/output file descriptor, the shell automatically terminates the file descriptor when the script ends. If it is not automatically terminated and you want to manually terminate the script while it is running, redirect the file descriptor to & as in exec 3>&.

#!/bin/bash
# testing closing file descriptors
exec 3> test17file ===> Redirect the output of #3 to test17file
echo "This is a test line of data" >&3 ===> Save echo statement in test17file
exec 3>&- ===> Exit file descriptor #3
echo "This won’t work" >&3 ===>Save output as number 3

if run this
$ ./badtest
./badtest: 3: Bad file descriptor
$

 

Let's look at an example of terminating a file descriptor and using it again in a script.

#!/bin/bash
# testing closing file descriptors
exec 3> test17file
echo "This is a test line of data" >&3
exec 3>&
cat test17file
exec 3> test17file
echo "This’ll be bad" >&3

$ ./test17
This is a test line of data
$ cat test17file
This’ll be bad
$

 

5. Display open file descriptor.

If you want to inquire the currently open file descriptor among user-defined file descriptors, you can use the lsof command. If you type lsof, all files currently open in Linux, processes running in the background, and information about users logged into the system are displayed. However, if you want to see only the file descriptor, you can use it together with the options below.

 

-a : Performs an AND operation on the result of two options.

 

-p : This option is used to specify a specific PID. To use the currently used PID, you can use the $$ symbol.

 

-d : Used to specify a file descriptor.

The following is an example of outputting file descriptors 0, 1 and 2 of the currently used pid together.

$ lsof -a -p $$ -d 0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 11246 hyowon 0u CHR 136,2 0t0 5 /dev/pts/2
bash 11246 hyowon 1u CHR 136,2 0t0 5 /dev/pts/2
bash 11246 hyowon 2u CHR 136,2 0t0 5 /dev/pts/2

 

A description of each field in the above output is given below.

6. Reducing command output results

If the process running in the background or the user does not want to display an error message, redirecting STDERR to a NULL file can reduce the output.

 

Let's look at some examples below.

$ ls -al > /dev/null ====> Redirect the output of the ls command to /dev/null
$ cat /dev/null
$

$ cat testfile ===> View the contents of testfile.
This is the first line.
This is the second line.
This is the third line.
$ cat /dev/null > testfile ===> Redirect dev/null as input to testfile.
$ cat testfile ===> You can see that all the contents of the file have been deleted.
$

 

7. Using temporary files

Linux provides special directories for temporary files. /tmp directory. Linux systems automatically delete all files in /tmp upon reboot. When you want to create a temporary file, use the mktemp command to create a file. The umask is not applied to the created files, and read and write permissions are granted to the creator, and other users cannot connect.

Creating temporary files

To create a temporary file, specify the file name followed by six X characters.

$mktemp testing.XXXXXX
$ ls -al testing*
-rw------- 1 rich rich 0 Oct 29 21:30 testing.UfIi13
$

 

Let's look at one more script.

#! /bin/bash
# temp file example
tempfile=`mktemp test21.XXXXXX` ===> Creating temporary files using mktemp
exec 3>$tempfile ===>Redirect file descriptor 3 to tempfile

echo "this script writes to temp file $tempfile"
echo "This is the fiest line" >&3 ===> save tempfile에 echo statement
echo "This is the second line" >&3
echo "This is the last line" >&3
exec 3>&- ===> exit File Descript 3

echo "Donw creating tempfile the contents are:" ===>Output echo statement to monitor
cat $tempfile ===>output tempfile's info
rm -f &tempfile 2> /dev/null ===>Drop stderr to null

if run this
$ ./test20
this script writes to temp file test21.qwUPhy
Done creating tempfile the contents are:
This is the fiest line
This is the second line
This is the last line
/tmp/fileQL0qjI

 

Create an entrance exam file under /tmp

The -t option causes the file created by mstemp to be created in the /tmp file. The file name created with the -t option becomes the full file name by adding the file name specified by the user and the path in front of it.

$ mktemp -t test.XXXXXX
/tmp/test.xG3374
$ ls -al /tmp/test*
-rw------- 1 rich rich 0 2007-10-29 18:41 /tmp/test.xG3374

 

Let's see a usage example.

#!/bin/bash
# creating a temp file in /tmp
tempfile=`mktemp -t tmp.XXXXXX`
echo "This is a test file." > $tempfile
echo "This is the second line of the test." >> $tempfile
echo "The temp file is located at: $tempfile"
cat $tempfile
rm -f $tempfile
#
if run t this
$ ./test20
The temp file is located at: /tmp/tmp.Ma3390
This is a test file.
This is the second line of the test.
$

 

Create a temporary directory

The -d option is used to create a temporary directory. Like /tmp, this temporary directory disappears after reboot. So let's look at an example.

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가
#!/bin/bash
# using a temporary directory
tempdir=`mktemp -d dir.XXXXXX` ==> Create a temporary directory.
cd $tempdir ==> 임시 디렉토리로 이동
tempfile1=`mktemp temp.XXXXXX` ==> create temp file
tempfile2=`mktemp temp.XXXXXX` ==> create temp file
exec 7> $tempfile1
exec 8> $tempfile2
echo "Sending data to directory $tempdir" ==> display location of temp file
echo "This is a test line of data for $tempfile1" >&7 ==> save the echo result to temp file
echo "This is a test line of data for $tempfile2" >&8 ==> save the echo result to temp file

messages

Sometimes it is necessary to monitor and save logging messages to a file. In this case, there is a command to enable it instead of redirecting it. You can use the tee command. The command syntax can be used as follows. When the tee command is used, the result is transmitted to the monitor and the specified file.

 

tee filename

$ date | tee testfile
Mon Oct 29 18:56:21 EDT 2007
$ cat testfile
Mon Oct 29 18:56:21 EDT 2007
$


The tee command overwrites its output to a file each time it is executed. If it is not overwritten and you want to add it, you can use it like the example below.


$ date | tee -a testfile
2021. 06. 15. (화) 16:22:55 KST
$ cat testfile
2021. 06. 15. (화) 16:21:15 KST
2021. 06. 15. (화) 16:22:46 KST
2021. 06. 15. (화) 16:22:55 KST

 

#shellscript

#linux

#STDIN

#STDOUT

#STDERR

#data

 

 

728x90
반응형

'Shell Script' 카테고리의 다른 글

12 Making Function  (5) 2022.08.16
11 Script Control  (0) 2022.08.15
9. User data input processing  (1) 2022.08.13
8 Detailed Structed Shell Command  (1) 2022.08.12
7 Structured Command  (5) 2022.08.11