Linux文件重定向的高級技巧與實(shí)踐
前言:
在Linux中,文件重定向(file redirection)是指將命令的輸入和輸出重定向到文件或其他設(shè)備,而不是默認(rèn)的標(biāo)準(zhǔn)輸入(stdin)和標(biāo)準(zhǔn)輸出(stdout)。它是通過不同的符號來實(shí)現(xiàn)的。
重定向
標(biāo)準(zhǔn)輸入重定向 (<)
標(biāo)準(zhǔn)輸入重定向使用 <
符號將文件的內(nèi)容傳遞給命令作為輸入。例如,假設(shè)你有一個包含文本的文件,你可以將該文件的內(nèi)容作為輸入傳遞給命令進(jìn)行處理。
示例:
- 將文件內(nèi)容作為命令的輸入:
wc < text.txt
這個命令會計(jì)算 log.txt
文件中的行數(shù)、字?jǐn)?shù)和字符數(shù)。
輸出重定向(> 和 >>)
標(biāo)準(zhǔn)輸出重定向 (>
) 是將命令的輸出從默認(rèn)的屏幕(標(biāo)準(zhǔn)輸出)轉(zhuǎn)向一個指定的文件。這個操作是通過 >
符號來實(shí)現(xiàn)的,它會將命令的標(biāo)準(zhǔn)輸出寫入到文件中。如果文件已經(jīng)存在,重定向操作會覆蓋原有的內(nèi)容;如果文件不存在,它會新建一個文件。
>
(輸出重定向):將命令的標(biāo)準(zhǔn)輸出重定向到文件,如果文件已存在,它會覆蓋文件內(nèi)容。
示例:
echo hello linux > log.txt
? 該命令會將 "hello linux
輸出到 log.txt
文件,如果文件已存在,文件內(nèi)容會被覆蓋。
>>
(追加輸出):將命令的標(biāo)準(zhǔn)輸出追加到文件的末尾,而不是覆蓋。
示例:
echo "HELLO LINUX" >> log.txt
該命令將 HELLO LINUX
追加到 log.txt
文件的末尾。
標(biāo)準(zhǔn)錯誤輸出重定向 (2>)
ls non_existent_file 2> error.log
- 打開
error.log
文件。 - 關(guān)閉標(biāo)準(zhǔn)錯誤輸出(文件描述符 2)。
- 使用
dup2()
將文件描述符指向error.log
。 - 將錯誤信息(例如“沒有該文件或目錄”)寫入
error.log
。
dup函數(shù)
在Linux中,dup
(duplicate)是一種系統(tǒng)調(diào)用,用于復(fù)制文件描述符。它允許一個進(jìn)程為已經(jīng)打開的文件描述符創(chuàng)建一個新的文件描述符,使得新舊描述符指向同一個文件或輸入輸出流。dup
通常用于文件重定向操作或管理多個文件描述符。
dup
:創(chuàng)建一個新的文件描述符,指向與原始文件描述符相同的文件或流。dup2
:類似于dup
,但允許指定新文件描述符。
dup 系統(tǒng)調(diào)用
函數(shù)原型:
int dup(int oldfd);
- 功能:創(chuàng)建一個新的文件描述符,它與
oldfd
指向相同的文件。新文件描述符是最小的未使用的文件描述符。 - 返回值:返回新的文件描述符,如果出錯則返回
-1
dup2 系統(tǒng)調(diào)用
函數(shù)原型:
int dup2(int oldfd, int newfd);
功能:將 oldfd
復(fù)制到 newfd
,如果 newfd
已經(jīng)打開,會先關(guān)閉它。與 dup
的區(qū)別在于,dup2
允許指定新文件描述符。
示例:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> int main() { // 使用 O_TRUNC 和 O_CREAT 創(chuàng)建或打開 log.txt 文件,如果文件存在則清空文件內(nèi)容 int fd = open("log.txt", O_TRUNC | O_CREAT | O_WRONLY, 0666); if(fd < 0) { // 如果打開文件失敗,輸出錯誤信息并返回 -1 perror("open"); return -1; } // 關(guān)閉標(biāo)準(zhǔn)輸出文件描述符 (stdout), 即文件描述符 1 close(1); // 將標(biāo)準(zhǔn)輸出文件描述符重定向到 fd 文件描述符 (指向 log.txt) dup2(fd, 1); // 要寫入文件的消息 const char* msg = "hello linux\n"; // 設(shè)置寫入消息的次數(shù) int cnt = 5; // 循環(huán)寫入消息 5 次 while(cnt--) { // 使用 write 函數(shù)將消息寫入標(biāo)準(zhǔn)輸出 (實(shí)際上是 log.txt 因?yàn)?stdout 已被重定向) write(1, msg, strlen(msg)); } return 0; // 程序成功結(jié)束 }
解釋:
- 打開文件:首先打開(或創(chuàng)建)一個名為
log.txt
的文件,并設(shè)置權(quán)限為0666
(允許所有用戶讀寫)。O_TRUNC
表示如果文件存在則清空文件內(nèi)容,O_CREAT
表示如果文件不存在則創(chuàng)建該文件,O_WRONLY
表示文件以寫模式打開。 - 關(guān)閉標(biāo)準(zhǔn)輸出:通過
close(1)
關(guān)閉標(biāo)準(zhǔn)輸出文件描述符(通常是終端輸出,文件描述符 1)。這意味著之后的標(biāo)準(zhǔn)輸出操作將不再輸出到終端,而是輸出到其他位置。 - 重定向標(biāo)準(zhǔn)輸出:
dup2(fd, 1)
將文件描述符 1(標(biāo)準(zhǔn)輸出)重定向到文件描述符fd
,即log.txt
文件。此時所有的標(biāo)準(zhǔn)輸出操作將會寫入到log.txt
。 - 寫入文件:程序使用
write(1, msg, strlen(msg))
來將消息 “hello linux” 寫入到標(biāo)準(zhǔn)輸出(實(shí)際上是log.txt
,因?yàn)橐呀?jīng)重定向了標(biāo)準(zhǔn)輸出)。這個操作會執(zhí)行 5 次,最終在log.txt
中寫入 5 次 “hello linux”。 - 關(guān)閉文件:程序在結(jié)束前沒有顯式關(guān)閉文件描述符
fd
,因?yàn)槌绦蚪Y(jié)束時文件會自動關(guān)閉。
重談輸入重定向(>)
echo "Hello, World!" > log.txt
- 打開文件:Shell 會用
open("output.txt", O_WRONLY | O_CREAT)
打開文件。 - 關(guān)閉標(biāo)準(zhǔn)輸出:Shell 會用
close(1)
關(guān)閉標(biāo)準(zhǔn)輸出文件描述符。 - 復(fù)制文件描述符:Shell 使用
dup2(fd, 1)
將標(biāo)準(zhǔn)輸出重定向到文件output.txt
。 - 執(zhí)行命令:命令
echo
會將輸出寫入文件,而不是終端。
stdout 和 stderr
在 Linux 系統(tǒng)中,stdout
和 stderr
都是進(jìn)程的標(biāo)準(zhǔn)輸出流,它們通過文件描述符進(jìn)行管理。它們的作用和使用方式有所不同,主要體現(xiàn)在它們各自用于處理正常輸出和錯誤輸出。
stdout
(標(biāo)準(zhǔn)輸出):用于輸出正常結(jié)果,默認(rèn)文件描述符為 1。stderr
(標(biāo)準(zhǔn)錯誤輸出):用于輸出錯誤信息,默認(rèn)文件描述符為 2。- 重定向:你可以使用
>
或>>
重定向標(biāo)準(zhǔn)輸出,而使用2>
或2>>
重定向標(biāo)準(zhǔn)錯誤輸出。你還可以通過&>
或2>&1
合并兩者的輸出。
示例:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> int main() { fprintf(stdout, "hello normal message\n"); fprintf(stdout, "hello normal message\n"); fprintf(stdout, "hello normal message\n"); fprintf(stdout, "hello normal message\n"); fprintf(stdout, "hello normal message\n"); fprintf(stderr, "hello error message\n"); fprintf(stderr, "hello error message\n"); fprintf(stderr, "hello error message\n"); fprintf(stderr, "hello error message\n"); fprintf(stderr, "hello error message\n"); return 0; }
待程序生成exe文件(file
),分別執(zhí)行:
./file > output.txt
./file > error.txt
./file > log.txt 2>&1
第一條命令 (./file > output.txt
)
- 這條命令將
file
程序的標(biāo)準(zhǔn)輸出(stdout)重定向到output.txt
文件。 file
程序生成的正常信息會被寫入到output.txt
中,且不會顯示在終端上。
第二條命令 (./file 2> error.txt
)
- 這條命令將
file
程序的標(biāo)準(zhǔn)錯誤輸出(stderr)重定向到error.txt
文件。 - 錯誤信息將寫入到
error.txt
中,而不會顯示在終端上。
第三條命令 (./file > log.txt 2>&1
)
- 這條命令將
file
程序的標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯誤輸出(stderr)都重定向到同一個文件log.txt
。 > log.txt
將標(biāo)準(zhǔn)輸出重定向到log.txt
,而2>&1
會將標(biāo)準(zhǔn)錯誤重定向到標(biāo)準(zhǔn)輸出的目標(biāo)(即log.txt
)。
重定向總結(jié)
步驟:
- 打開目標(biāo)文件:通過系統(tǒng)調(diào)用
open
打開目標(biāo)文件,獲取文件描述符。 - 關(guān)閉標(biāo)準(zhǔn)輸入輸出文件描述符:使用
close(0)
或close(1)
關(guān)閉標(biāo)準(zhǔn)輸入或標(biāo)準(zhǔn)輸出的文件描述符。 - 復(fù)制文件描述符:使用
dup2(fd, 1)
將標(biāo)準(zhǔn)輸入輸出或錯誤輸出的文件描述符重定向到目標(biāo)文件。
標(biāo)準(zhǔn)錯誤重定向到標(biāo)準(zhǔn)輸出的目標(biāo)(即log.txt
)。
以上就是Linux文件重定向的高級技巧與實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于Linux文件重定向的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
CentOS 7.x下的LEMP環(huán)境搭建詳細(xì)教程
我們常說的LNMP環(huán)境是指Linux/nginx/MySQL/PHP組合,LEMP包是由Linux、nginx、MariaDB/MySQL和PHP組成的,那么看來LEMP和LNMP是一樣的,而現(xiàn)在業(yè)內(nèi)習(xí)慣性的稱作LEMP。這篇文章主要介紹了CentOS 7.x下的LEMP環(huán)境搭建詳細(xì)教程,需要的朋友可以參考下2016-10-10詳解Linux 主機(jī)網(wǎng)絡(luò)接入配置
這篇文章主要介紹了詳解Linux 主機(jī)網(wǎng)絡(luò)接入配置的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)網(wǎng)絡(luò)接入配置的功能,需要的朋友可以參考下2017-10-10Centos7運(yùn)用/dev/shm進(jìn)行網(wǎng)站優(yōu)化
這篇文章主要介紹了LINUX中Centos7運(yùn)用/dev/shm進(jìn)行網(wǎng)站優(yōu)化相關(guān)知識點(diǎn),對此有興趣的朋友參考學(xué)習(xí)下。2018-03-03Linux環(huán)境下Apache服務(wù)器配置二級域名的方法詳解
這篇文章主要介紹了Linux環(huán)境下Apache服務(wù)器配置二級域名的方法,結(jié)合具體實(shí)例形式較為詳細(xì)的分析了Linux環(huán)境下Apache服務(wù)器配置二級域名的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-07-07解讀Linux下ip命令展示的網(wǎng)絡(luò)連接信息
這篇文章主要給大家介紹了關(guān)于Linux下解讀ip命令展示的網(wǎng)絡(luò)連接信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。2018-03-03Linux中openssl/opensslv.h找不到問題的解決方法
最近在安裝scrapy過程中碰到了openssl某個文件找不到的問題,通過查找相關(guān)的資料進(jìn)行了解決,下面這篇文章主要給大家分享了關(guān)于Linux中openssl/opensslv.h找不到問題的解決方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-07-07