Text size
പരീക്ഷിച്ചറിഞ്ഞത്6 മിനിറ്റ് വായന

നിങ്ങളെ അത്ഭുതപ്പെടുത്താത്ത ബാഷ് സ്ക്രിപ്റ്റുകൾ

ഷെൽ സ്ക്രിപ്റ്റുകൾ സുരക്ഷിതമാക്കുന്ന ശീലങ്ങൾ, പൈത്തണിലേക്ക് മാറേണ്ട സമയവും.

Bash scripts that don't surprise you
AI ഉപയോഗിച്ച് സൃഷ്ടിച്ച ചിത്രീകരണം

ബാഷിനെ എല്ലായിടത്തും കാണാം. ഐ. ഐ. പൈപ്പ്ലൈനുകൾ, ഡോക്കർ ഫയലുകൾ, വിന്യാസ സ്ക്രിപ്റ്റുകൾ, ക്രോൺ ജോലികൾ, വേഗത്തിലുള്ള ഓട്ടോമേഷനുകൾ. അത് അടിസ്ഥാന സൌകര്യങ്ങളെ ഒന്നിച്ചു നിർത്തുന്ന പശയാണ്.

ബാഷിന് ഒളിഞ്ഞിരിക്കുന്ന അപകടങ്ങളുണ്ട്. സ്ഥിരസ്ഥിതിയായി, ഇത് പിശകുകൾക്ക് ശേഷം പ്രവർത്തിക്കുന്നു, നിർവചിക്കാത്ത വേരിയബിളുകളെ ശൂന്യമായി കണക്കാക്കുന്നു, വാക്കുകളെ അപ്രതീക്ഷിതമായി വിഭജിക്കുന്നു. നിങ്ങളുടെ ലാപ്ടോപ്പിൽ നന്നായി പ്രവർത്തിക്കുന്ന ഒരു സ്ക്രിപ്റ്റ് തെറ്റായ ഫോൾഡർ നിർമ്മാണത്തിൽ അബദ്ധത്തിൽ ഇല്ലാതാക്കാം, ഒരു വേരിയബിൾ ശൂന്യമാണെങ്കിൽ.

എന്റെ തിരക്കഥകളെ ഏറ്റവും നല്ല രീതിയിൽ ബോറടിപ്പിക്കുന്ന ചില ശീലങ്ങളുണ്ട്.

ഓരോ സ്ക്രിപ്റ്റിന്റെയും ആദ്യ വരികൾ

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

അവര് ചെയ്യുന്നതെന്താണ്:

  • set -e: ഒരു കമാന് ഡ് പരാജയപ്പെടുമ്പോൾ സ്ക്രിപ്റ്റ് നിർത്തുക, തുടര് ന്നു് പോകുന്നതിന് പകരം.
  • set -u: ഒരു ശൂന്യമായ സ്ട്രിംഗിന് പകരം, നിർവചിക്കാത്ത വേരിയബിളുകളെ ഒരു പിശകായി കണക്കാക്കുക.
  • set -o pipefail: ഒരു പൈപ്പ്ലൈനില് ഏതെങ്കിലും കമാന് ഡുകള് പരാജയപ്പെട്ടാല് , അവസാനത്തെ കമാന് ഡിന് മാത്രമല്ല.
  • IFS=$'\n\t': പുതിയ വരികളിലും ടാബുകളിലും മാത്രം വേർതിരിക്കപ്പെട്ട വാക്കുകൾ, സ്പെയ്സുകൾ അല്ല. സ്പെയ്സുകൾ അടങ്ങിയ ഫയൽനാമങ്ങളില് കുറവ് ആശ്ചര്യങ്ങള് .

എന്തിന് ? set -u ഒരു ഉദാഹരണം കാണുക.

rm -rf "$BUILD_DIR/"*

