Praktek Pangalusna Bash Scripting: Pitunjuk Gancang pikeun Skrip Bash anu Dipercaya sareng Kinerja

Praktek Pangalusna Bash Scripting: Pitunjuk Gancang pikeun Skrip Bash anu Dipercaya sareng Kinerja
Wallpaper cangkang ku manapi

Debugging skrip bash sapertos milarian jarum dina tumpukan jukut, khususna nalika tambihan énggal muncul dina basis kode anu tos aya tanpa pertimbangan tepat waktu ngeunaan masalah struktur, logging sareng reliabilitas. Anjeun tiasa mendakan diri dina kaayaan sapertos kitu kusabab kasalahan anjeun nyalira atanapi nalika ngatur tumpukan skrip anu rumit.

regu Mail.ru Cloud Solutions narjamahkeun artikel kalawan rekomendasi anu bakal nulungan anjeun nulis, debug jeung ngajaga Aksara anjeun hadé. Percanten atawa henteu, euweuh ngéléhkeun kapuasan nulis bersih, kode bash siap pake anu hade unggal waktu.

Dina tulisan éta, panulis ngabagi naon anu anjeunna pelajari dina sababaraha taun katukang, ogé sababaraha kasalahan umum anu nyababkeun anjeunna teu waspada. Ieu penting sabab unggal pamekar parangkat lunak, dina sababaraha waktos dina karirna, damel sareng skrip pikeun ngajadikeun otomatis tugas kerja rutin.

Panangan bubu

Seuseueurna skrip bash anu kuring tepang henteu pernah ngagunakeun mékanisme ngabersihkeun anu épéktip nalika aya kajadian anu teu kaduga nalika palaksanaan naskah.

Kejutan tiasa timbul ti luar, sapertos nampi sinyal ti inti. Nanganan kasus sapertos kitu penting pisan pikeun mastikeun yén skripna cukup dipercaya pikeun ngajalankeun sistem produksi. Kuring sering nganggo pawang kaluar pikeun ngabales skenario sapertos kieu:

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 mangrupakeun cangkang diwangun-di paréntah nu mantuan Anjeun ngadaptarkeun fungsi cleanup nu disebut bisi aya sinyal. Nanging, perawatan khusus kedah dilaksanakeun sareng pawang sapertos SIGINT, nu nyababkeun naskah batal.

Sajaba ti éta, dina kalolobaan kasus Anjeun ngan kudu nyekel EXIT, Tapi ideu téh nu sabenerna bisa ngaropea paripolah naskah pikeun tiap sinyal individu.

Diwangun-di set fungsi - terminasi gancang on kasalahan

Penting pisan pikeun ngabales kasalahan pas kajadian sareng ngeureunkeun palaksanaan gancang. Henteu aya anu langkung parah tibatan neraskeun ngajalankeun paréntah sapertos kieu:

