Linux 輸入輸出(I/O)重定向

来源:http://www.cnblogs.com/divent/archive/2016/08/15/5773861.html
-Advertisement-
Play Games

輸入輸出重定向是在 linux shell 中經常使用的一個功能,本編博文簡單介紹了什麼是輸入輸出以及操作方法 ...



[TOC]


1、概念

在解釋什麼是重定向之前,先來說說什麼是文件描述符

Linux 文件描述符

文件描述符可以理解為 Linux 系統為文件分配的一個數字,範圍是 0-3 ,用戶也可以自定義文件描述符,但是自定文件描述符不在這裡的討論範圍

文件描述符(file descriptor)

名稱 類型 文件描述符 操作
標準輸入 standard input 0 <,<<
標準輸出 standard output 1 >,>>
標準錯誤輸出 standard error output 2 2>,2>>

文件描述符的存儲位置位於 /proc/self/fd ,文件描述符是通過一系列軟鏈接指向的預設輸出設備,這裡我們的預設設備就是模擬終端

模擬終端的文件可以使用命令 tty 來查看

[divent@bash]$ ls -al /proc/self/fd
total 0
lrwx------. 1 divent divent 64 Aug 15 14:09 0 -> /dev/pts/0
lrwx------. 1 divent divent 64 Aug 15 14:09 1 -> /dev/pts/0
lrwx------. 1 divent divent 64 Aug 15 14:09 2 -> /dev/pts/0

對於一條 Linux 的命令執行的過程如下

輸入輸出重定向流程圖

  1. 用戶開始從鍵盤(鍵盤在 Linux 上屬於文件)輸入數據,也就是系統從文件中讀取數據的時候
  2. shell 將接受到的數據(標準輸入)傳遞給相應的命令開始執行
  3. (yes)執行成功後,即可獲得標準正確輸出。(no)執行失敗後,獲得標準錯誤輸出
  4. 在預設情況下,標準正確輸出的結果與標準錯誤輸出的預設輸出都為當前用戶執行的終端

一個命令執行以前,會準備好所有的輸入輸出,預設分別綁定 stdin(0),stdout(1),stderr(2)。如果在準備命令的時候出現錯誤,那麼這個命令將不會執行


2、輸出重定向

格式

command [OPTION]{>,>>} [File]
option:
    1   standard output(default)
    2   standard error output
    &   all output

> 為覆蓋輸出,>>為追加輸出

示例

#假設當前文件夾有文件 test2 
[divent@bash]$ ls test test2
ls: cannot access test: No such file or directory
test2

這裡可以看到同時擁有的標準輸出與標準錯誤輸出都顯示在了屏幕上
現在我們要將輸出寫入到文件中

#假設已經有文件 test2 , test3
[divent@bash]$ ls test test2 > test3
ls: cannot access test: No such file or directory
[divent@bash]$ cat test3
test2

因為這裡的文件只預設接受了標準輸出,所以標準錯誤輸出就輸出到了終端上
我們也可以將標準錯誤輸出寫入到文件

#假設已經有文件 test2 , stderr
[divent@bash]$ ls test test2 2> stderr
test2
[divent@bash]$ cat stderr
ls: cannot access test: No such file or directory

這裡獲得的結果就和剛剛的結果正好相反
我們也可以將標準輸出與標準錯誤輸出都重定向到不同的文件

#假設已經有文件 test2 , stdout , stderr
[divent@bash]$ ls test test2 1> stdout 2>stderr
[divent@bash]$ cat stdout
test2
[divent@bash]$ cat stderr
ls: cannot access test: No such file or directory

這裡我們就將兩個不同的輸出輸出到了指定的文件中
我們也可以將兩個輸出同時輸出到同一個文件中

#假設已經有文件 test2 , test3
[divent@bash]$ ls test test2 &> test3
[divent@bash]$ cat test3
ls: cannot access test: No such file or directory
test2

這裡就使用 \& 將兩種輸出同時輸出到了同一個文件
我們也可以只接受某一種輸出,而將其他的輸出導向到其他地方

#假設已經有文件 test2 
[divent@bash]$ ls test test2 2>&-
test2
[divent@bash]$ ls test test2 2>/dev/null
test2
# &- 意義為關閉這個輸出,/dev/null 是 linux 的黑洞設備

註意

  • shell遇到 > 操作符,會判斷右邊文件是否存在,如果存在就先刪除,並且創建新文件。不存在直接創建。 無論左邊命令執行是否成功。右邊文件都會變為空。
  • >> 操作符,判斷右邊文件是否存在,如果不存在,先創建。以添加方式打開文件,會分配一個文件描述符[不特別指定,預設為1]然後,與左邊對應的輸出綁定。
  • 一條命令在執行前,先會檢查輸出是否正確,如果輸出設備錯誤,將不會進行命令執行

3、輸入重定向

格式

command {<} [File] {<<} [Word]

這裡的 <<< 意義不是類似於輸出重定向的操作符,< 是從文件中取出數據到指定的文件中

示例

[divent@bash]$ cat > newfile
123
abc
456
[divent@bash]$cat newfile
123
abc
456
#這裡使用 Ctrl + D 可以結束輸入,從鍵盤輸入的數據會保存存到 newfile 文件中

cat 命令直接使用的話可以直接接收鍵盤的輸入