എങ്കിൽ BUILD_DIR അബദ്ധത്തിൽ സജ്ജമാക്കിയിട്ടില്ലെങ്കിൽ, set -u ഇത് മാറുന്നു rm -rf /*. കൂടെ set -u, ഒരു പിശകോടെ സ്ക്രിപ്റ്റ് അവസാനിക്കുന്നു. ആ ഒറ്റ വരി പല സംവിധാനങ്ങളെയും രക്ഷിച്ചു.

(set -e ചില അറിയപ്പെടുന്ന എഡ്ജ് കേസുകൾ ഉണ്ട്, പോലുള്ള കമാൻഡുകൾ അവസ്ഥ അല്ലെങ്കിൽ സബ്ഷെല്ലുകൾ. ഇത് തികഞ്ഞതല്ല, പക്ഷേ സ്ഥിര സ്വഭാവത്തേക്കാൾ വലിയ മെച്ചപ്പെടുത്തലാണ്.

ബാഷിന് തോന്നുന്നു നിങ്ങള് ക്ക് അറിയാമെന്ന്. നല്ല തിരക്കഥകൾ ആരുമായും, അവരുടെ രചയിതാവിനെയും കുറിച്ച് അങ്ങനെ കരുതുന്നില്ല.

ഷെൽ ചെക്ക് ചെയ്യുക

ഷെൽ ചെക്ക് ചെയ്യുക ഷെൽ സ്ക്രിപ്റ്റുകൾക്കുള്ള ഒരു ലിംറ്റർ ആണ്, മികച്ച ബാഷ് എഴുതുന്നതിനുള്ള ഏറ്റവും ഉപയോഗപ്രദമായ ഒരു ഉപകരണം. അത് ഉദ്ധരിക്കാത്ത വേരിയബിളുകൾ, തെറ്റായ താരതമ്യങ്ങൾ, പ്രയോജനമില്ലാത്തവയെല്ലാം പിടിക്കുന്നു. catഓരോ മുന്നറിയിപ്പിനും വിശദീകരണങ്ങളോടെയുള്ള നിരവധി സൂക്ഷ്മമായ ബഗുകളും.

shellcheck deploy.sh

അത് നിങ്ങളുടെ എഡിറ്ററിലേക്കും ഐ. സി. ലേക്കും ചേർക്കുക. ഷെല് ചെക്ക് മുന്നറിയിപ്പുകളെ ഞാന് കമ്പൈലറിലെ പിശകുകളായി കണക്കാക്കുന്നു.

മിക്ക ബഗുകളെയും തടയുന്ന ശീലങ്ങൾ

നിങ്ങളുടെ വേരിയബിളുകൾ ഉദ്ധരിക്കൂ. എപ്പോഴും. "$file"അല്ല $file. ഉദ്ധരിക്കാത്ത വേരിയബിളുകൾ സ്പെയ്സുകളായി വിഭജിക്കപ്പെടുകയും വൈഡ്കാർഡുകളായി വികസിപ്പിക്കുകയും ചെയ്യുന്നു.

ഉപയോഗം [[ ]] പരിശോധനകൾക്കായി ബാഷില് , അല്ല [ ]. ഇത് കൂടുതൽ സുരക്ഷിതവും കൂടുതൽ സവിശേഷതകളും പിന്തുണയ്ക്കുന്നു.

if [[ -z "${ENVIRONMENT:-}" ]]; then
  echo "ENVIRONMENT must be set" >&2
  exit 1
fi

സ്ഥിരസ്ഥിതികളും ആവശ്യമായ പരിശോധനകളും നൽകുക പരാമീറ്റര് വിപുലീകരണത്തോടെ:

REGION="${REGION:-eu-central-1}"       # default value
: "${API_TOKEN:?API_TOKEN is required}" # fail with a message if unset

ഉപയോഗം local ഫംഗ്ഷനുകളില് അങ്ങനെ വേരിയബിളുകൾ ചോരാതിരിക്കില്ല.

stderr ലേക്ക് പിശകുകൾ എഴുതുക (>&2) കൂടാതെ പരാജയപ്പെട്ടാൽ പൂജ്യം അല്ലാത്ത കോഡുകളോടെ പുറത്തുകടക്കുക.

വൃത്തിയാക്കുക trap, സ്ക്രിപ്റ്റ് പരാജയപ്പെട്ടാലും:

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

ഉപയോഗം $(...) പിന്നിലേക്കുള്ള കുത്തിവയ്പ്പ് കമാന് ഡു മാറ്റി വയ്ക്കുന്നതിനായി.

വിശകലനം ഒഴിവാക്കുക ls. ഗ്ലോബ്സ് ഉപയോഗിക്കുക find പകരം.

ഞാൻ വീണ്ടും ഉപയോഗിക്കുന്ന ഒരു ടെംപ്ലേറ്റ്

#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat <<EOF
Usage: $(basename "$0") -e <environment> [-d]
  -e  target environment (staging|production)
  -d  dry run
EOF
}

log() { printf '%s [%s] %s\n' "$(date -u +%FT%TZ)" "${1}" "${2}" >&2; }

main() {
  local env="" dry_run=false

  while getopts ":e:dh" opt; do
    case "$opt" in
      e) env="$OPTARG" ;;
      d) dry_run=true ;;
      h) usage; exit 0 ;;
      *) usage; exit 1 ;;
    esac
  done

  [[ "$env" =~ ^(staging|production)$ ]] || { usage; exit 1; }

  log INFO "Deploying to $env (dry run: $dry_run)"
  if [[ "$dry_run" == false ]]; then
    : # real work here
  fi
}

main "$@"

ഇതിന് വാദപ്രതിവാദം വിശകലനം, സാധൂകരണം, സമയമുദ്ര ഉപയോഗിച്ച് ലോഗ് ചെയ്യൽ, ഡ്രൈ റൺ മോഡ്, ഒരു main ഫംഗ്ഷൻ ശരി, വേണ്ടാത്തത് മായ്ക്കുക.

ബാഷ് തെറ്റായ ഉപകരണമാണെങ്കിൽ

ബാഷ് കമാൻഡുകൾ ഒന്നിച്ച് ചേർക്കുന്നതിന് നല്ലതാണ്. മറ്റെല്ലാ കാര്യങ്ങളിലും അത് മോശമാണ്. ഒരു സ്ക്രിപ്റ്റ് ഉപയോഗിക്കുമ്പോൾ ഞാൻ പൈത്തണിലേക്ക് മാറുന്നു.

  • ഏകദേശം 100 വരികളാണ്.
  • യഥാര് ത്ഥ ഡാറ്റാ ഘടനകൾ (ചേര് ന്ന ഡാറ്റ, പട്ടികകളുടെ മാപ്പുകൾ) ആവശ്യമാണ്.
  • ലളിതമായ JSON അല്ലെങ്കിൽ YAML പാഴ്സ് ചെയ്യുന്നു jq വിളിക്ക്.
  • ആധികാരികത, പേജിനേഷൻ, വീണ്ടും ശ്രമങ്ങൾ എന്നിവ ഉപയോഗിച്ച് API-കളുമായി സംസാരിക്കുന്നു.
  • "പരാജയത്തെ തടയുക" എന്നതിനേക്കാൾ കൂടുതൽ സൂക്ഷ്മമായ പിശക് കൈകാര്യം ചെയ്യൽ ആവശ്യമാണ്.
  • പരിശോധനകൾ വേണം.
  • അത് വളരെക്കാലം പലര് ക്കും ഉപയോഗിക്കാന് സാധിക്കും.

ശരിയായ CLI ലൈബ്രറിയോ ചെറിയ Go ടൂളോ ഉള്ള പൈത്തൺ വായിക്കാനും പരിശോധിക്കാനും പരിപാലിക്കാനും വളരെ എളുപ്പമാണ്.

സിഐ പൈപ്പ്ലൈനുകളില്

CI YAML ൽ പലപ്പോഴും മൾട്ടി-ലൈൻ ഷെൽ സ്ക്രിപ്റ്റുകൾ അടങ്ങിയിരിക്കുന്നു. ഒരേ നിയമങ്ങൾ തന്നെയാണ് ബാധകമാകുന്നത്:

  • പല ഐ. സി. സിസ്റ്റങ്ങളും അനുവദിക്കുന്നില്ല set -euo pipefail സ്ഥിരമായി. അത് കൂട്ടിച്ചേര് ക്കുക, അല്ലെങ്കിൽ മുഴുവൻ ജോലിക്കും ഷെൽ ഓപ്ഷനുകൾ സജ്ജമാക്കുക.
  • YAML ൽ നിന്നും നീണ്ട സ്ക്രിപ്റ്റുകൾ ശേഖരത്തിലെ ഫയലുകളിലേക്ക് നീക്കുക, അവിടെ ShellCheck-ന് അവയെ ലിന്റ് ചെയ്യാനും നിങ്ങൾക്ക് അവയെ പ്രാദേശികമായി പ്രവർത്തിപ്പിക്കാനും കഴിയും.

പിന്നെ, ചെയ്യേണ്ട കാര്യം എന്താണ്?

കൂട്ടിച്ചേര് ക്കുക set -euo pipefail ഓരോ സ്ക്രിപ്റ്റിന്റെയും മുകളില് പോയി, അവയെല്ലാം ഷെല്ല് ചെക്ക് ചെയ്ത് നോക്കുക. ആ രണ്ടു ശീലങ്ങൾ ആണ് ഷെൽ സ്ക്രിപ്റ്റുകളിൽ നിന്നും ഞാൻ കണ്ടിട്ടുള്ള മിക്ക ദുരന്തങ്ങളും തടയുന്നത്.

എന്റെ അഭിപ്രായം, ബാഷ് ഒരു മൂർച്ചയുള്ള കത്തിയാണ്. ചെറിയ മുറിവുകള് ക്കായി ഉപയോഗിക്കുക, ഷെല്ല് ചെക്ക് ഉപയോഗിച്ച് അത് മൂർച്ചയുള്ളതാക്കുക, ജോലി വലുതാകുമ്പോള് ശരിയായ ഉപകരണത്തിലേക്ക് മാറുക.

ഡെസ്ലി