ShellScript_概念

  • 概念

    shell是外殼,用戶連接计算機用的外殼;shell也是一種程序;包括:

    GUI:Gnome, KDE, Xfce 圖形

    CLI:sh, csh, ksh, bash, tcsh, zsh 命令行

    shell在什麼時候被啓動?用戶登陸時要給用戶提供一個輸入命令的地方,這時就打開了一個shell。如果同時登陸兩個用戶,用的shell是一個嗎?因shell是一種程序,所以程序只能有一個,但進程是程序的副本,誰用的時候就拿來復制一個,可以有多個,哪怕是同一個用戶登陸三次也會打開三個進程。三個進程間彼此各不相幹,這是linux的特性;在每個進程看來,當前主機上只存在內核和當前進程,運行的只是自己,它不知道別的進程的存在。因爲系統識別進程是靠進程號識別的,所以進程號不同,就是不同的程序;進程是程序的副本,進程也是程序執行的實例(就是程序運行起來才是進程);進程是有生命周期的,從啓動那一刻到終止那一刻結束,這個過程由內核來管理。bash是一個外部命令,但啓動後它還有很多內置命令

  • bash特性:

    1. 命令歷史,上下箭頭可查看之前的命令、命令補全

    2. 支持管道、重定向

    3. 支持命令別名

    4. 支持命令行編輯

    5. 支持命令行展開

    6. 支持文件名通配

    7. 支持使用變量

    8. 支持編程

    注:可以讀一下bash的幫助文檔,man bash

  • 環境變量:定義用戶的工作環境

    PATH:命令搜索路徑

    HISTSIZE:命令歷史緩沖區大小,默認是1000條;

    例:echo $HISTSIZE(用echo $變量名 可以查看變量名)

  • SHELL的類型

    登錄式shell(站在用戶登錄的角度)

    1. 正常通過某終端登錄

    2. su – username或su –l username

    非登錄式shell

    1. su username

    2. 圖形終端下打開命令窗口

    3. 自動執行的shell腳本

  • bash的配置文件

    • 全局配置;全局生效

    ​ /etc/profile /etc/profile.d/*.sh /etc/bashrc

    • 個人配置;當前用戶生效

    ​ ~/.bash_profile ~/.bashrc

    • profile類的文件

      • 設定環境變量,比如將環境變量放在/etc/profile或/etc/profile.d目錄下(全局和個人都配置了,以個人為準,作用範圍越小的最終先生效)

      • 運行命令或腳本(登陸前的準備工作可以在此類文件中定義)

    • bashrc類的文件

      • 設定本地變量

      • 定義命令別名

    • 登陸式shell如何讀取配置文件

    ​ 讀取過程

    ​ /etc/profile → /etc/profile.d/*.sh →~/.bash_profile → ~/.bashrc → /etc/bashrc

    • 非登陸式shell如何讀取配置文件

    ​ ~/.bashrc → /etc/bashrc → /etc/profile.d/*.sh (因為不讀取/etc/profile和/.bash_profile所以使用兩種方式su過去的用戶是不同的,所以su – 是完成切換,不加-是半切換)

    例:用hive用戶登陸,並alias cls=clear會設置別名,但登出後會失效,但可在~/.bashrc定義別名的地方,在其中加入一行如:alias cls=’clear’即可在當前用戶下次登陸時生效,或使用. ~/.bashrc命令当时生效

    ~/.bash_profile定義登陸時的提醒信息,在其中加入一行如:echo “Hello,hive.Welcome to our system. It is date”;加入 umask 027 可使umask一直是027,默認是002是在/etc/profile中定義好的

  • 輸入輸出重定向與管道

    • bash:是腳本解釋器

    • 默認輸出設備:也叫標準輸出或STDOUT,文件描述符是1;只輸出正常的數據;如果沒指定輸入輸出設備就從默認的設備裏進行;

    • 默認輸入設備:也叫標準輸入或STDIN,文件描述符是0

    • 標准錯誤輸出:STDERR,描述符2

    • 標準輸入:鍵盤

    • 標准輸出和錯誤輸出:默認都輸出到顯示器

    • I/O重定向:改變輸入輸出來源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    \>:輸出重定向,覆蓋輸出
    \>>:追加輸出
    set -C:禁止對已經存在文件使用覆蓋重定向;強制覆蓋輸出,則使用>|
    set +C:關閉上述功能
    2>:重定向錯誤輸出
    2>>:追加方式
    例:ls /varr > /tmp/var.out 2> /tmp/err.out
    &>:重定向標準輸出或錯誤輸出至同一個文件
    <:輸入重定向 例:tr ‘a-z’ ‘A-Z’ < /etc/fstab
    <<:在此處生成文檔(Here Document )
    例:cat << END 之後可以一直輸入文字,直到輸入END為止,END可以自己定義;cat >> /tmp/myfile.txt << EOF,系統會等待用戶輸入數據直到輸入EOF為止,這種方式可以腳本中生成文件的
    • 管道:前一個命令的輸出,作為後一個命令的輸入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    语法:
    命令1 | 命令2 | 命令3 | …

    例:
    echo “redhat” | passwd --stdin hive
    cut -d: -f1 /etc/passwd | sort | tr ‘a-z’ ‘A-Z’
    echo “hello” | tee /tmp/hello.out
    # tee命令是從標准輸入數據讀取並保存一份文檔並輸出到顯示器,這裏顯示器上的結果是tee輸出的不是echo輸出的
    wc –l /etc/passwd | cut –d' ' -f1
    # 其中-d選項要指定分隔符為空格
  • 編譯器或解釋器是一種軟件,它是一個翻譯官,轉換人與機器所用的語言。shell就是這樣的翻譯官

  • 編程語言:機器語言(01代碼)、匯編語言(人和機器都可以理解)、高級語言(接近人的語言)

  • 高級語言分爲靜態與動態語言

    靜態語言屬於編譯型語言,有自己的程序開發環境,不需要借助額外的二進制程序就可以直接寫代碼,寫完後需要一個編譯器將其直接轉換成二進制代碼後可以獨立運行的就是靜態語言。它們是強類型(變量)語言,我們在使用編程的時候,無論哪種語言都提供一些控制語句或關鍵字,這些關鍵字最後能夠被我們的解釋器或編譯器轉換成能夠被機器識別的機器代碼或機器指令。編譯語言需要在程序編譯之前或轉換之前事先完成的,只有轉換完成以後,我們才能運行這個程序

    態語言屬於解釋型語言是弱類型的語言。不需要事先完成轉換以後才運行這個程序,代碼寫完後不需要轉換成二進制格式,而是有解釋器解釋一條執行一條,也就是程序在執行的時候才需要轉換。執行特性是on the fly;動態語言的解釋器是靜態語言開發的

  • 面向過程:把編程着眼點放在問題解決過程本身。適合開發小型程序。linux內核是用C開發的;shell, C

面向對象:把整個要實現的項目抽象成一個個的對象並且定義對象之間的動作。更適合開發大型程序;Java, python, perl, c++

  • 變量是內存空間,定義變量是命名內存的過程,空間用完後可回收

    內存:編址的存儲單元

    進程:數據、指令在內存,臨時存儲在內存;在進程中有一個字符串,人看它的是變量名,機器看是內存地址,機器通過此地址到內存中提取變量,變量被提取後內存空間會被回收

  • 變量類型:決定變量的存儲格式;事先定義好數據的存儲格式和長度,保存不下會溢出

  • 強類型編程語言:變量在使用前,必須事先聲明,甚至還需要初始化,就是給一個值;默認數值型是0,字符串型是空

    弱類型編程語言:變量用時聲明,甚至不區分類型;默認是字符串類型

  • bash變量類型:

    環境變量:作用域為當前shell進程及其子進程

    本地變量(局部變量):作用域為整個bash進程,啓動後可從shell中聲明變量,與bash進程相關,bash進程結束時變量也就都沒了。變量是進程的變量。局部變量的作用域為當前代碼段

    位置變量:$1, $2, …

    特殊變量:bash內置,保存特殊數據的

  • 程序執行,可能有兩類返回值:

    程序執行結果就是顯示的結果

    程序狀態返回代碼(0-255)

    ​ 0:正確執行;1-255:錯誤執行,1,2,127系統預留;

  • 對shell來講默認所有變量值都是字符串所以默認不能作算術運算

  • 腳本是命令的堆砌,按實際需要,結合命令流程控制機制實現的源程序

  • shebang:魔數,須以#!開頭之後寫出可執行文件的所在位置,#號注釋行,不執行;命令沒給路徑會到PATH環境變量中查找,要執行命令可以將當前路徑加入PATH環境變量中或用./指明當前路徑,也可以是其他路徑;腳本沒有執行權限時可用bash SCRIPTNAME來執行,這是明確告訴程序用bash解釋器來執行腳本。

  • 腳本在執行時會啟動一個子shell進程:

    命令行中啟動的腳本會繼承當前shell環境變量

    系統自動執行的腳本(非命令行啟動)就需要自我定義需要的各環境變量

  • shell是能夠實現接收用戶指令理解用戶接令的命令,並將它傳輸給內核,由內核指揮某個應用程序啓動的一個界面。Shell會提供一個用戶能夠和它交互的界面,其次將用戶的指揮行翻譯爲內核能夠理解的命令。

  • 函數:函數就是功能(function),必須被調用才能執行。函數的主要作用是代碼重用

作者

John Doe

发布于

2018-12-02

更新于

2023-03-17

许可协议