---
# System prepended metadata

title: '[shell] 讀取輸入參數'
tags: [shell script, linux, OS, $2, command, shift, $0, sh, parse_arguments, 輸入參數, $@, OS / Ubuntu / shell script, while-done, $#, bash, Ubuntu, case-esca, $1]

---

[shell] 讀取輸入參數
===
###### tags: `OS / Ubuntu / shell script`
###### tags: `OS`, `Ubuntu`, `linux`, `command`, `shell script`, `sh`, `bash`, `輸入參數`, `parse_arguments`, `$#`, `$@`, `$0`, `$1`, `$2`, `while-done`, `case-esca`, `shift`

<br>

[TOC]

<br>

## 印出輸入參數個數，並逐行印出輸入參數
```bash=
# run.sh
main() {
  echo '$#='$#
  echo '$@='$@
  echo '$0='$0
  echo '$1='$1
  echo '$2='$2
  
  echo '----------------'
  while [[ $# > 0 ]]; do
    echo $1
    shift
  done
}

main $@
```
- **執行結果**
    ```
    $ bash run-1.sh 1 2 3 -y   -h   --help
    
    $#=6                   <-- 6個參數
    $@=1 2 3 -y -h --help  <-- 輸入參數
    $0=run-1.sh            <-- 第0個參數：script 名稱
    $1=1                   <-- 第1個參數：1
    $2=2                   <-- 第2個參數：2
    ----------------
    1
    2
    3
    -y
    -h
    --help
    ```

<br>

---

## 專業範例
```bash=
AUTO_INSTALL=false
INTERACTIVE_INSTALL=false

COLOR_RESET='\033[0m'
COLOR_RED='\033[0;31m'

log_error() {
    # -e: enable interpretation of backslash escapes
    echo -e "${COLOR_RED}[ERROR]${COLOR_RESET} $1"
}

show_usage() {
    cat << EOF
Usage: $0 [OPTIONS]

Options:
  -y, --auto-install          自動安裝所有套件
  -i, --interactive           逐一詢問是否需要安裝某一套件
  -h, --help                  顯示此說明訊息

範例:
  $0 -y                       自動安裝所有套件
  $0 -i                       互動式安裝，逐一確認每個套件

EOF
    exit 0
}

parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -y|--auto-install)
                AUTO_INSTALL=true
                echo "set AUTO_INSTALL=true"
                shift
                ;;
            -i|--interactive)
                INTERACTIVE_INSTALL=true
                echo "set INTERACTIVE_INSTALL=true"
                shift
                ;;
            -h|--help)
                show_usage
                ;;
            *)
                log_error "未知的選項: $1"
                show_usage
                ;;
        esac
    done

    if [ "$AUTO_INSTALL" = true ] && [ "$INTERACTIVE_INSTALL" = true ]; then
        log_error "-y 和 -i 選項不能同時使用"
        exit 1
    fi
    
    echo "AUTO_INSTALL=$AUTO_INSTALL"
    echo "INTERACTIVE_INSTALL=$INTERACTIVE_INSTALL"
}

main() {
  parse_arguments "$@"
}

main "$@"
```
- **執行範例1：不帶任何參數**
    ![](https://hackmd.io/_uploads/SJTyloWkWl.png)
    ```bash
    $ bash run.sh   
    AUTO_INSTALL=false
    INTERACTIVE_INSTALL=false
    ```
- **執行範例2：參數衝突**
    ![](https://hackmd.io/_uploads/rJ4g1jbJ-l.png)
    ```bash
    $ bash run.sh -y -i       
    set AUTO_INSTALL=true
    set INTERACTIVE_INSTALL=true
    [ERROR] -y 和 -i 選項不能同時使用
    ```
- **執行範例3：顯示參數用法**
    ![](https://hackmd.io/_uploads/B1jsyj-1bg.png)
    ```bash
    $ bash run.sh -y -i --help
    set AUTO_INSTALL=true
    set INTERACTIVE_INSTALL=true
    Usage: run.sh [OPTIONS]

    Options:
      -y, --auto-install          自動安裝所有套件
      -i, --interactive           逐一詢問是否需要安裝某一套件
      -h, --help                  顯示此說明訊息

    範例:
      run.sh -y                       自動安裝所有套件
      run.sh -i                       互動式安裝，逐一確認每個套件

    ```
- **執行範例4：未知參數**
    ![](https://hackmd.io/_uploads/ByBheiW1-g.png)
    ```bash
    $ bash run.sh -a -b -c
    [ERROR] 未知的選項: -a
    Usage: run.sh [OPTIONS]

    Options:
      -y, --auto-install          自動安裝所有套件
      -i, --interactive           逐一詢問是否需要安裝某一套件
      -h, --help                  顯示此說明訊息

    範例:
      run.sh -y                       自動安裝所有套件
      run.sh -i                       互動式安裝，逐一確認每個套件

    ```

<br>

{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}
