1. 程式人生 > >shell中的輸入輸出重定向——shell程式設計學習_四

shell中的輸入輸出重定向——shell程式設計學習_四

shell中的輸入輸出

輸入輸出重定向

一般情況,我們的標準輸入是鍵盤,標準輸出是終端顯示器;但是在很多情況,我們需要從檔案中讀取資料作為輸入,然後將輸出資料儲存在檔案中。這是我們就需要將標準輸入從鍵盤重定向到檔案,將標準輸出重定向到檔案,這個過程就是輸入輸出重定向。

輸出重定向

輸出重定向有兩種方式

COMMAND > outputfile

COMMAND >> outputfile

其中>>>是輸出重定向的符號,前後必須有空格(這也是為什麼要將大於號轉義)。

>>>的區別

>示例:

[root@shell io_redirection]# pwd
/mnt/io_redirection [root@shell io_redirection]# echo fsx.com fsx.com [root@shell io_redirection]# echo fsx.com > test.txt [root@shell io_redirection]# cat test.txt fsx.com

如果使用>重定向資料到一個已經有內容的檔案,會完全覆蓋原來的內容

[root@shell io_redirection]# ls
test.txt
[root@shell io_redirection]# cat test.txt 
fsx.com
[root@shell io_redirection]# echo qq > test.txt [root@shell io_redirection]# cat test.txt qq

有時候我們不希望覆蓋源有資料,這時候就需要使用>>來完成操作,我們稱之為追加操作

[root@shell io_redirection]# ls
test.txt
[root@shell io_redirection]# cat test.txt 
qq
[root@shell io_redirection]# echo fsx.com >> test.txt 
[root@shell io_redirection]# cat test.txt 
qq fsx.com //注意,不是緊跟追加,而是另起一行

輸入重定向

輸入重定向使用COMMAND < outputfile來完成操作,將檔案內容輸出給命令。

[root@shell io_redirection]# cat < test.txt 
qq
fsx.com
[root@shell io_redirection]# cat < test.txt > test2.txt//同時輸入重定向,輸出重定向,將test.txt輸入重定向到cat,再輸出重定向到test2.txt中
[root@shell io_redirection]# ls
test2.txt  test.txt
[root@shell io_redirection]# cat test2.txt 
qq
fsx.com

內聯輸入重定向

使用格式:

COMMAND << marker //命令 << 標示符

data input //資料的輸入

marker //提示符,成對出現

具體示例:

