linux数据脚本整合,Linux 命令 & shell 脚本之08(呈现数据)

1.Linux的标准文件描述符

文件描述符 缩写 描 述

0 STDIN 标准输入

1 STDOUT 标准输出

2 STDERR 标准错误

2.STDIN

STDIN文件描述符代表shell的标准输入。对终端界面来说,标准输入是键盘.

在使用输入重定向符号(

它会读取文件并提取数据,就如同它是键盘上键入的.

[oracle@DB02 15]$ cat testfile.txt

first line.

second line.

third line.

[oracle@DB02 15]$ cat < testfile.txt

first line.

second line.

third line.

3.STDOUT

STDOUT文件描述符代表shell的标准输出。在终端界面上,标准输出就是终端显示器.

可以用输出重定向来改变.

[oracle@DB02 15]$ ls -l

total 4

-rw-r--r-- 1 oracle oinstall 39 Sep 29 06:57 testfile.txt

[oracle@DB02 15]$ ls -l > test2

也可以将数据追加到某个文件。这可以用>>符号来完成

[oracle@DB02 15]$ who >> test2

[oracle@DB02 15]$ cat test2

total 4

-rw-r--r-- 1 oracle oinstall 0 Sep 29 07:02 test2

-rw-r--r-- 1 oracle oinstall 39 Sep 29 06:57 testfile.txt

root tty1 2019-10-15 10:07

oracle pts/0 2020-09-25 07:06 (10.3.20.85)

3.STDERR

問題(命令報錯時無法將信息輸出給 test3)

[oracle@DB02 15]$ ls -l noexistsfile > test3

ls: cannot access noexistsfile: No such file or directory

[oracle@DB02 15]$ cat test3

重定向错误命令

[oracle@DB02 15]$ ls -l noexistsfile 2> test4

[oracle@DB02 15]$ cat test4

ls: cannot access noexistsfile: No such file or directory

将STDOUT和STDERR消息混杂在同一输出中的例子

[oracle@DB02 15]$ ls -l testfile.txt noexistsfile 2> test5

-rw-r--r-- 1 oracle oinstall 39 Sep 29 06:57 testfile.txt

[oracle@DB02 15]$ cat test5

ls: cannot access noexistsfile: No such file or directory

重定向错误和数据

[oracle@DB02 15]$ ls -l testfile.txt noexistsfile 2> test6 1> test7

[oracle@DB02 15]$ cat test6

ls: cannot access noexistsfile: No such file or directory

[oracle@DB02 15]$ cat test7

-rw-r--r-- 1 oracle oinstall 39 Sep 29 06:57 testfile.txt

可以将STDERR和STDOUT的输出重定向到同一个输出文件。为此bash shell提供了特殊的重定向符号&>

[oracle@DB02 15]$ ls -l testfile.txt noexistsfile &> test8

[oracle@DB02 15]$ cat test8

ls: cannot access noexistsfile: No such file or directory

-rw-r--r-- 1 oracle oinstall 39 Sep 29 06:57 testfile.txt

4.在脚本中重定向输出(临时重定向)

如果有意在脚本中生成错误消息,可以将单独的一行输出重定向到STDERR。你所需要做的

是使用输出重定向符来将输出信息重定向到STDERR文件描述符。在重定向到文件描述符时,你

必须在文件描述符数字之前加一个&:

[oracle@DB02 15]$ echo "This is an error message" >&2

This is an error message

$ cat test8.sh

#!/bin/bash

# testing STDERR messages

echo "This is an error" >&2

echo "This is normal output"

如果像平常一样运行这个脚本,你可能看不出什么区别。

$ ./test8.sh

This is an error

This is normal output

如果你在运行脚本时重定向了STDERR,脚本中所有导向STDERR的文本都会被重定向

$ ./test8.sh 2> test9

This is normal output

$ cat test9

This is an error

5.在脚本中重定向输出(永久重定向)

如果脚本中有大量数据需要重定向,那重定向每个echo语句就会很烦琐。取而代之,你可

以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符

$ cat test10.sh

#!/bin/bash

# redirecting all output to a file

exec 1>testout

echo "This is a test of redirecting all output"

echo "from a script to another file."

echo "without having to redirect every individual line"

$ ./test10.sh

$ cat testout

This is a test of redirecting all output

from a script to another file.

without having to redirect every individual line

可以在脚本执行过程中重定向STDOUT。

$ cat test11.sh

#!/bin/bash

# redirecting output to different locations

exec 2>testerror

echo "This is the start of the script"

echo "now redirecting all output to another location"

exec 1>testout

echo "This output should go to the testout file"

echo "but this should go to the testerror file" >&2

$ ./test11.sh

This is the start of the script

now redirecting all output to another location

$ cat testout

This output should go to the testout file

$ cat testerror

but this should go to the testerror file

6.在脚本中重定向输入

你可以使用与脚本中重定向STDOUT和STDERR相同的方法来将STDIN从键盘重定向到其他

位置。exec命令允许你将STDIN重定向到Linux系统上的文件中:

exec 0< testfile --这个命令会告诉shell它应该从文件testfile中获得输入,而不是STDIN

[oracle@DB02 15]$ cat test12.sh

#!/bin/bash

# redirecting file input

exec 0< testfile.txt

count=1

while read line; do

echo "Line #$count: $line"

count=$[ $count + 1 ]

done

[oracle@DB02 15]$ ./test12.sh

Line #1: first line.

Line #2: second line.

Line #3: third line.

7.创建自己的重定向(创建输出文件描述符)

在shell中最多可以有9个打开的文件描述符。其他6个从3~8的文件描述符均可用作输入或输出重定向。

你可以将这些文件描述符中的任意一个分配给文件,然后在脚本中使用它们。

可以用exec命令来给输出分配文件描述符。和标准的文件描述符一样,一旦将另一个文件

描述符分配给一个文件,这个重定向就会一直有效,直到你重新分配。

$ cat test13

#!/bin/bash

# using an alternative file descriptor

exec 3>test13out

echo "This should display on the monitor"

echo "and this should be stored in the file" >&3

echo "Then this should be back on the monitor"

$ ./test13

This should display on the monitor

Then this should be back on the monitor

$ cat test13out

and this should be stored in the file

这个脚本用exec命令将文件描述符3重定向到另一个文件。当脚本执行echo语句时,输出内

容会像预想中那样显示在STDOUT上。但你重定向到文件描述符3的那行echo语句的输出却进入

了另一个文件。这样你就可以在显示器上保持正常的输出,而将特定信息重定向到文件中(比如

日志文件)。

也可以不用创建新文件,而是使用exec命令来将输出追加到现有文件中。

exec 3>>test13out

现在输出会被追加到test13out文件,而不是创建一个新文件

8.创建自己的重定向(重定向文件描述符)

恢复已重定向的文件描述符。可以分配另外一个文件描述符给标准文件描述

符,反之亦然。这意味着你可以将STDOUT的原来位置重定向到另一个文件描述符,然后再利用

该文件描述符重定向回STDOUT。

$ cat test14.sh

#!/bin/bash

# storing STDOUT, then coming back to it

#本将文件描述符3重定向到文件描述符1的当前位置,也就是STDOUT

exec 3>&1

exec 1>test14out

echo "This should store in the output file"

echo "along with this line."

#将STDOUT重定向到文件描述符3的当前位置(现在仍然是显示器)。这意味着现在STDOUT又指向了它原来的位置:显示器

exec 1>&3

echo "Now things should be back to normal"

$ ./test14.sh

Now things should be back to normal

$ cat test14out

This should store in the output file

along with this line.

9.创建自己的重定向(创建输入文件描述符)

可以用和重定向输出文件描述符同样的办法重定向输入文件描述符。在重定向到文件之前,

先将STDIN文件描述符保存到另外一个文件描述符,然后在读取完文件之后再将STDIN恢复到它原来的位置。

[oracle@DB02 15]$ cat test15.sh

#!/bin/bash

# redirecting input file descriptors

#文件描述符6用来保存STDIN的位置

exec 6

exec 0< testfile.txt

count=1

while read line; do

echo "Line #$count: $line"

count=$[ $count + 1 ]

done

#将STDIN重定向到文件描述符6,从而将STDIN恢复到原先的位置:键盘的输入

exec 0

read -p "Are you done now? " answer

case $answer in

Y|y) echo "Goodbye";;

