1. I/O重定向

  默认情况下,有3个“文件”处于打开状态,stdin,stdout,stderr;重定向的解释:捕捉一个文件,命令,程序,脚本或者脚本中的代码块的输出,然后将这些输出作为输入发送到另一个文件,命令,程序或者脚本中。

  每个打开的文件都会被分配一个文件描述符,stdin,stdout,stderr的文件描述符分别是0,1,2.除了这3个文件,对于其他需要打开的文件,保留文件描述符3~9.在某些情况下,将这些额外的文件描述符分配给stdin,stdout或stderr作为临时的副本链接也是非常有用的。在经过复杂的重定向和刷新之后需要把他们恢复成正常状态。可以使用shell内建ulimit -n查看最大文件描述符,一般未1024.

ulimit描述如下:

              -a     All current limits are reported
-b The maximum socket buffer size
-c The maximum size of core files created
-d The maximum size of a process's data segment
-e The maximum scheduling priority ("nice")
-f The maximum size of files written by the shell and its children
-i The maximum number of pending signals
-l The maximum size that may be locked into memory
-m The maximum resident set size (many systems do not honor this limit)
-n The maximum number of open file descriptors (most systems do not allow this value to be set)
-p The pipe size in 512-byte blocks (this may not be set)
-q The maximum number of bytes in POSIX message queues
-r The maximum real-time scheduling priority
-s The maximum stack size
-t The maximum amount of cpu time in seconds
-u The maximum number of processes available to a single user
-v The maximum amount of virtual memory available to the shell and, on some systems, to its children
-x The maximum number of file locks
-T The maximum number of threads

ulimit -a结果如下:

