歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> Shell變量、數據重定向和管道

Shell變量、數據重定向和管道

日期:2017/2/28 13:48:53   编辑:SHELL編程

在上一篇博客Shell功能、配置和插件中,介紹了為什麼要使用shell,shell有哪些功能,如何使用oh my zsh來提高效率等,本篇重點介紹,shell中的變量的如何設置和讀取數據,讀取之後如何使用變量?每個程序一般都有輸入和輸出,讓我們看看數據重定向如何處理輸入和輸出的?還有,Unix/Linux系統提供豐富的工具,我們如何將這些工具通過管道來組合成更加強大的宏工具呢?下面,由我來逐一詳細介紹變量、數據重定向和管道。


Variable & Redirection & Pipe.png

變量

變量的作用

變量與其他程序設計語言一樣,都是存儲數據,然後被程序引用。相比於不使用變量,而是直接使用數據,存在兩個問題:

  1. 當數據改變時,直接使用數據的時候卻不能靈活地根據數據改變而隨著改變,而使用變量卻不同,它能夠做到這點。
  2. 當數據發生變化時,如果想保證數據一致性,必須查找所有引用該數據的所有地方,然後將它修改,當下一次再需要修改時,也是像這種情況一樣,是多麼繁瑣的事,而變量卻不用,只需要修改變量值即可。

因此,變量具有可變性易於修改的兩個特點。

變量的分類

在shell中,大概分為兩種變量:環境變量局部變量,主要區別在於它們的使用范圍不同,環境變量可以在父進程與子進程之間共享,而自定義變量只在本進程使用。舉一個簡單的例子來說明:


no share variable.png

我首先設置一個shell變量devname=sam,然後輸入bash打開一個新的shell,而這個shell是子進程,然後echo $devname輸出變量值,變量值為空,最後exit退出子進程。


share variable.png

但使用export devname設置環境變量後,再次進入輸入bash進入子進程之後,echo $devname輸出變量值,這次變量值是sam

查看環境變量envset

如果想查看系統中以及自定義有哪些環境變量,可以使用env命令:


env command.png

set命令不僅能查看環境變量,還可以查看與shell接口有關的變量,下面只截取一部分變量:


set command.png

變量有哪些操作

顯示echo $variable

如果你想顯示某個變量的值,例如PATH,你只需要輸入:

echo $PATH

echo command.png

注意上面一條命令,需要在變量名前加上一個符號$,這樣才能訪問變量

設置variable=value和取消unset

如果你想設置某個變量的值,只需在變量名和變量值之間用符號=連接就行了,例如:


set variable.png

由上面的輸入命令echo $devname,顯示結果為。由此可知,一開始如果沒有設置某個變量時,它的是為。另外,設置變量的規則還需要幾點注意:

  1. 在命名變量名時,變量名稱只能是英文字母和數字,而且首字母不能是數字。下面演示一個錯誤的例子:


    wrong variable name.png
  2. 等號=兩邊不能有空格


    blank can't exist.png
  3. 如果變量值有空格,可用雙引號" "或單引號' '來包圍變量值,但兩者是有區別:
    雙引號" "內的一些特殊字符,可以保持原有的特性,例如:


    double quotation marks.png

    而單引號' '內的一些特殊字符,僅為一般字符,即純文本,例如:


    single quotation marks.png
  4. 如果想顯示一些特殊字符($、空格、!等),在字符前面加上用轉義字符\

  5. 有些時候,變量的值可能來源於一些命令,這時你可以使用反單引號`命令`$(命令),例如:
    使用反單引號`命令`的方式


    get information from comand 1.png

    使用$(命令)的方式


    get information from comand 2.png
  6. 如果變量想增加變量的值,可以使用$variable累加


    append variable value.png
  7. 如果變量需要在其他子進程使用,用export關鍵字來設置變量為環境變量

    export VARIABLE
  8. 系統環境變量一般都是字母全部大寫,例如:PATHHOMESHELL

  9. 如果想取消設置變量的值,使用unset variable命令。注意,變量之前是沒有符號$


    unset variable.png

環境配置文件

之前那些設置的環境變量,一旦退出系統後,就不能再次使用,如果想再次使用,必須重新再設置才行。如果想就算退出系統,也能重新使用自定義的環境變量,那怎麼辦呢?

