I-Bash Scripting Best Practicing: Isikhokelo esiKhawulezayo kwiZikripthi zeBash ezithembekileyo kunye nokuSebenza

I-Bash Scripting Best Practicing: Isikhokelo esiKhawulezayo kwiZikripthi zeBash ezithembekileyo kunye nokuSebenza
Shell iphepha lokunamathisela odongeni by manapi

I-debugging bash scripts kufana nokukhangela inaliti kwi-haystack, ngakumbi xa izongezo ezintsha zivela kwi-codebase ekhoyo ngaphandle kokuqwalaselwa kwangethuba kwimiba yesakhiwo, ukugawulwa kwemithi kunye nokuthembeka. Unokuzifumana ukwiimeko ezinjalo ngenxa yeempazamo zakho okanye xa ulawula iimfumba ezintsonkothileyo zescripts.

Iqela Mail.ru Cloud Solutions iguqulelwe inqaku elineengcebiso eziza kukunceda ubhale, ulungise kwaye ugcine izikripthi zakho ngcono. Yikholwa okanye hayi, akukho nto ibetha ukwaneliseka kokubhala okucocekileyo, ikhowudi ye-bash elungele ukusetyenziswa esebenza ngalo lonke ixesha.

Kwinqaku, umbhali wabelana ngezinto azifundileyo kwiminyaka embalwa edlulileyo, kunye neempazamo eziqhelekileyo eziye zambamba. Oku kubalulekile kuba wonke umphuhlisi wesoftware, ngaxa lithile kumsebenzi wabo, usebenza kunye nezikripthi ukuzenzela imisebenzi yesiqhelo.

Abaphathi bomgibe

Uninzi lwezikripthi ze-bash endikhe ndadibana nazo zange zisebenzise indlela yokucoca esebenzayo xa kukho into engalindelekanga eyenzekayo ngexesha lokubhalwa kwescript.

Ukumangalisa kunokuvela ngaphandle, njengokufumana umqondiso osuka kwingundoqo. Ukuphatha iimeko ezinjalo kubaluleke kakhulu ukuqinisekisa ukuba imibhalo ithembekile ngokwaneleyo ukuba iqhutywe kwiinkqubo zemveliso. Ndihlala ndisebenzisa abaphathi bokuphuma ukuphendula kwiimeko ezinje:

function handle_exit() {
  // Add cleanup code here
  // for eg. rm -f "/tmp/${lock_file}.lock"
  // exit with an appropriate status code
}
  
// trap <HANDLER_FXN> <LIST OF SIGNALS TO TRAP>
trap handle_exit 0 SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM

trap liqokobhe elakhelwe-ngaphakathi umyalelo okunceda ubhalise umsebenzi wokucoca obizwa ngokuba kuyo nayiphi na imiqondiso. Nangona kunjalo, kufuneka kuthathelwe ingqalelo ekhethekileyo kunye nabaphathi abanje SIGINT, ebangela ukuba iskripthi siyeke.

Ukongeza, kwiimeko ezininzi kufuneka ubambe kuphela EXIT, kodwa uluvo kukuba unokwenza ngokwenyani impatho yeskripthi kuphawu ngalunye.

Eyakhelwe-ngaphakathi imisebenzi iseti - ukupheliswa ngokukhawuleza kwimpazamo

Kubaluleke kakhulu ukuphendula kwiimpazamo ngokukhawuleza nje ukuba zenzeke kwaye uyeke ukubulawa ngokukhawuleza. Akukho nto inokuba mbi ngakumbi kunokuqhubeka nokusebenzisa umyalelo onje:

