SHELL腳本攻略(學習筆記)--1.8 管道和重定向基礎

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/08/09/7325378.html
-Advertisement-
Play Games

本文目錄: 1.8.1 匿名管道"|" 1.8.2 重定向 1.8.2.1 重定向基礎 1.8.2.2 cat和重定向配合 1.8.2.3 tee雙重定向 1.8.2.4 <<和<<< 1.8.1 匿名管道"|" 管道符號意如其名,類似管道一樣將管道入口的數據通過管道傳遞給管道出口。 管道是為瞭解決 ...



本文目錄:

1.8.1 匿名管道"|"

1.8.2 重定向

1.8.2.1 重定向基礎

1.8.2.2 cat和重定向配合

1.8.2.3 tee雙重定向

1.8.2.4 <<和<<<


1.8.1 匿名管道"|"

管道符號意如其名,類似管道一樣將管道入口的數據通過管道傳遞給管道出口。

管道是為瞭解決進程間通信問題而存在,它可以讓兩個進程之間的數據進行傳遞,將一個進程的輸出數據傳遞給另一個進程作為其輸入數據。管道左邊是數據給予方,管道右邊是數據接收方。

例如echo "abcd" | passwd --stdin username,表示將進程echo的輸出結果"abcd"作為進程passwd的輸入數據。

基本的管道符號及其用法很容易理解。現在的疑問是,對於ps aux | grep "ssh" ,為什麼在結果里會有grep進程出現?

[root@xuexi ~]# ps aux | grep ssh
root       1211  0.0  0.1  82544  3600 ?        Ss   Jul26   0:00 /usr/sbin/sshd -D
root      25236  0.0  0.2 145552  5524 ?        Ss   05:28   0:00 sshd: root@pts/0
root      25720  0.1  0.2 145416  5524 ?        Ss   06:15   0:00 sshd: root@pts/1
root      25770  0.0  0.0 112648   948 pts/1    S+   06:15   0:00 grep --color=auto ssh

按一般想法,先執行了ps,得到輸出後將輸出數據傳遞給grep,這時候grep還沒運行而ps已經運行完畢了,為什麼還能統計到grep進程的信息呢?原因是管道實現的是進程間通信,兩個進程之間存在交叉,在運行ps進程後開始收集進程信息,grep也已經開始並處於等待接收數據狀態,當ps收集到任何數據後都將輸出放入記憶體由管道傳遞給grep進行篩選。

管道其本質是數據傳遞,管道左邊的輸出數據放入記憶體,由管道右邊的進程讀取。假如記憶體不足以完全存放輸出數據,則管道左邊的進程將一直等待,直到管道右邊取出記憶體中一部分的數據以讓管道左邊的進程繼續輸出,而管道右邊的進程在管道左邊的進程啟動後也立刻啟動了,但是它一直處於等待狀態,等待接收管道傳遞來的數據。

也就是說,管道左右兩邊的進程運行幾乎是沒有先後順序的。

那麼ps aux | grep "ssh"如何避免結果中出現grep自身的進程呢?方法有二:

方法一:ps aux | grep "ssh" | grep -v "grep"

方法二:ps aux | grep "ss[h]"

[root@xuexi ~]# ps aux | grep ss[h]
root       1211  0.0  0.1  82544  3600 ?        Ss   Jul26   0:00 /usr/sbin/sshd -D
root      25236  0.0  0.2 145552  5524 ?        Ss   05:28   0:00 sshd: root@pts/0
root      25720  0.0  0.2 145416  5524 ?        Ss   06:15   0:00 sshd: root@pts/1

方法一是應用grep的"-v"特性,方法二是應用正則表達式的特性。

在使用匿名管道的過程中,可能已經發現管道兩邊的進程是同屬一個進程組的,也就是說管道左方的數據只能傳遞給管道右方的進程,其他任何進程都沒法讀取此數據。但除了匿名管道,還有命名管道,命名管道是將一個進程的數據存儲到一個管道文件(fifo)中,其他進程可以讀取該管道文件來讀取其中的數據,也就是說不再限制數據讀取方。關於命名管道,請參閱Linux/unix操作系統內核或編程類的書籍,一般都會有詳細的介紹。

1.8.2 重定向