不用怕,系統提供一些環境配置文件:/etc/profile~/.bash_profile/etc/profile是系統整體的設置,每個用戶共享,最好不要修改;而~/.bash_profile屬於單個用戶的設置,每個用戶設置後,互不影響和共享。但因為我使用oh my zsh,之前~/.bash_profile設置一些配置都不生效了,但它提供一個環境配置文件.zshrc,所以如果想設置環境變量TEST,只需將export TEST=test添加.zshrc即可。


export variable in zshrc file.png

但在.zshrc文件設置好環境變量TEST後,echo $TEST為空,原因是還沒使用source命令來讀取環境配置文件。使用source .zshrc命令之後,設置環境變量TEST生效了


source command.png

數據重定向

含義

當輸入命令行時,一般都有輸入參數(standard input),而命令行處理完之後,一般都有輸出結果,結果有可能成功(standard output),也有可能失敗(standard error),而這些結果一般都會輸出到屏幕上,如果你想控制結果輸出到文件或以文件作為輸入的話,你需要了解數據重定向的分類和符號操作。


Redirection.png

分類

數據重定向主要分為三類:

  • stdin,表示標准輸入,代碼為0,使用<<<操作符
    符號<表示以文件內容作為輸入
    符號<<表示輸入時的結束符號
  • stdout,表示標准輸出,代碼為1,使用>>>操作符
    符號>表示以覆蓋的方式將正確的數據輸出到指定文件中
    符號>>表示以追加的方式將正確的數據輸出到指定文件中
  • stderr,表示標准錯誤輸出,代碼為2,使用2>2>>操作符
    符號2>表示以覆蓋的方式將錯誤的數據輸出到指定文件中
    符號2>>表示以追加的方式將錯誤的數據輸出到指定文件中

使用

stdout

當你輸入ls命令,屏幕會顯示當前目錄有哪些文件和目錄;而當你使用符號>時,輸出結果將重定向到dir.txt文件,而不顯示在屏幕上


stdin demo.png

而符號>與符號>>有什麼區別呢?>表示當文件存在時,將文件內容清空,然後stdout結果存放到文件中。而>>表示當文件存在時,文件內容並沒有清空,而是將stdout結果追加到文件尾部。

當你再次輸入命令ls > dir.txt時,文件內容並沒有改變,因為之前文件內容被清空,然後stdout結果存放在dir.txt文件


stdin demo 1.png

而你這次使用符號ls >> dir.txt的話,文件內容被追加到dir.txt文件


stdin demo 2.png
stderr

這次我輸入命令ls test顯示一個不存在的文件,會顯示錯誤信息。然後將錯誤信息輸出到文件error.txt


stderr demo 1.png

如果你想追加錯誤信息,可以使用2>>符號


stderr demo 2.png
stdout & stderr
  • 將stdout和stderr分離:>2>符號
    輸入ls README.md test,在屏幕顯示既有正確信息,也有錯誤信息,如果想將正確信息和錯誤信息分離到不同文件,你可以同時使用>2>符號


    seperate stdout & stderr.png
  • 將stdout和stderr合並:&>符號
    如果你想將正確信息和錯誤信息合並,且輸出到同一個文件,可以使用&>符號


    combine stdout & stderr.png
stdin

一般輸入一些簡單的數據的方式都是通過鍵盤,但是如果要輸入大量的數據,最好還是通過文件的方式。舉一個簡單例子:
首先輸入cat > test命令之後,你就可以輸入內容,那些內容最終會存放在test文件


stdin demo 1.png

但如果有大量數據從一個文件導入到test文件時,此時需要用到<符號


stdin demo 2.png

還一個符號<<需要解釋,符號<<表示輸入時的結束符號。輸入cat > test << "eof"命令之後,你就可以輸入內容,那些內容最終會存放在test文件,輸入完內容後可以輸入eof來結束輸入


stdin demo 3.png

管道

在Unix設計哲學中,有一個重要設計原則--KISS(Keep it Simple, Stupid),大概意思就是只關注如何做好一件事,並把它做到極致。每個程序都有各自的功能,那麼有沒有一樣東西將不同功能的程序互相連通,自由組合成更為強大的宏工具呢?此時,管道出現了,它能夠讓程序實現了高內聚,低耦合


How Pipe works.png

如果我想查看文件是否存在某個關鍵字,此時我可以使用管道


Pipe Demo.png

命令cat README.md | grep 'pod'的處理過程分為兩步:

  1. cat README.md查看文件內容
  2. 然後將cat README.md輸出的內容作為grep 'pod'命令的輸入,再進行處理。

上面一個很關鍵的符號|,就是管道,它能夠將前一個命令處理完的stdout作為下一條命令stdin

Copyright © Linux教程網 All Rights Reserved