Bash / Шилдэг дадлага ба shellcheck

Шилдэг дадлага ба shellcheck

Script бичих чадвараа эзэмшсэн. Одоо сайн code бичих зарчмуудыг сурах цаг боллоо. Мэргэжлийн хөгжүүлэгчид зөвхөн ажилладаг script биш, уншихад хялбар, засахад аюулгүй script бичдэг. Энэ хичээлд тэдний ашигладаг арга барилыг судална.

Script-н эхэнд тохируулга хийх

Сайн script бүр эхний мөрөнд strict mode тохируулдаг:

bash
#!/bin/bash
set -euo pipefail

# -e  : алдаа гарвал шууд зогсоно
# -u  : тодорхойлогдоогүй хувьсагч ашиглавал алдаа гаргана
# -o pipefail : pipe дотор алдаа гарвал бүхэл pipeline амжилтгүй болно

Энэ гурван тохируулга таны script-г маш хамгаалалттай болгоно. Зөвхөн #!/bin/bash бичиж зогсох нь хангалтгүй — set -euo pipefail нэмэхээ мартуузай.

Жишээ нь set -u байхгүй үед:

bash
#!/bin/bash
echo "Таны нэр: $NAEM"   # Алдаатай бичсэн — хоосон утга хэвлэнэ, алдаа гаргахгүй

set -u нэмсэн үед:

bash
#!/bin/bash
set -euo pipefail
echo "Таны нэр: $NAEM"   # bash: NAEM: unbound variable — шууд зогсоно

Хувьсагчдыг зөв ашиглах

Хувьсагч ашиглахдаа үргэлж хашилтад оруулах хэрэгтэй. Энэ нь хоосон зай агуулсан утгуудад тулгарах асуудлыг шийдэнэ:

bash
#!/bin/bash
set -euo pipefail

# Муу хэв маяг
file=my document.txt
cat $file        # Алдаа: "my" ба "document.txt" хоёр тусдаа аргумент болно

# Сайн хэв маяг
file="my document.txt"
cat "$file"      # Зөв: нэг аргумент болно

Тогтмол утгуудыг UPPERCASE-р нэрлэх заншилтай:

bash
#!/bin/bash
set -euo pipefail

readonly MAX_RETRIES=3
readonly LOG_FILE="/var/log/myapp.log"
readonly BASE_DIR="$(dirname "$0")"

echo "Log файл: $LOG_FILE"

readonly нь хувьсагчийн утгыг санамсаргүй өөрчлөхөөс хамгаалдаг.

Функц зөв бичих

Функц бичихдэн local ашиглан дотоод хувьсагч тодорхойлох хэрэгтэй:

bash
#!/bin/bash
set -euo pipefail

greet_user() {
  local name="$1"
  local greeting="Сайн уу"
  echo "$greeting, $name!"
}

calculate_sum() {
  local a="$1"
  local b="$2"
  local result=$(( a + b ))
  echo "$result"
}

greet_user "Болд"
total=$(calculate_sum 15 27)
echo "Нийт: $total"

local ашиглахгүй бол функцийн дотоод хувьсагч бүх script-д харагдаж, санамсаргүй давхцал үүсч болно.

Алдаа зохицуулах

Алдааг тодорхой, ойлгомжтой дамжуулах хэрэгтэй. stderr рүү алдааны мэдэгдэл илгээнэ:

bash
#!/bin/bash
set -euo pipefail

log_error() {
  echo "[АЛДАА] $*" >&2
}

log_info() {
  echo "[МЭДЭЭЛЭЛ] $*"
}

backup_file() {
  local source="$1"
  local dest="$2"

  if [[ ! -f "$source" ]]; then
    log_error "Файл олдсонгүй: $source"
    return 1
  fi

  cp "$source" "$dest" || {
    log_error "Хуулах амжилтгүй: $source$dest"
    return 1
  }

  log_info "Амжилттай хуулагдлаа: $dest"
}

backup_file "config.txt" "config.backup.txt"

shellcheck ашиглах

shellcheck бол Bash script-н алдааг автоматаар илрүүлдэг хэрэгсэл юм. Мэргэжлийн хөгжүүлэгч бүр үүнийг ашигладаг.

Суулгах:

bash
# Ubuntu/Debian
sudo apt install shellcheck

# macOS
brew install shellcheck

Ашиглах:

bash
shellcheck myscript.sh

Жишээ гаралт:

код
In myscript.sh line 5:
  for f in $(ls *.txt); do
            ^---------^ SC2045: Iterating over ls output is fragile.
                                 Use globs instead: for f in *.txt

In myscript.sh line 8:
  if [ $count == 5 ]; then
       ^------^ SC2086: Double quote to prevent globbing and word splitting.

Shellcheck тус бүр дэлгэрэнгүй тайлбартай — SC дугаарыг shellcheck.net дээр хайж нэмэлт мэдээлэл авч болно.

Нэр томьёоны зарчим

Script, функц, хувьсагчдыг нэрлэхдэн тодорхой, илэрхий нэр өгөх хэрэгтэй:

bash
#!/bin/bash
set -euo pipefail

# Муу нэрлэлт
f() { cp "$1" "$2"; }
d="/home/user/stuff"

# Сайн нэрлэлт
backup_config_file() {
  local source_path="$1"
  local backup_path="$2"
  cp "$source_path" "$backup_path"
}

readonly CONFIG_BACKUP_DIR="/home/user/backups"

Нэр уншихад л функц юу хийдгийг ойлгогдох ёстой.

Дараагийн хичээлд:

Сүлжээний командуудыг судална — curl, wget, ssh ашиглан интернэтэс файл татаж, алсын серверт холбогдон ажиллана.