N|n) echo "Sorry, this is the end.";;

esac

----------------------------------------------------

[oracle@DB02 15]$ ./test15.sh

Line #1: first line.

Line #2: second line.

Line #3: third line.

Are you done now? n

Sorry, this is the end.

创建自己的重定向(创建读写文件描述符)

可以打开单个文件描述符来作为输入和输出。可以用同一个文件描述符对同一个文件进行读写。

不过用这种方法时,你要特别小心。由于你是对同一个文件进行数据读写,shell会维护一个

内部指针,指明在文件中的当前位置。任何读或写都会从文件指针上次的位置开始。如果不够小

心,它会产生一些令人瞠目的结果。看看下面这个例子:

[oracle@DB02 15]$ cat test16.sh

#!/bin/bash

# testing input/output file descriptor

#了exec命令将文件描述符3分配给文件testfile.txt以进行文件读写

exec 3<> testfile.txt

read line

echo "Read First: $line"

echo "test line" >&3

[oracle@DB02 15]$ cat testfile.txt

first line.

second line.

third line.

[oracle@DB02 15]$ ./test16.sh

Read First: first line.

[oracle@DB02 15]$ cat testfile.txt

first line.

test line

e.

third line.

11.关闭文件描述符

创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭它们。然而在有些

情况下,你需要在脚本结束前手动关闭文件描述符。

