詳解Unix Linux中Shell指令碼的輸入輸出

2021-05-22 11:02:35 字數 2726 閱讀 2942

shell的i/o語法比較複雜,難以理解,更難以正確使用。shell的輸入輸出語法有兩個難點:重定向和檔案描述符。我以前對shell指令碼輸入/輸出的理解也有錯誤。最近重新整理思路,決定寫一篇文章來總結i/o重定向。

一、先介紹幾個基本概念:

(1)檔案(file):在unix/linux中,檔案型別有七種,這七種型別是:目錄、符號鏈結(指向另乙個檔案)、套接字檔案、塊裝置檔案、字元裝置檔案、命名管道檔案、普通檔案。這意味著,i/o裝置被unix/linux視為「特殊」的檔案,所以對裝置進行輸入輸出等同於讀寫檔案。

(2)檔案描述符(file descriptor ):實際上,shell中的檔案描述符等同於c語言中的檔案結構(參見《the c programming languag》的7.5節),它是乙個包含檔案資訊的結構,這些資訊包括:緩衝區的位置,緩衝區中當前字元的位置,檔案是否到達末尾等。shell指令碼通過檔案描述符來讀寫檔案。乙個shell指令碼有10個檔案描述符。其中,0、1、2是標準輸入、標準輸出和標準錯誤,我們可以任意使用的檔案描述符是3 到9。

(3)重定向(redirect):在shell中,我們可以對命令(命令就是程式或指令碼)的標準輸入、標準輸出和標準錯誤進行重定向,使其指向其他檔案。

(4)重定向的作用域(redirect's scope ):重定向的「作用域」這個概念是我自己提出的,它對理解重定向的作用效果非常重要!我們來看下面這幾個例子:

例1:重定向的「作用域」侷限於乙個命令

#!/bin/bash

echo "hello world"  > result.txt

解析:這個重定向的作用域是echo命令,命令結束重定向也就結束了。

例2:重定向的「作用域」侷限於乙個迴圈

#!/bin/bash

while read line

doecho "$line"

done < name.txt

解析:這個重定向的作用域是while迴圈,在迴圈執行期間,標準輸入都被重定向到了當前目錄的的name.txt檔案,即每次read都是從檔案中讀取一行,且read是順序讀取檔案的所有行。

while迴圈結束時,重定向就結束了。

#!/bin/bash

while read line < name.txt

doecho "$line"

done

解析:這個重定向的作用域是read命令,每次read都重新進行一次重定向。這造成了可怕的結果,每次都讀取檔案中的第一行,無限迴圈下去。

例3:重定向的「作用域」侷限於整個指令碼

#!/bin/bash

#this script called ltx_test

while read line

doecho "$line"

done

在終端執行這個指令碼,執行命令

ltx_test < name.txt

解析:這個重定向的作用域是整個指令碼,在指令碼執行期間,標準輸入都被重定向到了當前目錄的的name.txt檔案,即每次read都是從檔案中讀取一行,且read是順序讀取每一行。指令碼結束時,重定向就結束了。

二、下面開始討論shell指令碼中輸入/輸出的的兩種情況:

(1)指令碼只使用標準輸入、標準輸出和標準錯誤

shell會自動為我們開啟和關閉0、1、2這三個檔案描述符,我們不需要顯式地開啟或關閉它們。標準輸入是命令的輸入,預設指向鍵盤;標準輸出是命令的輸出,預設指向螢幕;標準錯誤是命令錯誤資訊的輸出,預設指向螢幕。

如果沒有顯式地進行重定向,命令通過檔案描述符0從螢幕讀取輸入,通過檔案描述符1和2將輸出和錯誤資訊輸出到螢幕。但如果我們想從其他檔案(再次強調,i/o裝置在unix/linux中也是檔案)讀取輸入或產生輸出,就需要對0、1、2使用重定向了。其語法如下:

command < filename                         把標準輸入重定向到filename檔案中

command 0< filename                       把標準輸入重定向到filename檔案中

command > filename                         把標準輸出重定向到filename檔案中(覆蓋)

command 1> fielname                       把標準輸出重定向到filename檔案中(覆蓋)

command >> filename                       把標準輸出重定向到filename檔案中(追加)

command 1>> filename                     把標準輸出重定向到filename檔案中(追加)

command 2> filename                       把標準錯誤重定向到filename檔案中(覆蓋)

command 2>> filename                     把標準輸出重定向到filename檔案中(追加)

command > filename 2>&1               把標準輸出和標準錯誤一起重定向到filename檔案中(覆蓋)

command >> filename 2>&1             把標準輸出和標準錯誤一起重定向到filename檔案中(追加)

command < filename >filename2        把標準輸入重定向到filename檔案中,把標準輸出重定向

到filename2檔案中

command 0< filename 1> filename2   把標準輸入重定向到filename檔案中,把標準輸出重定向

UNIX linux中的引號

unix中的引號分為三種 單引號,雙引號,反引號 單引號 用單引號括起來的字元作為普通字元,即使是特殊字元也不例外.雙引號 除了 和 這幾個字元仍是特殊字元保持其特殊效能以外,其他的字元全部作為普通字元.其中 是用其後指定的變數的值代替此變數和 是轉移字元,指出對其後的字元不做特殊處理.反引號 反引...

Unix Linux中Cron的用法

cron是unix或者linux下用來定時任務的命令,大致的用法如下 1 服務的啟動和關閉 sbin service crond start 啟動服務 sbin service crond stop 關閉服務 sbin service crond restart 重啟服務 sbin service ...

Unix Linux中的 dev fd機制

比較新的unix linux系統都提供名為 dev fd的目錄,其中有檔案0 1 2等檔案,開啟這些檔案,相當於複製這些檔案描述符 例如 fd open dev fd 0 mode 等價於fd dup 0 檔案描述符fd和0將共享乙個檔案表記錄項。我們再來做一些試驗 在debian下執行以下命令 c...