1.8.2.1 重定向基礎

最常見的標準輸入(stdin)、標準輸出(stdout)和標準錯誤輸出(stderr)的文件描述符分別是0、1和2,其中0、1、2也可以認為是它們的數字代號。對於輸出信息,可以認為是列印在屏幕上的信息,而沒給出錯誤的就是標準輸出,給出錯誤提示的是標準錯誤輸出,當然這樣說明有失偏頗,但是易於理解。還可以自定義自己的描述符,實現高級重定向,在以後的文章中可能會介紹一下它們的用法。

標準輸入 = /dev/stdin   = 代號0 = <或<<符號。

標準輸出 = /dev/stdout = 代號1 = >或>>符號。

標準錯誤輸出 = /dev/stderr = 代號2 = 使用2>或2>>符號。

<、>、2>實現的是覆蓋功能,>>、2>>實現的是追加的功能,但是<<不是追加功能,而是表示此處生成文檔(here document),在後面cat和重定向配合的內容里有說明。此外,還有<<<,它表示此處字元串(here string),也見下文。

有時候,使用"-"也表示/dev/stdin。如:

[root@xuexi ~]# cat /etc/fstab | cat -

腳本中常見2>&1和&>的符號,它們都表示將stdout和stderr都重定向到同一個地方去,即重定向所有輸出內容。如最常見的"&> /dev/null"。

將stdout或stderr丟到/dev/null表示丟棄輸出信息,反過來,將/dev/null重定向到某個文件則表示清空文件。

[root@xuexi ~]# cat /dev/null > ab.sh

除此,還有以下幾種方法快速清空文件

[root@xuexi ~]# > ab.sh
[root@xuexi ~]# : > ab.sh             # 或"true >ab.sh",其實它們都等價於">ab.sh"
[root@xuexi ~]# echo '' > ab.sh
[root@xuexi ~]# truncate -s 0 ab.sh   # truncate命令用於收縮和擴展文件大小
[root@xuexi ~]# dd if=/dev/null of=ab.sh

最後最重要的一點:在有重定向符號的語句中,命令執行之前已經將文件截斷了。所以如果正在編輯一個文件並將編輯的結果重定向回這個文件將出現異常,因為截斷後就沒有合適的內容用於編輯。一個簡單的示例如下:

[root@xuexi ~]# head a.log > a.log

有些時候直接使用">"覆蓋輸出是比較危險的。可以使用set -C來設置如果輸出重定向文件已經存在則不覆蓋。使用set +C來取消set -C的效果。如果在設置了set -C時仍然想強制覆蓋,可以使用“>|”代替“>”來重定向輸出。同理錯誤輸出也有此特性。

[root@xuexi tmp]# set -C

[root@xuexi tmp]# cat flip >ttt.txt
-bash: ttt.txt: cannot overwrite existing file

[root@xuexi tmp]# cat flip >| ttt.txt

[root@xuexi tmp]# set +C

1.8.2.2 cat和重定向配合

配合cat使用可以分行輸入內容到文件中。

[root@xuexi tmp]# cat <<eof>log.txt   # 覆蓋的方式輸入到log.txt
> this is stdin character
> eof

也可以使用下麵的方法。

[root@xuexi tmp]# cat >log1.txt <<eof 
> this is stdin character first!
> eof

一方面,eof部分都必須使用"<<eof",它表示here document,此後輸入的內容都作為一個document輸入給cat。既然是document,那就肯定有document結束符標記document到此結束,結束符使用的是here document後的字元,例如此處為eof。其實不使用eof,使用其他字元也是一樣的,但document的結束符也必須要隨之改變。如:

[root@xuexi ~]# cat <<abcx
> 123
> 345
> abcx
123
345

另一方面,>log1.txt表示將document的內容覆蓋到log1.txt文件中,如果是要追加,則使用>>log1.txt。所以,追加的方式如下:

[root@xuexi tmp]# cat >>log1.txt <<eof 
> this is stdin character first!
> eof

[root@xuexi tmp]# cat <<eof>>log1.txt 
> this is stdin character first!
> eof

1.8.2.3 tee雙重定向