rm -rf ${directory_name}/*

Punten dicatet yén variabel directory_name teu ditangtukeun.

Penting pikeun ngagunakeun fungsi anu diwangun pikeun nanganan skenario sapertos kitu set, sapertos set -o errexit, set -o pipefail atawa set -o nounset dina awal naskah. Pungsi ieu mastikeun yén skrip anjeun bakal kaluar pas manggihan kode kaluar non-enol, pamakéan variabel undefined, paréntah teu valid ngaliwatan pipa, jeung saterusna:

#!/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

Catetan: diwangun-di fungsi kayaning set -o errexit, bakal kaluar naskah pas aya "atah" kode balik (lian ti enol). Ku sabab eta leuwih hade ngenalkeun penanganan kasalahan khusus, contona:

#!/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

Nulis skrip ku cara ieu maksakeun anjeun langkung ati-ati ngeunaan paripolah sadaya paréntah dina naskah sareng antisipasi kamungkinan kasalahan sateuacan anjeun kaget.

ShellCheck pikeun ngadeteksi kasalahan nalika pangwangunan

Éta patut ngahijikeun hal sapertos ShellCheck kana ngembangkeun anjeun sarta nguji pipelines pikeun pariksa kode bash anjeun ngalawan prakték pangalusna.

Kuring ngagunakeun éta dina lingkungan pamekaran lokal kuring pikeun kéngingkeun laporan ngeunaan sintaksis, semantik, sareng sababaraha kasalahan dina kode anu kuring lasut nalika ngembangkeun. Ieu mangrupikeun alat analisis statik pikeun skrip bash anjeun sareng kuring nyarankeun pisan ngagunakeunana.

Ngagunakeun kode kaluar anjeun sorangan

Kodeu balik dina POSIX henteu ngan enol atanapi hiji, tapi enol atanapi henteu nol. Paké fitur ieu pikeun balik kode kasalahan custom (antara 201-254) pikeun sagala rupa kasus kasalahan.

Inpormasi ieu teras tiasa dianggo ku skrip sanés anu ngabungkus anjeun pikeun ngartos naon jinis kasalahan anu kajantenan sareng ngaréspon sasuai:

#!/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
}

Catetan: punten ati-ati pisan sareng nami variabel anu anjeun tangtukeun pikeun ngahindarkeun variabel lingkungan anu teu kahaja.

Fungsi logging

Éndah sareng terstruktur logging penting pikeun gampang ngartos hasil naskah anjeun. Sapertos sareng basa pamrograman tingkat luhur anu sanés, kuring sok nganggo fungsi logging asli dina skrip bash kuring, sapertos __msg_info, __msg_error jeung saterusna.

Ieu ngabantuan nyadiakeun struktur logging standar ku nyieun parobahan dina ngan hiji tempat:

#!/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"

Kuring biasana nyobian gaduh sababaraha jinis mékanisme dina naskah kuring __init, dimana variabel logger sapertos kitu sareng variabel sistem sanésna diinisialisasi atanapi disetel ka nilai standar. Variabel ieu ogé tiasa disetél tina pilihan garis paréntah salami panyebaran naskah.

Contona, hiji hal kawas:

$ ./run-script.sh --debug

Nalika skrip sapertos dieksekusi, éta ngajamin yén setélan-lebar sistem disetel ka nilai standar upami diperyogikeun, atanapi sahenteuna diinisialisasi kana hal anu luyu upami diperyogikeun.

Kuring biasana nangtukeun pilihan naon initialize na naon teu ngalakukeun dina trade-off antara panganteur pamaké sarta detil konfigurasi nu pamaké bisa / kedah delve kana.

Arsitéktur pikeun dianggo deui sareng kaayaan sistem bersih

Modular / kode reusable

├── framework
│   ├── common
│   │   ├── loggers.sh
│   │   ├── mail_reports.sh
│   │   └── slack_reports.sh
│   └── daily_database_operation.sh

Kuring nyimpen Repository misah nu abdi tiasa nganggo initialize hiji proyék anyar / Aksara bash nu Abdi hoyong ngamekarkeun. Naon waé anu tiasa dianggo deui tiasa disimpen dina gudang sareng dicandak ku proyék-proyék sanés anu hoyong nganggo fungsionalitas éta. Ngatur proyék ku cara ieu sacara signifikan ngirangan ukuran naskah anu sanés sareng ogé mastikeun yén dasar kode leutik sareng gampang diuji.

Sapertos conto di luhur, sadaya fungsi logging sapertos __msg_info, __msg_error jeung sajabana, sapertos laporan Slack, dikandung sacara misah dina common/* tur dinamis nyambung dina skenario sejenna kawas daily_database_operation.sh.

Ninggalkeun sistem anu bersih

Upami anjeun ngamuat sumberdaya naon waé nalika naskahna dijalankeun, disarankeun pikeun nyimpen sadaya data sapertos dina diréktori anu dibagi nganggo nami acak, f.eks. /tmp/AlRhYbD97/*. Anjeun tiasa nganggo generator téks acak pikeun milih nami diréktori:

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

Sanggeus réngsé gawé, cleanup of directories misalna bisa disadiakeun dina pawang hook dibahas di luhur. Upami diréktori samentawis henteu diurus, aranjeunna ngumpulkeun sareng dina sababaraha tahap nyababkeun masalah anu teu kaduga dina host, sapertos disk pinuh.

Ngagunakeun file konci

Sering anjeun kedah mastikeun yén ngan ukur hiji conto naskah anu dijalankeun dina host iraha waé. Ieu tiasa dilakukeun nganggo file konci.

Kuring biasana nyieun file konci dina /tmp/project_name/*.lock jeung pariksa ayana maranéhanana di awal naskah. Ieu ngabantuan skrip nungtungan anggun sareng ngahindarkeun parobihan anu teu kaduga dina kaayaan sistem ku skrip anu sanés jalan paralel. Konci file henteu diperyogikeun upami anjeun peryogi naskah anu sami pikeun dieksekusi paralel dina host anu dipasihkeun.

Ukur sareng ningkatkeun

Urang sering kedah damel sareng skrip anu dijalankeun dina waktos anu lami, sapertos operasi database sapopoé. Operasi sapertos biasana ngalibatkeun runtuyan léngkah: ngamuat data, mariksa anomali, ngimpor data, ngirim laporan status, jeung sajabana.

Dina kasus sapertos kitu, kuring sok nyobian ngarobih naskah kana skrip leutik anu misah sareng ngalaporkeun status sareng waktos palaksanaanna nganggo:

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

Teras kuring tiasa ningali waktos palaksanaan kalayan:

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

Ieu mantuan kuring ngaidentipikasi masalah / wewengkon slow dina Aksara nu peryogi optimasi.

Good tuah!

Naon deui anu dibaca:

  1. Go jeung GPU caches.
  2. Conto aplikasi anu didorong acara dumasar kana webhooks dina panyimpenan objék S3 tina Mail.ru Cloud Solutions.
  3. Saluran telegram kami ngeunaan transformasi digital.

sumber: www.habr.com

Tambahkeun komentar