[root@shell io_redirection]# result=`bc << eof
scale=3
var1=3.14
var2=2
var3=var1*var2
print var3
> eof`
[root@shell io_redirection]# echo $result
6.28

檔案描述符與錯誤重定向

檔案描述符

在Linux系統中,將每個物件當作檔案處理(Linux的核心思想,一切皆檔案),包括輸入輸出的過程。

Linux用檔案描述符來表識每一個檔案物件。

檔案描述符是一個非負整數,用來唯一標識會話中開啟的檔案。

每一個過程一次最多可以有 9 個檔案描述符

LInux中shell提供三個檔案描述符:

檔案描述符縮寫描述
0STDIN標準輸入
1STDOUT標準輸出
2STDERR標準錯誤

錯誤重定向

標準輸入輸出重定向:COMMAND 1> outputfileCOMMAND 0< outputfile

預設情況下,標準輸入輸出不需要指定檔案描述符。但是如果對錯誤資訊進行重定向是,就必須使用 2 來進行描述:COMMAND 2> outputfile

[root@shell io_redirection]# cat fsx//當我們試圖訪問一個不存在的檔案,系統會輸出標準錯誤到終端
cat: fsx: No such file or directory
[root@shell io_redirection]# cat fsx 2> test4.txt//我們使用標準錯誤描述符,將錯誤資訊重定向到一個檔案中,則錯誤資訊就被輸出到該檔案中
[root@shell io_redirection]# cat test4.txt 
cat: fsx: No such file or directory

這是我們進行錯誤捕獲和錯誤處理的重要方式。

特別是,當我們的輸出有正確輸出,也有錯誤輸出的時候,就可以使用檔案描述符,將其分看,方便進一步處理

[fsx@shell ~]$ find /etc/ -name passwd* 1>find_out.txt 2>find_err.txt //將標準輸出寫入find_out.txt檔案,將標準錯誤寫入find_err.txt檔案
[fsx@shell ~]$ cat find_out.txt 
/etc/pam.d/passwd
/etc/passwd-
/etc/passwd
[fsx@shell ~]$ cat find_err.txt 
find: `/etc/lvm/cache': Permission denied
find: `/etc/lvm/backup': Permission denied
find: `/etc/lvm/archive': Permission denied
find: `/etc/dhcp': Permission denied
find: `/etc/audisp': Permission denied
find: `/etc/selinux/targeted/modules/active': Permission denied
find: `/etc/audit': Permission denied
find: `/etc/pki/rsyslog': Permission denied
find: `/etc/pki/CA/private': Permission denied
find: `/etc/sudoers.d': Permission denied

在指令碼中重定向輸入輸出

輸出重定向

shell指令碼中輸出重定向分為兩種,一種是臨時重定向,一種是永久重定向

  • 臨時重定向:COMMAND >&檔案描述符

[root@shell io_redirection]# cat test.sh 
#!/bin/bash

echo "test error" >&2//定義了一個錯誤資訊,提供了我們自定義錯誤資訊的能力
echo "normal output"
//編寫一個指令碼檔案test.sh,具體內容如上
[root@shell io_redirection]# bash test.sh //如果執行bash,都會顯示,看起來沒什麼差別,這是因為標準錯誤也是通過標準輸出的形式體現。
test error
normal output
[root@shell io_redirection]# bash test.sh 2>>errlog//如果我們將標準錯誤重定向到errlog檔案中,則只顯示標準輸出
normal output
[root@shell io_redirection]# cat errlog //檢視檔案中重定向的標準錯誤
test error

  • 永久重定向:exec 檔案描述符>檔名

將一個檔案描述符值(1/2)定給一個檔案。

[root@shell io_redirection]# cat test2.sh 
#!/bin/bash

exec 1>testout.txt
echo "normal output 1"
echo "normal output 2"
[root@shell io_redirection]# bash test2.sh 
[root@shell io_redirection]# cat testout.txt 
normal output 1
normal output 2
//這就將輸出全部重定向到了檔案中

這也可以同時定義標準錯誤和標準輸出重定向

[root@shell io_redirection]# cat test3.sh 
#!/bin/bash

exec 1>testout.txt
exec 2>testerr.txt

echo "normal output 1" >&1
echo "normal output 2" >&1
echo "error output 1" >&2
echo "error output 2" >&2
[root@shell io_redirection]# bash test3.sh 
[root@shell io_redirection]# cat testerr.txt 
error output 1
error output 2
[root@shell io_redirection]# cat testout.txt 
normal output 1
normal output 2

指令碼中的輸入重定向

使用exec 0<檔名可以實現指令碼中的輸入重定向。

[root@shell io_redirection]# cat input.sh 
#!/bin/bash

exec 0< testerr.txt//使用exec實現輸入重定向,將testerr.txt作為輸入

count=1//定義一個變數count,用來遍歷testerr.txt
while read line//迴圈遍歷輸入的每一行
do
echo "line $count: $line"//輸出,"line 行號:每行內容"
count=$[count+1]//count自增,實現遍歷每行
done
[root@shell io_redirection]# bash input.sh //檢視輸出結果
line 1: error output 1
line 2: error output 2

管道

在shell中,將一個命令的輸出,重定向到另一個命名的輸入,就需要用到管道。資料通過管道在兩個命令中實現了傳遞。具體格式:

COMMAND1 | COMMAND2

ps -aux | less

就是將ps -aux的輸出,傳遞給less就可以實現分頁檢視

[root@shell io_redirection]# ps -axu | grep bash
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root      1018  0.0  0.3 108304  1944 pts/0    Ss   21:47   0:00 -bash
root      1033  0.0  0.3 108304  1896 pts/1    Ss+  21:47   0:00 -bash
root      1369  0.0  0.1 103244   832 pts/0    S+   23:30   0:00 grep bash
//將ps命令的輸出傳遞給grep命令,實現過濾出bash相關的程序資訊

如果我們使用

ps -aux > psfile

less < psfile

這樣也可以實現ps -aux | less的功能,但是這樣1,效率不高;2,核心開銷大

管道前後命令是同時進行的,不佔用檔案或者緩衝器,效能大大提高。

有沒有一個即可以輸出到終端,又實現重定向?即一個輸入,兩個輸出?

[root@shell io_redirection]# date |tee date.txt
Tue Apr 10 23:35:06 EDT 2018
[root@shell io_redirection]# cat date.txt 
Tue Apr 10 23:35:06 EDT 2018

這就是tee命令,tee命令的實現是管道和檔案輸入輸出重定向的同時利用