Linux雜記6

junwind發表於2021-03-05
shell
    變數一定是在某個程式的程式中使用的,變數一定是程式的變數,程式結束,變數失效
    看這個例子就知道
    [root@localhost ~]# name=xqw
    [root@localhost ~]# echo $name
    xqw
    [root@localhost ~]# bash
    [root@localhost ~]# echo $name
    父shell中宣告的變數,子shell中是沒有的

    引用變數 ${name}  花括號也可省略
    下面這種情況需要加{}
    [root@localhost ~]# animal=pig
    [root@localhost ~]# echo "there are some $animals."
    there are some .   //無法解析到$animals,沒有定義這個變數
    [root@localhost ~]# echo "there are some ${animal}s."
    there are some pigs.

    環境變數:
        作用域為當前shell程式,及其子程式,如果是重新開啟登入的shell,則作用域無效
        export var_name = val  宣告一個環境變數
        也可先定義一個變數,再把他宣告為環境變數
            NAME=lyl
            export NAME 
            bash
            echo $NAME

    本地變數:區域性變數
        set var_name = value    作用域為當前整個bash程式,set可省略
        local var_name = value    只對當前程式碼段(函式)有效
        位置變數: $1 , $2 , ...   引用指令碼的引數

        特殊變數(系統變數)
            $?   上一個程式(命令)的執行狀態返回值
                程式執行,一般有兩種返回
                1. 執行的結果
                2. 程式執行的狀態返回碼(0-2550  正確的被執行
                    1-255  錯誤的被執行
                            12127  系統預留
                            其它碼,使用者寫指令碼中可自定義使用


        指令碼在執行時,會啟動一個子shell程式,父程式的環境變數在子shell程式中是可以被使用的;
        注意:命令列中啟動的指令碼,是可以繼承父程式的環境變數,但是系統自動執行的指令碼,是需要再單獨定義需要的
        環境變數;


    pstree 程式樹

    輸出重定向:
        >
        >>
        2>
        2>>
        &>
        /dev/null    資料黑洞  軟體模擬的裝置

        id student &> /dev/null
        echo $?

    程式結束後,變數會自動銷燬,如果程式一直不結束,變數將一直佔用記憶體空間
    unset var_name    注意:不用加$  ,  加$是引用變數的值,不加$才是變數本身

    set  檢視當前shell中的環境變數和本地變數
    printenv , env , export   檢視當前shell中的環境變數

    [root@localhost ~]# animals=pig
    [root@localhost ~]# animals=$animals:goat
    [root@localhost ~]# echo $animals
    pig:goat
    [root@localhost ~]# animals=$animals:sheep
    [root@localhost ~]# echo $animals
    pig:goat:sheep

    同理,修改PATH值:
        export PATH=$PATH:/usr/local/apache/bin   注意,PATH是環境變數,需要export
        export PATH=/usr/local/mysql/bin:$PATH

    對於shell來說,預設所有變數的值都是string,所以是不能直接做算術運算的;如下
        [root@localhost ~]# A=2
        [root@localhost ~]# B=3
        [root@localhost ~]# C=$A+$B
        [root@localhost ~]# echo $C
        2+3

    [root@localhost ~]# file /bin/ls
        /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs),....

        ELF 64-bit LSB executable  可執行,可連結的二進位制檔案

    [root@localhost ~]# file /lib/ld-2.17.so 
        /lib/ld-2.17.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, ...

        ELF 32-bit LSB shared object  這是一個共享庫

shell指令碼:
    指令碼第一行  #!/bin/bash   指定直譯器 , 其它行以#開頭的是註釋
    first.sh
        #!/bin/bash
        cat /etc/fstab
        ls /var 

    chmod +x first.sh
    ./first.sh

    執行時,要加一個路徑,不然找不到,或者將路徑加入到PATH環境變數中
    不給執行許可權也是能執行的,需要加直譯器,如: bash first.sh

寫一個指令碼,完成以下任務:
1、新增5個使用者, user1,..., user5
    useradd user1
2、每個使用者的密碼同使用者名稱,而且要求,新增密碼完成後不顯示passwd命令的執行結果資訊;
    echo user1 | passwd --stdin user1 &> /dev/null
3、每個使用者新增完成後,都要顯示使用者某某已經成功新增;