rm -rf ${directory_name}/*

Nceda uqaphele ukuba utshintsho directory_name ayimiselwanga.

Kubalulekile ukusebenzisa imisebenzi eyakhelweyo ukusingatha iimeko ezinjalo setnjenge set -o errexit, set -o pipefail okanye set -o nounset ekuqaleni kweskripthi. Le misebenzi iqinisekisa ukuba iskripthi sakho siya kuphuma kamsinya nje sakuba sidibana nayo nayiphi na ikhowudi yokuphuma engeyo-zero, ukusetyenziswa kwezinto eziguquguqukayo ezingachazwanga, imiyalelo engasebenziyo egqithwe phezu kombhobho, njalo njalo:

#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail

function print_var() {
  echo "${var_value}"
}

print_var

$ ./sample.sh
./sample.sh: line 8: var_value: unbound variable

Qaphela: imisebenzi eyakhelwe-ngaphakathi njenge set -o errexit, iya kuphuma kwiscript ngokukhawuleza ukuba kukho ikhowudi yokubuyisela "eluhlaza" (ngaphandle kweqanda). Ngoko ke kungcono ukwazisa ukuphatha iimpazamo zesiko, umzekelo:

#!/bin/bash
error_exit() {
  line=$1
  shift 1
  echo "ERROR: non zero return code from line: $line -- $@"
  exit 1
}
a=0
let a++ || error_exit "$LINENO" "let operation returned non 0 code"
echo "you will never see me"
# run it, now we have useful debugging output
$ bash foo.sh
ERROR: non zero return code from line: 9 -- let operation returned non 0 code

Ukubhala izikripthi ngale ndlela kukunyanzela ukuba ulumke ngakumbi malunga nokuziphatha kwayo yonke imiyalelo ekwiskripthi kwaye ulindele ukuba kwenzeke impazamo ngaphambi kokuba ikuthathe ngokumangalisayo.

ShellCheck ukubona iimpazamo ngexesha lophuhliso

Kufanelekile ukudibanisa into enje ShellKhangela kuphuhliso lwakho kunye nemibhobho yokuvavanya ukujonga ikhowudi yakho ye-bash ngokuchasene nezenzo ezilungileyo.

Ndiyisebenzisa kwindawo yam yophuhliso lwasekhaya ukufumana iingxelo malunga ne-syntax, i-semantics, kunye neempazamo ezithile kwikhowudi endinokuthi ndiyiphosile ngelixa ndiphuhlisa. Esi sisixhobo sokuhlalutya okumileyo kwizikripthi zakho ze-bash kwaye ndincoma kakhulu ukuba uyisebenzise.

Ukusebenzisa iikhowudi zakho zokuphuma

Iikhowudi zokubuya kwiPOSIX ayingoziro okanye enye kuphela, kodwa inguziro okanye ixabiso elingengo-zero. Sebenzisa ezi mpawu ukubuyisela iikhowudi zempazamo yesiko (phakathi kwe-201-254) kwiimeko ezahlukeneyo zeempazamo.

Olu lwazi lunokuthi ke lusetyenziswe zezinye izikripthi ezisonga eyakho ukuqonda ngqo ukuba loluphi uhlobo lwempazamo eyenzekileyo kwaye usabele ngokufanelekileyo:

#!/usr/bin/env bash

SUCCESS=0
FILE_NOT_FOUND=240
DOWNLOAD_FAILED=241

function read_file() {
  if ${file_not_found}; then
    return ${FILE_NOT_FOUND}
  fi
}

Qaphela: Nceda ulumkele amagama aguquguqukayo owachazayo ukunqanda ngempazamo ukugqithisela ngaphezulu kwezinto eziguquguqukayo.

Imisebenzi yokugawulwa kwemithi

Ukugawulwa kwemithi okuhle kunye nokucwangcisiweyo kubalulekile ukuqonda ngokulula iziphumo zeskripthi sakho. Njengezinye iilwimi ezikumgangatho ophezulu, ndihlala ndisebenzisa imisebenzi yokugawulwa kwemveli kwizikripthi zam ze-bash, ezifana __msg_info, __msg_error kwaye njalo njalo.

Oku kunceda ukubonelela ngesakhiwo esisemgangathweni sokugawulwa kwemithi ngokwenza utshintsho kwindawo enye kuphela:

#!/usr/bin/env bash

function __msg_error() {
    [[ "${ERROR}" == "1" ]] && echo -e "[ERROR]: $*"
}

function __msg_debug() {
    [[ "${DEBUG}" == "1" ]] && echo -e "[DEBUG]: $*"
}

function __msg_info() {
    [[ "${INFO}" == "1" ]] && echo -e "[INFO]: $*"
}

__msg_error "File could not be found. Cannot proceed"

__msg_debug "Starting script execution with 276MB of available RAM"

Ndihlala ndizama ukuba nohlobo oluthile lwendlela kwizikripthi zam __init, apho iinguqu ezinjalo zelogi kunye nezinye iinguqu zesixokelelwano ziqaliswa okanye zimiselwe kumaxabiso angagqibekanga. Ezi ziguquguqukayo zinokusetwa kwiinketho zelayini yomyalelo ngexesha lokubizwa kwescript.

Umzekelo, into efana nale:

$ ./run-script.sh --debug

Xa umbhalo onjalo uphunyeziwe, uqinisekisa ukuba izicwangciso zenkqubo-banzi zimiselwe kumaxabiso angagqibekanga ukuba ayafuneka, okanye ubuncinane aqaliswe kwinto efanelekileyo ukuba kuyimfuneko.

Ndidla ngokusekela ukhetho lwento ekufuneka iqaliswe kwaye ungayenzi kurhwebo phakathi kojongano lomsebenzisi kunye neenkcukacha zoqwalaselo apho umsebenzisi anokuthi ajonge kulo.

Ulwakhiwo lokusetyenziswa kwakhona kunye nococeko lwenkqubo yelizwe

Ikhowudi yemodyuli/enokusetyenziswa kwakhona

β”œβ”€β”€ framework
β”‚   β”œβ”€β”€ common
β”‚   β”‚   β”œβ”€β”€ loggers.sh
β”‚   β”‚   β”œβ”€β”€ mail_reports.sh
β”‚   β”‚   └── slack_reports.sh
β”‚   └── daily_database_operation.sh

Ndigcina indawo yokugcina eyahlukileyo endinokuthi ndiyisebenzise ukuqalisa iprojekthi entsha/iskripthi se-bash endifuna ukusiphuhlisa. Nantoni na enokuphinda isetyenziswe ingagcinwa kwindawo yokugcina kwaye ifunyanwe zezinye iiprojekthi ezifuna ukusebenzisa loo msebenzi. Ukulungiselela iiprojekthi ngale ndlela kunciphisa kakhulu ubungakanani bezinye izikripthi kwaye kwakhona kuqinisekisa ukuba isiseko sekhowudi sincinci kwaye kulula ukuvavanya.

Njengoko kumzekelo ongentla, yonke imisebenzi yokugawulwa kwemithi efana __msg_info, __msg_error kunye nezinye, njengeengxelo ze-Slack, ziqulethwe ngokwahlukeneyo common/* kunye nokudibanisa ngamandla kwezinye iimeko ezifana daily_database_operation.sh.

Shiya ngasemva inkqubo ecocekileyo

Ukuba ulayisha naziphi na izixhobo ngelixa iskripthi sisebenza, kuyacetyiswa ukuba ugcine yonke loo datha kulawulo ekwabelwana ngalo ngegama elingenamkhethe, umz. /tmp/AlRhYbD97/*. Ungasebenzisa iijenereyitha zokubhaliweyo ezingakhethiyo ukukhetha igama likavimba weefayili:

rand_dir_name="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"

Emva kokugqitywa komsebenzi, ukucocwa kwezikhokelo ezinjalo kunokubonelelwa kubaphathi be-hook abaxoxwe ngasentla. Ukuba abalawuli bexeshana abakhathalelwanga, bayaqokelelana kwaye kwinqanaba elithile babangele iingxaki ezingalindelekanga kumamkeli, njengediski epheleleyo.

Ukusebenzisa iifayile zokutshixa

Rhoqo kufuneka uqinisekise ukuba mnye kuphela umzekelo weskripthi osebenzayo kumamkeli nangaliphi na ixesha. Oku kunokwenziwa ngokusebenzisa iifayile zokutshixa.

Ndidla ngokwenza iifayile zokutshixa ngaphakathi /tmp/project_name/*.lock kwaye ujonge ubukho babo ekuqaleni kwescript. Oku kunceda iscript siphelise kakuhle kwaye sinqande utshintsho olungalindelekanga kwisistim yemo yesinye iskripthi esisebenza ngokunxuseneyo. Iifayile zokutshixa azifuneki ukuba ufuna umbhalo ofanayo ukuze uphunyezwe ngokuhambelana kumamkeli onikiweyo.

Ukulinganisa kunye nokuphucula

Kuhlala kufuneka sisebenze ngemibhalo esebenza ixesha elide, elifana nokusebenza kwedatha yemihla ngemihla. Imisebenzi enjalo ibandakanya ukulandelelana kwamanyathelo: ukulayisha idatha, ukujonga izinto ezingaqhelekanga, ukungenisa idatha, ukuthumela iingxelo zesimo, njalo njalo.

Kwiimeko ezinjalo, ndihlala ndizama ukwaphula iskripthi sibe sisikripthi esincinci esahlukileyo kwaye ndixele ubume babo kunye nexesha lokuphumeza usebenzisa:

time source "${filepath}" "${args}">> "${LOG_DIR}/RUN_LOG" 2>&1

Emva kwexesha ndiyabona ixesha lokwenziwa:

tac "${LOG_DIR}/RUN_LOG.txt" | grep -m1 "real"

Oku kundinceda ukuba ndibone ingxaki/iindawo ezicothayo kwizikripthi ezifuna ukwenziwa ngcono.

nethamsanqa!

Yintoni enye ekufuneka uyifunde:

  1. Hamba kunye neecache zeGPU.
  2. Umzekelo wesicelo esiqhutywe kwisiganeko esisekelwe kwii-webhooks kwi-S3 into yokugcina i-Mail.ru Cloud Solutions.
  3. Ijelo lethu letelegram malunga nenguqu yedijithali.

umthombo: www.habr.com

Yongeza izimvo