---
# System prepended metadata

title: Shell 操作 (1)
tags: [Linux, Shell]

---

# Shell 簡介
- Interface to communicate with kernel
- Where you type commands
- [交大 Shell PDF](https://nasa.cs.nycu.edu.tw/sa/2020/slides/03_Shell.pdf)

## 相互協助、牽絆
- **硬體(Hardware)：**
  整個系統的實體工作者，沒有電力系統、CPU、硬碟等，就什麼都不用動了。
- **核心(kernel)：**
  是內部的核心，聽完Shell的翻譯，再指示硬體要進行的工作
- **Shell：**
  是外部的表殼，接收使用者的訊息，再翻譯給Kernel請他處理
- **使用者：**
  將需求或想做的事輸入給Shell
  > 是最不穩定的要因之一，每次執行程式有錯，都說不是他的錯，但幾乎都是他的錯

![](https://hackmd.io/_uploads/HkYY_n1gT.png =500x)

# Interactive shell, Login shell, 環境變數讀取流程

## Interactive shell vs. non-Interactive shell

### Interactive shell (互動式)
\# 互動式 shell 被定義為僅接受使用者在 tty 上輸入的命令並向使用者確認輸出的 shell。
- 互動式腳本是需要使用者輸入的腳本，互動式腳本無法在背景運行，因為它們需要使用者輸入。
- 存在一個叫 `PS1` 的環境變量。
  ![](https://hackmd.io/_uploads/BJjMo31eT.png =400x)

### non-Interactive shell
\# 非互動式 shell 是一種不與使用者互動的 shell，我們可以透過腳本或類似的方式運行它。
- 它可以通過一些自動化過程運行。
- 在這種情況下，`.bashrc` 和 `.profile` 檔案不會被執行。

:::success
*Ex:* **Init** 和 **啟動** 等腳本被認為是非互動式的，因為它們必須**在沒有人工干預的情況下運行**。
:::

## Login shell vs. non-Login shell
:::warning
Bash shell 可以是登入 shell 或非登入 shell。兩種類型的 shell 都透過不同的環境設定來呼叫。
:::

### Login shell
\# 當使用者透過終端機、SSH成功登入Linux系統，或使用「su -」指令切換到使用者時，就會建立一個Login shell。
- 當登入 shell 啟動時，它會執行一組預先配置的腳本來設定環境。
1. 登入 shell 調用`/etc/profile`
2. `/etc/profile`呼叫 `/etc/profile.d/*.sh` 中的腳本
3. 然後執行用戶`~/.bash_profile`
4. `~/.bash_profile`呼叫用戶`~/.bashrc`
5. `~/.bashrc`呼叫`/etc/bashrc`

### non-Login shell
\# 非登入 shell 由登入 shell 啟動，例如，從另一個 shell 或程式啟動的 shell 是非登入 shell。
- 不用於登入系統的shell執行以下腳本來設定shell環境
1. 非登入 shell 首先執行`~/.bashrc`
2. 然後`~/.bashrc`執行`/etc/bashrc`
3. `/etc/bashrc`呼叫腳本`/etc/profile.d`

## [不同類型的 shell](https://www.baeldung.com/linux/interactive-non-interactive-login-non-login-shells)

### Interactive shell & Login shell
- 互動式 shell 接收來自使用者的命令並向使用者顯示輸出。
- 使用者在登入其帳戶時會獲得一個登入 shell。
:::success
當我們使用ssh或 telnet等程式時，我們會得到一個互動式登入 shell 
:::
```shell!
## Interactive login shell
$ bash -l
$ echo $-; shopt login_shell
himBHs
login_shell     on
```

### Interactive shell & non-Login shell
:::success
當我們在 Linux 機器上開啟終端機時，我們會得到一個互動式非登入 shell
:::
```shell!
## Interactive, non-login shell. Regular terminal
$ echo $-; shopt login_shell
himBHs
login_shell     off
```

### non-Interactive shell & Login shell
- 這種情況極為罕見，您不太可能遇到它。
- 啟動方法之一是`echo command | ssh server.` 當`ssh`沒有命令啟動時（因此`ssh`不是在遠端 shell 上`ssh command`運行），它會啟動一個登入 shell。`command`如果`stdin`不是`ssh`tty，它將啟動一個非互動式 shell。這就是為什麼`echo command | ssh server`會啟動非互動式登入 shell。
:::success
如果我們將 tty 以外的其他內容（例如命令）作為標準輸入提供給ssh，我們會收到一個非互動式登入 shell。
:::
```shell!
## Non-interactive login shell
$ echo 'echo $-; shopt login_shell' | ssh localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
hBs
login_shell     on
```

### non-Interactive shell & non-Login shell
:::success
當我們在機器上執行腳本時，我們會得到一個非互動式非登入 shell，這是因為它們在非互動式的新 shell 中運作。
:::
```shell!
## Non-interactive, non-login shell
$ bash -c 'echo $-; shopt login_shell'
hBc
login_shell     off
```

## Shell Environment Variables
- Controlling shell behaviors
- There are many environment variables that control the shell behavior

| 環境變數  | 用途                                  |
| --------- | ------------------------------------- |
| $HOME     | 當前登入使用者的主目錄                |
| $PATH     | 系統會去哪些目錄中尋找可執行的程式    |
| $PS1      | 設定 Linux 的 Bash Shell 命令提示字串 |
| $HOSTNAME | 伺服器的主機名                        |
| $USER     | 當前登入使用者的使用者名稱            |
| $PWD      | 當前工作目錄                          |
| $SHELL    | 使用者當前使用的Shell解析器           |
| $LANG     | Linux系統的語言、地區、字元集         |

> [$PS1 設定](https://blog.gtwang.org/linux/how-to-make-a-fancy-and-useful-bash-prompt-in-linux-1/)

### 檢視環境變數

```shell!
echo $環境變數名
```

### 設定環境變數

```shell!
export 變數名='值'
```
- [環境變數設定](https://www.readfog.com/a/1633131905297780736)

## 環境變數讀取流程

環境變數檔案的執行順序如下：
`/etc/profile` -> `/etc/profile.d` -> `/etc/bashrc` -> `使用者的.bash_profile` -> `使用者的.bashrc`

<br>

> [time=Tue, Sep 26, 2023 11:43 AM]