core file size          (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 513989
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
 1 COMMAND_OUTPUT >
2 #将stdout重定向到一个文件,如果这个文件不存在,就创建,否则就覆盖
3 : > filename
4 #将filename变成一个空文件(size=0);
5 # :是一个占位符,不产生任何输出
6 > filename
7 #同上,某些shell可能不支持
8
9 COMMAND_OUTPUT >>
10 #将stdout重定向到一个文件,如果这个文件不存在,就创建,否则就追加
11 1> filename
12 #重定向stdout到filename;
13 1>> filename
14 #重定向并追加stdout到filename;
15
16 M>N
17 #M是文件描述符,默认是1;N是一个文件名;文件描述符M被重定向到文件N
18
19 M>&N
20 #M是文件描述符,默认是1;N是一个文件描述符;文件描述符M被重定向到文件N
21
22 2>&1
23 #重定向stderr到stdout,将错误消息的输出,发送到与标准输出所指向的方向
24
25 i>&j
26 #重定向描述符i到j,默认i是1
27
28 0<FILENAME
29 <FILENAME
30 #从文件中接受输入
31
32 [j]<>filename
33 #为了读写filename,把filename打开,并且将文件描述符j分配给它;如果filename不存在,就创建;如果描述符j没指定,默认fd 0,stdin
34 echo 1234567890 > File # 写字符串到"File".
35 exec 3<> File # 打开"File"并且将fd 3分配给它.
36 read -n 4 <&3 # 只读取4个字符.
37 echo -n . >&3 # 写一个小数点
38 exec 3>&- # 关闭fd 3.
39 cat File # ==> 1234.67890
 1 n<&-
2 #关闭输入文件描述符n
3
4 0<&-,<&-
5 #关闭stdin
6
7 n>&-
8 #关闭输出文件描述符n
9
10 1>&-,>&-
11 #关闭stdout

2. 使用exec进行I/O重定向

参考资料:http://www.linuxplus.org/kb/x13380.html

exec <filename命令会将stdin重定向到文件中. 从这句开始, 所有的stdin就都来自于这个文件了, 而不是标准输入(通常都是键盘输入). 这样就提供了一种按行读取文件的方法, 并且可以使用sed和/或awk来对每一行进行分析.

使用exec进行IO重定向可以避免子shell的产生

 1 #!/bin/bash
2 #avoid_subshell.sh
3
4 Lines=0
5 echo
6 cat myfile.txt | while read line; #管道会产生子shell
7 do {
8 echo $line
9 (( Lines++ )); #Lines的自加属于子shell范围,外部不能访问
10 echo "in while Lines is $Lines"
11 }
12 done
13
14 echo "Number of lines read = $Lines" #结果为0,显示的结果是错误的
15 echo "------------------------"
16
17 exec 3<> myfile.txt #使用exec打开文件,使用文件描述符3
18 while read line <&3
19 do {
20 echo "$line"
21 (( Lines++ )); #不会产生子shell
22 }
23 done
24 exec 3>&-
25 echo "Number of lines read = $Lines" #Lines输出的值是正确的
26 exit 0

上述代码中应该增加一行"exec 3<&-";原因:使用<>打开文件的读写操作之后,在关闭时,需要分别关闭文件的读和写,需要分开操作。

其中,myfile.txt的内容如下:

1 Line 1.
2 Line 2.
3 Line 3.
4 Line 4.
5 Line 5.
6 Line 6.
7 Line 7.
8 Line 8.

3. 代码块重定向

参考资料:http://www.linuxplus.org/kb/redircb.html

下面是for循环的重定向example:

 1 #!/bin/bash
2
3 if [ -z "$1" ]
4 then
5 Filename=names.data #
6 else
7 Filename=$1
8 fi
9
10 #Filename=${1:-names.data} #这句可以代替上面的if语句(参数替换)
11
12
13 Savefile=$Filename.new #保存最终结果的文件
14 FinalName=Jonah #终止“read”时的名称
15
16 line_count=`wc $Filename | awk '{ print $1 }'` #目标文件的行数
17 echo "line_count=$line_count"
18
19 for name in `seq $line_count` #seq会打印出数字序列
20 do
21 read name
22 echo "$name"
23 if [ "$name" = "$FinalName" ]
24 then
25 break
26 fi
27 done < "$Filename" > "$Savefile" #重定向stdin到文件$Filename,
28 # 将输出重定向到$Savefile文件
29
30 exit 0

最新文章

  1. Jaunt登陆索尼PSVR,为其提供大量VR视频
  2. PHP采集curl应用的一点小疑惑
  3. [HIHO1393]网络流三&#183;二分图多重匹配
  4. 2014 todo list
  5. 基础KMP两道
  6. 用sqlplus登陆数据库时,oracle 11g出现ORA-12514问题
  7. JavaScript的一些基本语句代码如下!!!!
  8. C++输入输出流的重载
  9. php通过curl实现bigpipe
  10. 【HDU1232】畅通工程(并查集基础题)
  11. [跟我学Spring学习笔记][DI配置与使用]
  12. 轻松学习Asp.net中的控件
  13. MySQL命令窗口下中文显示乱码的解决过程
  14. nginx 支持ipv6设置
  15. 记一次Java调优案例分析
  16. zabbix3.4.7官方解释触发器
  17. Java 11 Tutorial
  18. spring入门常见的问题及解决办法
  19. Ubuntu 14.04(64位)+GTX970+CUDA8.0+Tensorflow配置 (双显卡NVIDIA+Intel集成显卡) ------本内容是长时间的积累,有时间再详细整理
  20. &#39;ascii&#39; codec can&#39;t decode byte 0xd6 in position 0

热门文章

  1. vue-cli3 创建多页面应用项目
  2. spark相关介绍-提取hive表(一)
  3. 每日学习——C++习题
  4. confluence 开源破解
  5. k8s工作负载资源之deployment
  6. php无限分类 构建树形结构
  7. Selenium多浏览器处理 (Chrome/Firefox/IE)
  8. MySQL修改root密码的多种方法, mysql 导出数据库(包含视图)
  9. 学会了这些英文单词,妈妈再也不用担心我学不会Python
  10. 记一次 .NET 某纺织工厂 MES系统 API 挂死分析