條件判斷
    如果使用者不存在
        新增使用者
        給密碼
        提示新增成功
    否則
        提示使用者已存在,退出


bash中的條件判斷:
    條件測試型別: 整數, 字元, 檔案        

    條件測試表示式:
        [ expression ]
        [[ expression ]]
        test expression

    整數比較:比較兩個整數大小,雙目操作

    -eq  是否相等   
        [root@localhost ~]# a=3
        [root@localhost ~]# b=6
        [root@localhost ~]# [ $a -eq $b ]
        [root@localhost ~]# echo $?
        1
        [root@localhost ~]# b=3
        [root@localhost ~]# [ $a -eq $b ]
        [root@localhost ~]# echo $?
        0

    -ne  不等
    -gt  大於
    -lt  小於
    -ge  大於等於
    -le  小於等於

邏輯與  &&  
    短路現象:
        第一個條件為假時,後面的不用判斷了
        第一個條件為真,則後面的必須判斷

        [root@localhost ~]# id user3 &> /dev/null && echo 'user3 is exists.'   使用者存在,後面的還需要執行
        user3 is exists.

        [root@localhost ~]# id user1 &> /dev/null && echo 'user3 is exists.'   使用者不存在,後面的不執行
        [root@localhost ~]# 


邏輯或:||
    短路現象:第一個條件為真,則後面不用判斷


如果使用者不存在,就新增使用者?
    ! id user6 && useradd user6   前面為真,即不存在使用者,後面執行
    id user6 || useradd user6     前面為假,後面繼續執行


判斷一個檔案是否是大檔案?
    vim second.sh
        #!/bin/bash
        lines=`wc -l /etc/inittab`   引用一個命令得返回結果(注意不是狀態返回碼),需要變數
        #echo $lines

        finlines=`echo $lines | cut -d' ' -f1`
        #echo $finlines

        [ $finlines -gt 100 ] && echo '/etc/inittab is a big file.' || echo '/etc/inittab is a small file.'

        [ $finlines -gt 100 ] && echo '/etc/inittab is a big file.'整體為假,或後面得還得執行

        指令碼執行結束,變數被撤銷
        變數名:
            只能包含字母,數字,下劃線,並且不能以數字開頭,
            不應該跟系統中已有得環境變數重名

如果一個使用者存在,就顯示存在,否則就新增使用者?
    id user1 && echo 'user1 exists.' || useradd user1

如果使用者不存在,就新增,否則,顯示其已經存在?
! id user1 && useradd user1 || echo 'user1 exists.'

如果使用者不存在,就新增,並且給密碼,否則,顯示其已經存在?
!id user1 && useradd user1 && echo 'user1' | passwd --stdin user1 || echo 'user1 exists.'


練習:寫一個指令碼,完成以下要求:
1. 新增3個使用者user1,user2,user3;但要先判斷使用者是否存在,不存在而後再新增
2. 新增完成後,顯示一共新增了幾個使用者,當然,不能包括因為事先存在而沒有新增的
3. 最後顯示當前系統上共有多少個使用者
    [root@localhost tmp]# cat adduser2.sh 
    #!/bin/bash

    ! id user1 &> /dev/null && useradd user1 && echo 'user1' | passwd --stdin user1 &> /dev/null || echo 'user1 exists.'
    ! id user2 &> /dev/null && useradd user2 && echo 'user2' | passwd --stdin user2 &> /dev/null || echo 'user2 exists.'
    ! id user3 &> /dev/null && useradd user3 && echo 'user3' | passwd --stdin user3 &> /dev/null || echo 'user3 exists.'

    users=`wc -l /etc/passwd | cut -d: -f1`
    echo "$users users."


練習:寫一個指令碼,完成以下任務
給定一個使用者:
    1. 如果其UID0,就顯示此為管理員
    2. 否則,就顯示其為普通使用者

    #!/bin/bash

    name=user1
    userid=`id -u $name`

    [ $userid -eq 0 ] && echo 'admin' || echo 'common user.'

練習:寫一個指令碼,完成以下任務
1. 使用一個變數儲存一個使用者名稱;
2. 刪除此變數中的使用者,且一併刪除其家目錄;
3. 顯示“使用者刪除完成”類的資訊;
本作品採用《CC 協議》,轉載必須註明作者和本文連結
六月的風