1. 程式人生 > >LinuxSHELL腳本中read、重定向和文件句柄和進程數目控制

LinuxSHELL腳本中read、重定向和文件句柄和進程數目控制

read、文件描述符、重定向、進程控制、

1、把重定向作為read的輸入

read可以從標準輸入讀取一行,下面就使用read配合重定向把文件作為read的標註輸入。

#!/bin/bash
#name:     links.sh
# Revision:    1.1
# Date:        2017//
# Author:      yemo
# Email:       [email protected]
# Website:     
# Description: Print the ip-links
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) yemo
# License:     GPL
#

while read line ;do
	echo "line=$line"
	sleep 2
done </home/yemo/model.txt        #把文件作為read的的輸入

unset line

接下來運行一下

[email protected]:/home/yemo# bash  file_des.sh 
line=#!/bin/bash
line=#name:     links.sh
line=# Revision:    1.1
line=# Date:        2017/6/
line=# Author:      yemo
line=# Email:       [email protected]
line=# Website:
line=# Description: Print the ip-links
line=# Notes:
line=# -------------------------------------------------------------------------------

輸出了我的bash頭部模板文件的內容

2、再話文件描述符

文件在打開時候系統給每一個打開的文件分配用於維護的描述符,這通常包括系統打開文件描述符表,進程級的文件描述符表(文件操作符標誌和文件句柄的引用),文件系統i-node表。

基本用法

exec fd<>file                 #創建一個文件句柄                                    
exec fd>&-   or   exec -fd<&     #關閉文件句柄

創建文件描述符後在/proc/PID/fd中新建,通過$$查看當前shell的PID。

[email protected]
/* */:/home/yemo# cd /proc/$$/fd [email protected]:/proc/6833/fd# ls 0 1 2 255

給文件/home/yemo/model.txt創建一個描述符fd6

[email protected]:/proc/6833/fd# exec 6<>/home/yemo/model.txt
[email protected]:/proc/6833/fd# ls
0  1  2  255  6

打開fd6,查看內容

[email protected]:/proc/6833/fd# cat 6
#!/bin/bash
#name:     links.sh
# Revision:    1.1
#後面挺長就省略了,這不是重點

我們可以通過fd6,讀寫文件model.txt

[email protected]:/proc/6833/fd# echo "hello girl" >>6
[email protected]:/proc/6833/fd# tail -1 6
hello girl

如果刪除文件,fd6會怎麽樣呢

[email protected]:/proc/6833/fd# stat -c %i /home/yemo/model.txt   #先查看下inode
128531
[email protected]:/proc/6833/fd# stat -c %i 6
49938
[email protected]:/proc/6833/fd# rm /home/yemo/model.txt 
[email protected]:/proc/6833/fd# ls
0  1  2  255  6

fd6顯示成紅色,表示文件已經不存在了,我們打開一下

[email protected]:/proc/6833/fd# cat 6
#!/bin/bash
#name:     links.sh
# Revision:    1.1
#此處省略很多行
hello girl

依舊可以打開,文件的刪除只是刪除的上級目錄的存在的一個文件名,當文件在使用時候,並不會釋放inode,只要block的數據沒被覆蓋都可以找回來,這裏文件不大直接打開fd6重定向回去就好。

3、通過fd把文件內容傳給read

[email protected]:/proc/6833/fd# exec 6>&-            #關閉文件句柄
[email protected]:/proc/6833/fd# ls
0  1  2  255

新建腳本測試一下

使用-u選項:

-u fdread from file descriptor FD instead of the standard input

#!/bin/bash
#filename:     file_des.sh
# Revision:    1.1
# Date:        2017-06-09
# Author:      yemo
# Email:       [email protected]
# QQ:		787743742
# Website:     
# Description: 
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) yemo
# License:     GPL

exec 6<>/home/yemo/model.txt                       #創建文件句柄(fd6)

while read -u 6 line ;do                   #循環讀取文件
	echo "line=$line"
	sleep 2
done 
exec 6>&-                          #文件用完,關閉文件句柄
unset line                         #自定義變量,結束釋放

執行結果:

[email protected]:/home/yemo# bash file_des.sh 
line=#!/bin/bash
line=#name:     links.sh
line=# Revision:    1.1
line=# Date:        2017/6/
line=# Author:      yemo
line=# Email:       [email protected]            #後面的內容就省略了

表面上看來這麽做和單獨使用重定向效果一樣,但是當程序需要多個輸入時候,單獨的重定向只能讓read讀取單獨一個文件內容無法為每個單獨指定輸入。

4、通過文件句柄創建多進程

read -u 讀取文件描述符的方式讀取字符串

設置文件描述符中回車數量為預設進程數目

通過循環建立多進程

#!/bin/bash
#filename:     mproc.sh
# Revision:    1.1
# Date:        2017-06-09
# Author:      yemo
# Email:       [email protected]
# QQ:		787743742
# Website:     
# Description: This is use for test shell multiprocess
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) yemo
# License:     GPL
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# you should have received a copy of the GNU General Public License
#
# If any changes are made to this script, please mail me a copy of the changes
# -------------------------------------------------------------------------------
#Version 1.0
#

main_sub() {
	local loop_time=$(( $1 % 7 ))
	echo -e "$i\t----\t---$loop_time begin"
	sleep $loop_time
	echo -e "$i\t-----\t$loop_time end"
}
tmp_file="/tmp/.fifo-$$"
mkfifo $tmp_file                                       #創建fifo文件用於進程通信   
exec 6<>$tmp_file                                      #創建文件句柄6為管道
rm -f $tmp_file


my_thread=6                                           #限制進程數
runtime=50

for (( i=0 ; i < $my_thread ; i++ )) ; do
	echo
done >&6                                           #循環寫入回車符到管道

for (( i=0 ; i < $my_thread ; i++ )) ; do
	  read -u 6                                    #進程數量控制
		{
			main_sub $i
			echo >&6      #每次函數執行完寫入一個回車符,保證進程數目是指定的
		}&                                       #後臺運行
done
wait                                              #父進程等待子進程結束後再退出

exec 6<&-
exit 0




本文出自 “庭前夜末空看雪” 博客,請務必保留此出處http://12550795.blog.51cto.com/12540795/1934220

LinuxSHELL腳本中read、重定向和文件句柄和進程數目控制