要关闭文件描述符,将它重定向到特殊符号&-。脚本中看起来如下:

exec 3>&-

一旦关闭了文件描述符,就不能在脚本中向它写入任何数据,否则shell会生成错误消息

$ cat badtest

#!/bin/bash

# testing closing file descriptors

exec 3> test17file

echo "This is a test line of data" >&3

exec 3>&-

echo "This won't work" >&3

$ ./badtest

./badtest: 3: Bad file descriptor

阻止命令输出

在Linux系统上null文件的标准位置是/dev/null。你重定向到该位置的任何数据都会被丢掉,不会显示

$ ls -l > /dev/null

$ cat /dev/null

是避免出现错误消息,也无需保存它们的一个常用方法

[oracle@DB02 15]$ ls -l testfile.txt noexistsfile 2> /dev/null

-rw-r--r-- 1 oracle oinstall 39 Sep 29 08:33 testfile.txt

速清除现有文件中的数据--在输入重定向中将/dev/null作为输入文件。由于/dev/null文件不含有任何内容

[oracle@DB02 15]$ cat /dev/null > testfile.txt

[oracle@DB02 15]$ cat testfile.txt

12.创建临时文件(创建本地临时文件)

mktemp会在本地目录中创建一个文件。要用mktemp命令在本地目录中创建一个临时文件,你只要指定一个文件名模板就行了。

模板可以包含任意文本文件名,在文件名末尾加上6个X就行了

[oracle@DB02 15]$ mktemp tmp.XXXXXX --mktemp命令会用6个字符码替换这6个X,从而保证文件名在目录中是唯一的

tmp.FwegMN

[oracle@DB02 15]$ ls tmp*

tmp.FwegMN

在脚本中使用mktemp命令时,可能要将文件名保存到变量中,这样就能在后面的脚本中引用了

$ cat test19.sh

#!/bin/bash

# creating and using a temp file

tempfile=$(mktemp test19.XXXXXX)

exec 3>$tempfile

echo "This script writes to temp file $tempfile"

echo "This is the first line" >&3

echo "This is the second line." >&3

echo "This is the last line." >&3

exec 3>&-

echo "Done creating temp file. The contents are:"

cat $tempfile

rm -f $tempfile 2> /dev/null

$ ./test19.sh

This script writes to temp file test19.vCHoya

Done creating temp file. The contents are:

This is the first line

This is the second line.

This is the last line.

$ ls -al test19*

-rwxr--r-- 1 rich rich 356 Oct 29 22:03 test19*

13.创建临时文件(在/tmp 目录创建临时文件)

-t选项会强制mktemp命令来在系统的临时目录来创建该文件。在用这个特性时,

mktemp命令会返回用来创建临时文件的全路径,而不是只有文件名

[oracle@DB02 15]$ mktemp -t tmp.XXXXXX

/u01/tmp/tmp.0BPnVH

[oracle@DB02 15]$ ls /u01/tmp/tmp*

/u01/tmp/tmp.0BPnVH

$ cat test20.sh

#!/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

$ ./test20.sh

The temp file is located at: /tmp/tmp.Ma3390

This is a test file.

This is the second line of the test.

14.创建临时目录

-d选项告诉mktemp命令来创建一个临时目录而不是临时文件。这样你就能用该目录进行任

何需要的操作了,比如创建其他的临时文件

$ cat test21.sh

#!/bin/bash

# using a temporary directory

tempdir=$(mktemp -d dir.XXXXXX)

cd $tempdir

tempfile1=$(mktemp temp.XXXXXX)