現在來嘗試從文件中輸入

#這裡的示例我們使用剛纔創建的 test3 文件
[divent@bash]$ cat test3
ls: cannot access test: No such file or directory
test2
[divent@bash]$ cat > newfile < test3
[divent@bash]$ cat newfile 
ls: cannot access test: No such file or directory
test2

這裡的先將文件中的數據提取到了命令 cat 中 ,然後由 cat 寫入到 newfile


4、自定義輸入輸出設備

解釋

除了使用系統給你定義的文件描述符以外,用戶還可以自己自定義文件描述符,首先使用 ulimit -n 來查看文件描述符的上限,然後使用命令 exec 來為一個文件添加文件描述符

示例

#首先查看一下現在已經被占用的文件描述符
[divent@bash]$ ls /proc/self/fd
0   1   2   3

#這個時候我們可以使用 exec 命令來為一個文件賦予一個文件描述符
[divent@bash]$ touch /tmp/test && exec 5>/tmp/test

#然後我們再查看文件描述符 5
[divent@bash]$ ls -al /proc/self/fd/5
l-wx------. 1 divent divent 64 Aug 15 14:54 /proc/self/fd/5 -> /tmp/test

#現在我們使用自己自定義的文件描述符來重定向輸出
[divent@bash]$ ls -l /etc >&5

#然後我們再來查看文件中的數據, 因為文件中有數據,這裡就只取出前 5 行作為示例
[divent@bash]$ head -n 5 /tmp/test
total 1936
drwxr-xr-x.  3 root root     4096 Jun 10 22:12 abrt
-rw-r--r--.  1 root root       16 Jun  9 16:56 adjtime
-rw-r--r--.  1 root root     1518 Feb 22 22:11 aliases
drwxr-xr-x.  2 root root     4096 Jun 10 22:11 alsa

#我們也可以使用 exec 來將文件的預設輸出指向文件
[divent@bash]$ exec 1>&5
[divent@bash]$ ls -l /etc
#這個時候就會發現沒有輸出了,已經輸出內容已經到了 /tmp/test 中了

#如果想要恢復輸出,將預設輸出重新指向當前 /dev/pts/0 即可
[divent@bash]$ exec 1>/dev/pts/0

#關閉文件描述符
[divent@bash]$ exec 5>&-

#最後我們查看一下
[divent@bash]$ ls /proc/self/fd
0  1  2  3

最後說兩句

  • 如果不是很好理解的話,一定要貫徹 Linux 一切皆文件的理念,文件描述符最終也是指向的是文件
  • 使用自己自定義的描述符可以簡化一些備份之類的任務
  • 在 shell 腳本中,輸入輸出重定向是經常使用的

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 跟蹤標記:3604 功能: 輸出DBCC命令返回結果到查詢視窗(通常是SSMS視窗),類似print命令的顯示效果; 用途: 常用於獲取DBCC IND, DBCC PAGE命令的輸出結果,因為這2個命令預設不輸出任何結果。 舉例: 跟蹤標記:3605 功能: 輸出DBCC命令返回結果到SQL Se ...
  • 頁併發訪問的保護:閂鎖 在多線程併發情況下,需要防止讀線程讀到寫線程正在寫的資源,在編程中,通過使用互斥器(Mutexes), 信號量(Semaphore), 臨界區(Critical Section)和事件(Event Object)來保護資源,而這些機制在SQL Server中被統一表示為 閂鎖 ...
  • http://blog.csdn.net/cyuyan112233/article/details/50190927 http://beikeit.com/post-514.html ...
  • 在 PE文件頭的 IMAGE_OPTIONAL_HEADER 結構中的 DataDirectory(數據目錄表) 的第二個成員就是指向輸入表的。每個被鏈接進來的 DLL文件都分別對應一個 IMAGE_IMPORT_DESCRIPTOR (簡稱IID) 數組結構。 typedef struct _IM... ...
  • 一、線程標識 和每個進程都有一個進程ID一樣,每個線程也有一個線程ID,線程ID是以pthread_t數據類型來表示的,在Linux中,用無符號長整型表示pthread_t,Solaris 把phread_t數據類型表示為無符號整型,FreeBSD 和Mac OS X 用一個指向pthread結構的 ...
  • 安裝VirtualBox為了共用文件夾,折騰了一晚上!網上的很多資料都不是很全面,這裡就全面的總結一下,如果有其他的疑問,可以留言多多交流。 "VirtualBox下載地址,版本為5.1.2" 設置共用文件路徑 點擊虛擬機 設置 選擇 共用文件夾 (圖1 設置共用文件夾) 設置共用文件夾路徑 1 選 ...
  • Linux作為操作系統,Apache作為Web伺服器,MySQL作為資料庫,PHP作為伺服器端腳本解釋器。由於這四個軟體都是免費或開放式源碼軟體,因此使用這種不用花一分錢(人工成本除外)就可以建立起一個穩定、免費的網站系統,被業界稱為“LAMP”組合。今天,我們就講講MySQL資料庫的安裝和簡單應用 ...
  • CoreOS Hyper-V 安裝, Install to disck 準備 安裝鏡像 https://coreos.com/releases/ 選擇版本, 點 Browse Images, 下載以下文件 (本文以 Alpha 為例) coreos_production_iso_image.iso ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...