第 15 章 呈现数据

5.1 理解输入输出

  两种显示脚本输出的方法:

  1、在显示器上显示

  2、将输出重定向到文件中

15.1.1 标准文件描述符

  文件描述符    缩写    描述

  0        STDIN   标准输入

  1        STDOUT  标准输出

  2        STDERR  标准错误

  默认情况下STDERR文件描述符和STDOUT 文件描述符指向同样的地方

15.1.2 命令行重定向

  1、将文件描述符紧紧的放在重定向符号前,实现重定向错误

  

   2、重定向错误和数据

  

  3、可以将STDERR和STDOUT的输出重定向到同一个输出文件     &>

  

15.2 在脚本中重定向输出

15.2.1 临时重定向

  1、临时重定向是指某条输出临时重定向到某个文件描述符

  

  可以在脚本中, 重定向文件描述符时,必须在文件描述符之前加上 & ,且不能有空格

  

15.2.2、永久性重定向脚本中的所有命令

    如果脚本中有大量数据需要重定向, 那重定向每个echo 语句就会有些烦琐,取而代之, 你可以使用exec命令告诉shell在脚本指向期间重定向某个特定文件描述符。

  

#!/bin/bash

exec 1>testout # 1> 和testout之间可以有空格
exec 2>testout1 # 重定向标准错误

echo "This is a test of redirecting all output"
echo "From a script to another file" >&2
# 一旦重定向STDOUT 或者 STDERR, 就很难再将他们重定向回原来的位置

15.3 在脚本中重定向输入

  

#!/bin/bash

exec 0< testfile
count=1

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

15.4 创建自定义重定向

  1、创建输出文件描述符;2、重定向文件描述符 3、创建输入文件描述符;4、创建读写文件描述符;5、关闭文件描述符

  

#!/bin/bash
echo 
exec 3>testfile # 创建输出文件描述符

echo "创建输出文件描述符" >&3 # 内容输出到 testfile

#重定向文件描述符, 指向已有的文件描述符, 不会受指向的描述符的改变而改变
exec 3>&1 # 保存文件描述符, 指向文件描述符即保存文件描述符

exec 1>testfile
echo "This should store in the output file"
echo "along with this line"

echo 1>&3 # 还原文件描述符, 指向之间保存的文件描述符

echo "Now things should be normal"

 15.4.3 创建输入文件描述符

  可以用和重定向输出文件描述符的方法重定向输入文件描述符

  

#!/bin/bash

#redirecting input file descriptors

exec 6<&0
exec 0< testfile

count=1
while read line; do
    echo "Line #$count:$line"
    count=$[ $count + 1 ]
done
exec 0<&6
read -p "Are you done now?" answer
cast $answer in
Y | y) echo "Goodbye";;
N | n) echo "Sorry, this is the end.";;
esac

15.4.4 创建读写文件描述符

  使用此方法时,应特别小心, 由于你是对同一个文件进行数据读写操作, shell会维护一个内部指针, 指明在文件中的当前位置, 任何读取或写入都从文件指针上次的位置开始。

  

#!/bin/bash
#testing input/output file descriptor

exec 3<> testfile
read line <&3

echo "Read: $line"
echo "This is a test line" >&3

15.4.5 关闭文件描述符

  如果你创建了新的输入或输出文件描述符, shell会在脚本退出时自动关闭他们,然而在某些情况下, 你需要在脚本结束前手动关闭文件描述符。

  关闭文件描述符, 将它重定向到特殊符号 &-

  exec 3>&-

  

#!/bin/bash

exec 3> test17file
echo "This is a test line of data" >&3
exec 3>&- # 文件描述符一旦关闭, 就不能向它写入任何数据,否则shell会生成错误
echo "This won't work" >&3

  

15.5 列出打开的文件描述符

  lsof 命令会列出整个linux系统打开的所有文件描述符, 但它会向非系统管理员用户提供linux系统信息, 鉴于此, 许多linux系统隐藏了该命令, 这样用户就不会一不小心就发现它,

  在很多linux系统中(Fedora), lsof命令位于/user/sbin/目录,想要以普通用户账户来运行它,必须通过全路径名来引用:

  $/usr/sbin/lsof

  lsof  有两个参数 -p 和 -d,前者允许指定进程ID, 后者允许指定文件描述符编号

  想要知道进程的当前PID, 可以用特殊环境变量$$ (shell 会将它设为当前PID) . -a 选项用来对其他两个选项的结果指向布尔AND 运算。 这回产生如下结果:

  

15.6 阻止命令输出

  1、有时候, 你可能不想显示脚本输出, 这在脚本作为后台运行时很常见, 可以将STDERR重定向到一个叫做null文件的特殊文件。在linux系统中null文件的标准位置是/dev/null

    

 

  2、有时候,也用/dev/null 来清除某个文件

    cat /dev/null > testfile

15.7.1 创建临时文件

  mktemp testing.XXXXXX

  mktemp -t testing.XXXXXX 在指定/tmp路径下创建临时文件

  mktemp -d dir.XXXXXX 在创建临时目录

15.8 记录消息

  将输出同时发送到显示器和日志文件, 只要用特殊的tee命令就行

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

  tee filename

  

15.9 实例

  

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

 

   

 

 

    

    

  

  

posted on 2018-05-22 15:47  牛大黑  阅读(90)  评论(0)    收藏  举报

导航