tempfile2=$(mktemp temp.XXXXXX)

exec 7> $tempfile1

exec 8> $tempfile2

echo "Sending data to directory $tempdir"

echo "This is a test line of data for $tempfile1" >&7

echo "This is a test line of data for $tempfile2" >&8

$ ./test21.sh

Sending data to directory dir.ouT8S8

$ ls -al

total 72

drwxr-xr-x 3 rich rich 4096 Oct 17 22:20 ./

drwxr-xr-x 9 rich rich 4096 Oct 17 09:44 ../

drwx------ 2 rich rich 4096 Oct 17 22:20 dir.ouT8S8/

-rwxr--r-- 1 rich rich 338 Oct 17 22:20 test21*

$ cd dir.ouT8S8

[dir.ouT8S8]$ ls -al

total 16

drwx------ 2 rich rich 4096 Oct 17 22:20 ./

drwxr-xr-x 3 rich rich 4096 Oct 17 22:20 ../

-rw------- 1 rich rich 44 Oct 17 22:20 temp.N5F3O6

-rw------- 1 rich rich 44 Oct 17 22:20 temp.SQslb7

[dir.ouT8S8]$ cat temp.N5F3O6

This is a test line of data for temp.N5F3O6

[dir.ouT8S8]$ cat temp.SQslb7

This is a test line of data for temp.SQslb7

记录消息(tee)

tee命令相当于管道的一个T型接头。它将从STDIN过来的数据同时发往两处。一处是STDOUT,另一处是tee命令行所指定的文件名

tee filename

由于tee会重定向来自STDIN的数据,你可以用它配合管道命令来重定向命令输出。

$ date | tee testfile

Sun Oct 19 18:56:21 EDT 2014

$ cat testfile

Sun Oct 19 18:56:21 EDT 2014

输出出现在了STDOUT中,同时也写入了指定的文件中。注意,默认情况下,tee命令会在每

次使用时覆盖输出文件内容,如果你想将数据追加到文件中,必须用-a选项。

$ date | tee -a testfile

利用这个方法,既能将数据保存在文件中,也能将数据显示在屏幕上。

$ cat test22.sh

#!/bin/bash

# using the tee command for logging

tempfile=test22file

echo "This is the start of the test" | tee $tempfile

echo "This is the second line of the test" | tee -a $tempfile

echo "This is the end of the test" | tee -a $tempfile

$ ./test22.sh

This is the start of the test

This is the second line of the test

This is the end of the test

$ cat test22file

This is the start of the test

This is the second line of the test

This is the end of the test

csv to sql 案例

$cat test23.sh

#!/bin/bash

# read file and create INSERT statements for MySQL

outfile='members.sql'

IFS=','

while read lname fname address city state zip; do

cat >> $outfile << EOF

INSERT INTO members (lname,fname,address,city,state,zip) VALUES

('$lname', '$fname', '$address', '$city', '$state', '$zip');

EOF

done < ${1}

脚本中出现了三处重定向操作

1: 在done语句中出现的重定向符号:done < ${1}

2、3:另外两处重定向操作出现在同一条语句中: cat >> $outfile << EOF

这条语句中包含一个输出追加重定向(双大于号)和一个输入追加重定向(双小于号)。

输出重定向将cat命令的输出追加到由$outfile变量指定的文件中。cat命令的输入不再取自标准

输入,而是被重定向到脚本中存储的数据。EOF符号标记了追加到文件中的数据的起止。

在这个例子中,使用以下输入数据文件。

$ cat members.csv

Blum,Richard,123 Main St.,Chicago,IL,60601

Blum,Barbara,123 Main St.,Chicago,IL,60601

Bresnahan,Christine,456 Oak Ave.,Columbus,OH,43201

Bresnahan,Timothy,456 Oak Ave.,Columbus,OH,43201

运行脚本时,显示器上不会出现任何输出:

$ ./test23 < members.csv

在members.sql输出文件中,你会看到如下输出内容。

$ cat members.sql

INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',

'Richard', '123 Main St.', 'Chicago', 'IL', '60601');

INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Blum',

'Barbara', '123 Main St.', 'Chicago', 'IL', '60601');

INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan',

'Christine', '456 Oak Ave.', 'Columbus', 'OH', '43201');

INSERT INTO members (lname,fname,address,city,state,zip) VALUES ('Bresnahan',

'Timothy', '456 Oak Ave.', 'Columbus', 'OH', '43201');

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值