---
# System prepended metadata

title: W11 (2023/11/21)
tags: ['2023_1', Linux]

---

# W11 (2023/11/21)

## 腳本相關

* 變數操作
    1. 調用變數
    ```r=
    $ foo=123
    $ echo "${foo}"
    123
    ```
    2. 取得部分字串/字元
    ```r=
    $ a=123456789
    $ echo "${a:2:6}"
    345678    # 第一個數字的位置是0
    
    # cut操作 (第一個數字的位置是1)
    $ echo ${a} | cut -c 3-8
    345678
    ```
    3. 字串長度
    ```r=
    $ echo ${#a}
    9
    $ a="hello world"    # 空白也算
    $ echo ${#a}
    11
    ```
    4. 取代字串
    ```r=
    $ echo ${a}
    hello world
    $ echo ${a/world/$(whoami)}    # ${呼叫的變數/取代的字/替換的字}
    hello user
    ```
    * 依據變數存在與否
        1. ${變數:-輸出} 
        ```bash=
        # 如果變數不存在(為空), 輸出 " - " 後面的東西
        $ echo ${name}

        $ echo ${name:-empty}
        empty
        ```
        2. ${變數:+輸出} 
        ```bash=
        # 如果變數存在, 輸出後面的內容
        $ echo ${name:+hello ${name}}
        
        $ name="Lin"
        $ echo ${name:+hello ${name}}
        hello Lin
        ```
        3. ${變數:=輸出}
        ```bash=
        # 如果變數不存在(為空), 將變數等於輸出
        $ echo ${name}

        $ echo ${name:=chris}
        chris
        $ echo ${name}
        chris
        ```        
        
* 迴圈
    1. 遞增
    ```r=
    # 該空白的地方要空白，不然shellscript很多時候會報錯
    [user@centos-vm1 test]$ vim for.sh
    for i in {1..10}; do
      if (( i % 2 == 0 )); then
        continue
      fi
      if (( i == 7 )); then
        break
      fi
      echo "${i}"
    done
    
    [user@centos-vm1 test]$ chmod +x for.sh 
    [user@centos-vm1 test]$ ./for.sh 
    1
    3
    5
    ```
    2. 跳
    ```r=
    [user@centos-vm1 test]$ cat for2.sh 
    for i in {1..10..2}; do
      echo "${i}"
    done
    [user@centos-vm1 test]$ ./for2.sh 
    1
    3
    5
    7
    9
    ```
    3. 一行迴圈
    ```r=
    [user@centos-vm1 test]$ while true; do echo $(whoami); sleep 1; done;
    user
    user
    user
    user
    user
    user
    ^C
    ```