可以使用tee雙重定向。一般情況下,重定向要麼將信息輸入到文件中,要麼輸出到屏幕上,但是既想輸出到屏幕又想輸出到文件就比較麻煩。使用tee的雙重定向功能可以實現該想法。如圖。

tee [-a] file

選項說明:

    -a:預設是將輸出覆蓋到文件中,使用該選項將變為追加行為。

    file:除了輸出到標準輸出中,還將輸出到file中。如果file為"-",則表示再輸入一次到標準輸出中。

例如下麵的代碼,將a開頭的文件內容全部保存到b.log,同時把副本交給後面的的cat,使用這個cat又將內容保存到了x.log。其中"-"代表前面的stdin。

[root@xuexi tmp]# cat a* | tee b.log | cat - >x.log

還可以直接輸出到屏幕:

[root@xuexi tmp]# cat a* | tee b.log | cat

tee預設會使用覆蓋的方式保存到文件,可以使用-a選項來追加到文件。如:

[root@xuexi tmp]# cat a* | tee -a b.log | cat

現在就可以在使用cat和重定向創建文件或寫入內容到文件的同時又可以在屏幕上顯示一份。

[root@xuexi tmp]# cat <<eof | tee ttt.txt
> x y
> z 1
> eof

x y
z 1

1.8.2.4 <<和<<<

在bash中,<<和<<<是特殊重定向符號。<<表示的是here document,<<<表示的是here string。

here document在上文已經解釋過了,對於here string,表示將<<<後的字元串作為輸入數據。

例如:

passwd --stdin user <<< password_value

等價於:

echo password_value | passwd --stdin user

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7325378.html

註:若您覺得這篇文章還不錯請點擊下右下角的推薦,有了您的支持才能激發作者更大的寫作熱情,非常感謝!


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

-Advertisement-
Play Games
更多相關文章
  • 內置判斷,成功的時候返回0,不成功返回非零 test 判斷表達式 [ 判斷表達式 ] 註意前後必須留空格哦 數值運算 -eq 等於 -ne 不等於 -gt 大於 -ge 大於等於 -lt 小於 -le 小於等於 字元串運算 = 等於 != 不等於 -z 是否為空 -n 是否不為空 文件運算 -r 是 ...
  • Linux中Swap(即:交換分區),類似於Windows的虛擬記憶體,就是當記憶體不足的時候,把一部分硬碟空間虛擬成記憶體使用,從而解決記憶體容量不足的情況。swap分區在非高記憶體的伺服器上必不可少,但是swap不能充當記憶體使用。 一、swap分區擴展的方法 新建swap分區:以分區的形式創建swap 新 ...
  • IP地址:4段十進位,共32位二進位,如:192.168.1.1 二進位就是:11000000|10101000|00000001|00000001 子網掩碼可以看出有多少位是網路號,有多少位是主機號: 255.255.255.0 二進位是:11111111 11111111 11111111 00 ...
  • 一.系統管理與維護 1. pwd:print working directory 列印工作目錄 2. cd: change directory 改變或進入路徑 ● cd ~/ cd : 當前用戶目錄;回到主目錄(中間有空格!) ● cd /:根目錄; ● cd - :上一次訪問的目錄; ● cd .... ...
  • 原文發表於cu:2016-05-05 參考文檔: 一.環境 Server:CentOS-7-x86_64-1511 Client:Win7 x86_64, Chrome/Firefox瀏覽器 二.準備 1. iptables CentOS7預設自帶firewall,無iptables。 2. SEL ...
  • 如果你的伺服器的總是報告記憶體不足,並且時常因為記憶體不足而引發服務被強制kill的話,在不增加物理記憶體的情況下,啟用swap交換區作為虛擬記憶體是一個不錯的選擇,如果是SSD硬碟,正常讀寫速度都在300MB/s以上,啟用swap後性能提高了不少,特別是在處理消耗大記憶體的腳本方面。 ...
  • 0x00. Command Notation[Name] The name of the command.[Format] The code sequence. [ ]k indicates the contents of the [ ] s... ...
  • 聲明:本文為轉載的文章;並非由本人創作;發博文只是為了整理、記錄。 推薦的比較完全,比較清晰的文章(含圖):http://blog.csdn.net/sunny04/article/details/40627311 轉載時請註明出處和作者聯繫方式:http://blog.csdn.net/absur ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...