* 中括號/方括號
    1. 用法1
    [test相關筆記](https://reurl.cc/Do24Ne)

    2. 用法2 (array)
    ```r=
    [user@centos-vm1 test]$ array=("123" "456" "789")
    [user@centos-vm1 test]$ echo "$array"
    123
    [user@centos-vm1 test]$ echo "${array[0]}"
    123
    [user@centos-vm1 test]$ echo "${array[1]}"
    456
    [user@centos-vm1 test]$ echo "${array[2]}"
    789
    [user@centos-vm1 test]$ echo "${array[@]}"
    123 456 789
    
    # 取index
    [user@centos-vm1 test]$ echo "${!array[@]}"
    0 1 2
    # index數量
    [user@centos-vm1 test]$ echo "${#array[@]}"
    3
    ```

* 小括號(Parentheses)
    1. 命令替換
    ```r=
    # $() 和 ` ` 用途相同
    [user@centos-vm1 test]$ echo $(whoami)
    userv
    [user@centos-vm1 test]$ echo `whoami`
    user
    ```
    2. array
    ```r=
    # 宣告
    [user@centos-vm1 test]$ array=("123" "456" "789")
    [user@centos-vm1 test]$ echo $array    # 第0個
    123
    [user@centos-vm1 test]$ echo ${array[1]}    第1個
    456
    
    # Append
    $ a=(1 2)
    $ b=(3 4)
    $ a=("${a[@]}" "${b[@]}")    # array a,b結合
    $ echo ${a[@]}
    1 2 3 4

    # 複製
    $ a=('123 456' '789')
    $ b=("${a[@]}")
    $ echo ${b[@]}
    123 456 789
    
    # 走訪
    $ cat for3.sh 
    a=()
    echo ${a[@]}
    a+=('123')
    echo ${a[@]}
    a+=('456')
    echo ${a[@]}
    a+=('678' '987')
    echo ${a[@]}
    for i in ${!a[@]}; do
      echo "${i}: ${a[i]}"
    done
    
    $ ./for3.sh 

    123
    123 456
    123 456 678 987
    0: 123
    1: 456
    2: 678
    3: 987
    ```

* 雙小括號
    1. 算數的擴充套件
    ```r=
    # 基本運算
    $ echo $((1+1))
    2
    
    $ a=6
    $ b=7
    $ echo $((${a}*${b}))
    42

    # 轉進位制
    $ echo $((2#111))
    7
    $ echo $((2#1111))
    15
    
    # 比大小
    $ a=9
    $ b=11
    $ echo $(($a+3 >= $b))    # 9+3 >= 11
    1
    $ echo $(($a+3 <= $b))    # 9+3 <= 11
    0

    # 累加(如果寫成 a++ , 下一次呼叫才會看到加完的變數)
    $ a=10
    $ echo $((++a))
    11
    $ echo $((++a))
    12
    
    # 判斷式的寫法
    if (( $a + 2 > $b ))
    ```

* readonly、local變數
    * readonly
    ```bash=
    $ a=1
    $ readonly a    # 把 a 變成readonly的變數
    $ a=2
    bash: a: readonly variable
    $ echo ${a}
    1
    ```
    * local
    ```bash=
    $ function hi {
    >   a="Hello"
    >   local b="World"          
    >   echo "$a $b"
    > }
    [user@centos-vm1 ~]$ hi
    Hello World
    [user@centos-vm1 ~]$ echo ${a}
    Hello
    [user@centos-vm1 ~]$ echo ${b}
        # 因為b是local變數, 所以出了function就叫不到
    ```
    * 解除 readonly
    ```bash=
    $ unset -v a
    bash: unset: a: cannot unset: readonly variable
    $ gdb --batch-silent --pid=$$ --eval-command='call unbind_variable("a")'
    $ a=2
    $ echo ${a}
    2
    ```

參考: [Bash Script 語法解析](https://medium.com/vswe/bash-shell-script-cheat-sheet-15ce3cb1b2c7)


## 課本
* Linux網路運作
    Linux 網路的運作由兩個不同的server管理跟維護 (這兩個互斥，開A的話B就關)
    1. NetworkManager (個人型或移動的設備網路，自動化設定)
    2. network (伺服器使用，手動設定)

    **NetworkManager**
    ![image](https://hackmd.io/_uploads/rymL_RFV6.png)

    **network**
    ![image](https://hackmd.io/_uploads/SJAquAKEp.png)

* 網卡
![image](https://hackmd.io/_uploads/By0WFAF46.png)
**關閉網卡`[user@centos-vm1 ~]$ sudo ifconfig ens192 down`**
![image](https://hackmd.io/_uploads/HkiQKRKEa.png)
**開啟網卡`[user@centos-vm1 ~]$ sudo ifconfig ens192 up`**

    **清除網卡內容**
    ![photo_2023-11-21_15-25-45](https://hackmd.io/_uploads/S12qi0F4a.jpg)

    **變更Mac address**
    ![photo_2023-11-21_15-27-04](https://hackmd.io/_uploads/Byu7kJcV6.jpg)

    **IP、mask設定**
    ![photo_2023-11-21_15-40-33](https://hackmd.io/_uploads/Bkcfy1q46.jpg)

    **複製網路卡(虛擬)**
    ![photo_2023-11-21_15-45-48](https://hackmd.io/_uploads/ry7BeJc4p.jpg)

* ip (類似ifconfig)
`[user@centos-vm1 ~]$ ip address show`
`[user@centos-vm1 ~]$ ip addr show`
`[user@centos-vm1 ~]$ ip a s`
**功能一樣**
![image](https://hackmd.io/_uploads/HkTae1qNa.png)

    RX:傳送 TX:接受 (檢查效能)
    ![image](https://hackmd.io/_uploads/r133-1cV6.png)
    
    用ip指令新增介面卡
    ![photo_2023-11-21_15-54-44](https://hackmd.io/_uploads/ryR8zJ5E6.jpg)

    用ip指令刪除介面卡
    ![photo_2023-11-21_15-55-27](https://hackmd.io/_uploads/BkMKGkcNa.jpg)

    路由表
    ![image](https://hackmd.io/_uploads/H1b07kcNa.png)
    **增加內定路由**
    ![photo_2023-11-21_16-03-06](https://hackmd.io/_uploads/rkQPNJq4a.jpg)

## 把NetworkManager --> network

* 沒改過任何網卡的機器這樣就完成了
    1. 先關閉NetworkManager
    `$ sudo systemctl stop NetworkManager`
    2. 開機啟動 network
    `$ sudo chkconfig network on`
    3. 啟動 network
    `$ sudo systemctl start network`

* 檢查與關閉
    1. 檢查
        `$ sudo systemctl status network`
    2. 測試
    `ping 8.8.8.8 -c 3`
    3. 把 NetworkManager 的開機啟動關閉
    `sudo systemctl disable NetworkManager`


:::info
先檢查網路設定, 包括正常對外 (`ping 8.8.8.8`)
:::

* 解法1
    1. 檢查在 /etc/sysconfig/network-scripts/ 底下的東西
    2. 查看 NAT 那張的網卡名稱 ( ex: **ens33** **ens160** )
    `ip a s` `ifconfig`
    3. **ifcfg-** 開頭的留下兩張 ( ex: **ifcfg-lo** **ifcfg-ens33** ) 其餘ifcfg-開頭的刪掉
    `ifcfg-lo` `ifcfg-*NAT的網卡名`
    4. 回到前面的 **檢查與關閉**


* 解法2 (暴力, 不建議這樣做)
    1. 切換到 /etc/sysconfig/network-scripts/
    2. 查看 NAT 那張的網卡名稱 ( ex: **ens33** **ens160** )
    `ip a s` `ifconfig`
    3. 刪除所有 **ifcfg-** 開頭的
    4. 新增網路卡設定檔
    `sudo vim ifcfg-網卡名`
        ```r=
        TYPE=Ethernet
        DEVICE=ens160            # 改為自己 `ip a s` 的網卡名字
        ONBOOT=yes
        BOOTPROTO=static
        IPADDR=192.168.68.100    # `ip a s` 顯示的IP
        NETMASK=255.255.255.0
        GATEWAY=192.168.68.2     # `ip r s` 顯示的GW
        ```
    5. 回到前面的 **檢查與關閉**