بش اسڪرپٽنگ بهترين طريقا: قابل اعتماد ۽ ڪارڪردگي بش اسڪرپٽ لاءِ هڪ تڪڙي رهنمائي

بش اسڪرپٽنگ بهترين طريقا: قابل اعتماد ۽ ڪارڪردگي بش اسڪرپٽ لاءِ هڪ تڪڙي رهنمائي
مناپي طرفان شيل وال پيپر

بيش اسڪرپٽ کي ڊيبگ ڪرڻ هڪ گاهه جي اسٽيڪ ۾ سوئي ڳولڻ وانگر آهي، خاص طور تي جڏهن موجوده ڪوڊ بيس ۾ نوان اضافا ظاهر ٿين ٿا، بغير ساخت، لاگنگ ۽ اعتبار جي مسئلن جي بروقت غور ڪرڻ کان سواء. توهان پنهنجو پاڻ کي اهڙين حالتن ۾ ڳولي سگهو ٿا يا ته توهان جي پنهنجي غلطين جي ڪري يا جڏهن اسڪرپٽ جي پيچيده انبار کي منظم ڪندي.

ٽيم Mail.ru ڪلائوڊ حل سفارشن سان گڏ هڪ آرٽيڪل ترجمو ڪيو جيڪو توهان جي لکت کي بهتر نموني لکڻ، ڊيبگ ڪرڻ ۽ برقرار رکڻ ۾ مدد ڪندو. ان تي يقين رکو يا نه، ڪجھ به صاف لکڻ جي اطمينان کي مات نٿو ڪري، استعمال ڪرڻ لاء تيار بش ڪوڊ جيڪو هر وقت ڪم ڪري ٿو.

آرٽيڪل ۾، ليکڪ حصيداري ڪري ٿو جيڪو هن گذريل ڪجهه سالن ۾ سکيو آهي، انهي سان گڏ ڪجهه عام غلطيون جيڪي هن کي گارڊ بند ڪري ڇڏيون آهن. اهو ضروري آهي ڇاڪاڻ ته هر سافٽ ويئر ڊولپر، پنهنجي ڪيريئر ۾ ڪجهه نقطي تي، اسڪرپٽ سان ڪم ڪري ٿو معمول جي ڪم جي ڪم کي خودڪار ڪرڻ لاء.

ٽريپ سنڀاليندڙ

گهڻيون بش اسڪرپٽ جيڪي مون کي سامهون آيون آهن ڪڏهن به هڪ موثر صاف ڪرڻ واري ميڪانيزم کي استعمال نه ڪندا آهن جڏهن ڪجهه غير متوقع طور تي اسڪرپٽ جي عمل دوران ٿئي ٿي.

حيرت انگيز ٻاهران پيدا ٿي سگهي ٿي، جهڙوڪ بنيادي مان سگنل وصول ڪرڻ. اهڙين ڪيسن کي سنڀالڻ تمام ضروري آهي انهي ڳالهه کي يقيني بڻائڻ لاءِ ته لکتون ڪافي قابل اعتماد آهن پروڊڪشن سسٽم تي هلائڻ لاءِ. مان اڪثر هن طرح جي منظرنامي جو جواب ڏيڻ لاءِ ٻاهر نڪرڻ وارا هينڊلر استعمال ڪندا آهن:

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 ھڪڙو شيل بلٽ ان ڪمانڊ آھي جيڪو توھان کي رجسٽر ڪرڻ ۾ مدد ڪري ٿو صاف ڪرڻ واري فنڪشن جيڪا ڪنھن سگنل جي صورت ۾ سڏيو وڃي ٿو. تنهن هوندي به، خاص خيال رکڻ گهرجي handlers سان جيئن SIGINT، جيڪو اسڪرپٽ کي ختم ڪرڻ جو سبب بڻائيندو آهي.

ان کان سواء، اڪثر ڪيسن ۾ توهان کي صرف پڪڙڻ گهرجي EXIT، پر خيال اهو آهي ته توهان اصل ۾ هر فرد سگنل لاءِ رسم الخط جي رويي کي ترتيب ڏئي سگهو ٿا.

بلٽ ان سيٽ افعال - غلطي تي جلدي ختم ٿيڻ

اهو تمام ضروري آهي ته جيئن ئي غلطيون ٿينديون آهن انهن جو جواب ڏيڻ ۽ جلدي عمل کي روڪڻ. ڪجھ به خراب نه ٿي سگھي ٿو جاري رکڻ کان وڌيڪ حڪم جاري رکڻ وانگر:

rm -rf ${directory_name}/*

مهرباني ڪري نوٽ ڪريو ته variable directory_name مقرر نه ڪيو ويو.

اهڙين حالتن کي سنڀالڻ لاءِ بلٽ ان فنڪشن استعمال ڪرڻ ضروري آهي set، جيئن ته set -o errexit, set -o pipefail يا set -o nounset رسم الخط جي شروعات ۾. اهي فنڪشن انهي ڳالهه کي يقيني بڻائين ٿا ته توهان جي اسڪرپٽ جلدي ٻاهر نڪرندي جيئن اهو ڪنهن به غير صفر نڪرڻ واري ڪوڊ سان ملندو، اڻ ڄاڻايل متغيرن جو استعمال، غلط ڪمانڊ پائپ مٿان گذريو، وغيره.

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

نوٽ: تعمير ٿيل افعال جهڙوڪ set -o errexit, جلد ئي اسڪرپٽ مان نڪرندو جيئن اتي "خام" موٽڻ وارو ڪوڊ هوندو (صفر کان سواءِ). تنهن ڪري اهو بهتر آهي ته رواجي غلطي سنڀالڻ کي متعارف ڪرايو، مثال طور:

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

اسڪرپٽ لکڻ هن طريقي سان توهان کي اسڪرپٽ ۾ سڀني حڪمن جي رويي جي باري ۾ وڌيڪ محتاط ٿيڻ تي مجبور ڪري ٿو ۽ توهان کي حيران ٿيڻ کان پهريان ڪنهن غلطي جي امڪان جو اندازو لڳايو.

شيل چيڪ ڪريو ڊولپمينٽ دوران غلطيون ڳولڻ لاءِ

اهو ڪجهه ضم ڪرڻ جي لائق آهي جهڙوڪ شيل چيڪ ڪريو توهان جي ڊولپمينٽ ۽ ٽيسٽنگ پائپ لائنن ۾ توهان جي بش ڪوڊ کي جانچڻ لاءِ بهترين عملن جي خلاف.

مان ان کي استعمال ڪريان ٿو پنھنجي مقامي ڊولپمينٽ ماحول ۾ نحو، اصطلاحي، ۽ ڪوڊ ۾ ڪجھ نقصن تي رپورٽون حاصل ڪرڻ لاءِ جيڪي ترقي ڪرڻ دوران مون کي ياد ٿي سگھي ٿي. هي هڪ جامد تجزيي وارو اوزار آهي توهان جي بش اسڪرپٽس لاءِ ۽ مان ان کي استعمال ڪرڻ جي انتهائي صلاح ڏيان ٿو.

توهان جي پنهنجي نڪرڻ جا ڪوڊ استعمال ڪندي

POSIX ۾ ريٽرن ڪوڊ صرف صفر يا هڪ نه آهن، پر صفر يا هڪ غير صفر قدر. مختلف غلطين جي ڪيسن لاءِ ڪسٽم ايرر ڪوڊ (201-254 جي وچ ۾) واپس ڪرڻ لاءِ ھي خاصيتون استعمال ڪريو.

اها معلومات پوءِ استعمال ڪري سگھجن ٿا ٻين اسڪرپٽس پاران جيڪي توهان کي سمجهه ۾ آڻين ٿيون ته ڪهڙي قسم جي غلطي ٿي آهي ۽ ان مطابق رد عمل ظاهر ڪريو:

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

نوٽ: مھرباني ڪري خاص طور تي محتاط رھو متغير نالن سان جيڪي توھان بيان ڪندا آھيو حادثاتي طور تي ماحولياتي متغيرن کي ختم ڪرڻ کان بچڻ لاءِ.

لاگنگ افعال

توهان جي اسڪرپٽ جي نتيجن کي آساني سان سمجهڻ لاءِ خوبصورت ۽ منظم لاگنگ ضروري آهي. جيئن ٻين اعليٰ سطحي پروگرامنگ ٻولين سان، مان هميشه پنهنجي بيش اسڪرپٽس ۾ مقامي لاگنگ فنڪشن استعمال ڪندو آهيان، جهڙوڪ __msg_info, __msg_error ۽ پوء تي.

هي صرف هڪ جڳهه ۾ تبديليون ڪندي هڪ معياري لاگنگ ڍانچي مهيا ڪرڻ ۾ مدد ڪري ٿو:

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

مان اڪثر ڪوشش ڪندو آهيان ته منهنجي اسڪرپٽ ۾ ڪنهن قسم جو ميکانيزم هجي __init, جتي اهڙي logger variables ۽ ٻيا سسٽم متغير شروع ڪيا ويا آهن يا ڊفالٽ ويلز تي مقرر ڪيا ويا آهن. اهي متغير پڻ مقرر ڪري سگھجن ٿا ڪمانڊ لائن اختيارن مان اسڪرپٽ جي دعوت دوران.

مثال طور، ڪجھه وانگر:

$ ./run-script.sh --debug

جڏهن اهڙي اسڪرپٽ تي عمل ڪيو ويندو آهي، اهو يقيني بڻائي ٿو ته سسٽم-وائڊ سيٽنگون ڊفالٽ ويلز تي مقرر ڪيون ويون آهن جيڪڏهن اهي گهربل هجن، يا گهٽ ۾ گهٽ شروع ڪيو وڃي ته ضروري هجي ته مناسب هجي.

مان عام طور تي بنيادي طور تي چونڊجي ٿو ته ڇا شروع ڪرڻ گهرجي ۽ ڇا نه ڪرڻ گهرجي واپار جي وچ ۾ يوزر انٽرفيس ۽ ترتيبن جي تفصيلن جي وچ ۾ جيڪي صارف ڪري سگھن ٿا/ان ۾ داخل ٿيڻ گهرجي.

ٻيهر استعمال ۽ صاف سسٽم اسٽيٽ لاءِ آرڪيٽيڪچر

ماڊلر / ٻيهر استعمال لائق ڪوڊ

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

مان هڪ الڳ مخزن رکندو آهيان جيڪو مان استعمال ڪري سگهان ٿو هڪ نئين پروجيڪٽ/بش اسڪرپٽ کي شروع ڪرڻ لاءِ جيڪو مان ترقي ڪرڻ چاهيان ٿو. ڪا به شيء جيڪا ٻيهر استعمال ڪري سگهجي ٿي ذخيرو ۾ ذخيرو ٿي سگهي ٿي ۽ ٻين منصوبن پاران ٻيهر حاصل ڪري سگهجي ٿي جيڪي انهي ڪارڪردگي کي استعمال ڪرڻ چاهيندا آهن. پروجيڪٽس کي منظم ڪرڻ هن طريقي سان ٻين اسڪرپٽس جي سائيز کي خاص طور تي گھٽائي ٿو ۽ اهو پڻ يقيني بڻائي ٿو ته ڪوڊ جو بنياد ننڍڙو ۽ ٽيسٽ ڪرڻ آسان آهي.

جيئن مٿي ڏنل مثال ۾، سڀ لاگنگ افعال جهڙوڪ __msg_info, __msg_error ۽ ٻيا، جهڙوڪ Slack رپورٽون، الڳ الڳ ۾ شامل آهن common/* ۽ متحرڪ طور تي ٻين منظرنامن ۾ ڳنڍيو جهڙوڪ daily_database_operation.sh.

هڪ صاف نظام کي ڇڏي ڏيو

جيڪڏهن توهان ڪي وسيلا لوڊ ڪري رهيا آهيو جڏهن اسڪرپٽ هلي رهي آهي، اها سفارش ڪئي وئي آهي ته اهڙي سموري ڊيٽا کي گڏ ڪيل ڊاريڪٽري ۾ بي ترتيب نالي سان، مثال طور. /tmp/AlRhYbD97/*. توھان ڊاريڪٽري جو نالو چونڊڻ لاءِ بي ترتيب ٽيڪسٽ جنريٽر استعمال ڪري سگھو ٿا:

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

ڪم جي مڪمل ٿيڻ کان پوء، مٿي ذڪر ڪيل ٿلهو هينڊلر ۾ اهڙي ڊائريڪٽرن جي صفائي مهيا ڪري سگهجي ٿي. جيڪڏهن عارضي ڊائريڪٽرن جو خيال نه رکيو وڃي، اهي جمع ٿين ٿا ۽ ڪجهه اسٽيج تي ميزبان تي اڻڄاتل مسئلا پيدا ڪن ٿا، جهڙوڪ مڪمل ڊسڪ.

لاک فائلن کي استعمال ڪندي

گهڻو ڪري توهان کي پڪ ڪرڻ جي ضرورت آهي ته هڪ اسڪرپٽ جو صرف هڪ مثال ڪنهن به وقت ميزبان تي هلندڙ آهي. اهو تالا فائلون استعمال ڪندي ڪري سگهجي ٿو.

مان عام طور تي لاڪ فائلون ٺاهيندو آهيان /tmp/project_name/*.lock ۽ لکت جي شروعات ۾ انهن جي موجودگي جي جانچ ڪريو. هي اسڪرپٽ کي شاندار طور تي ختم ڪرڻ ۾ مدد ڪري ٿو ۽ متوازي ۾ هلندڙ هڪ ٻي اسڪرپٽ ذريعي سسٽم اسٽيٽ ۾ غير متوقع تبديلين کان پاسو ڪري ٿو. لاڪ فائلن جي ضرورت نه آھي جيڪڏھن توھان کي ھڪڙي اسڪرپٽ جي ضرورت آھي ھڪڙي ڏنل ميزبان تي متوازي طور تي عمل ڪيو وڃي.

ماپ ۽ بهتر ڪريو

اسان کي اڪثر اسڪرپٽ سان ڪم ڪرڻ جي ضرورت آهي جيڪي ڊگھي عرصي تائين هلن ٿيون، جهڙوڪ روزاني ڊيٽابيس آپريشن. اهڙن عملن ۾ عام طور تي قدمن جو سلسلو شامل هوندو آهي: ڊيٽا لوڊ ڪرڻ، بي ضابطگين جي چڪاس، ڊيٽا درآمد ڪرڻ، اسٽيٽس رپورٽون موڪلڻ وغيره.

اهڙين حالتن ۾، مان هميشه ڪوشش ڪندو آهيان ته اسڪرپٽ کي الڳ الڳ اسڪرپٽ ۾ ورهايو ۽ انهن جي صورتحال ۽ عمل جي وقت کي استعمال ڪندي رپورٽ ڪريو:

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

بعد ۾ آئون ان سان گڏ عملدرآمد جو وقت ڏسي سگهان ٿو:

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

هي مون کي اسڪرپٽ ۾ مسئلو/سست علائقن جي نشاندهي ڪرڻ ۾ مدد ڪري ٿو جن کي اصلاح جي ضرورت آهي.

سٺي قسمت!

ٻيو ڇا پڙهو:

  1. وڃو ۽ GPU ڪيش.
  2. Mail.ru Cloud Solutions جي S3 آبجیکٹ اسٽوريج ۾ ويب هوڪس تي ٻڌل واقعن تي هلندڙ ايپليڪيشن جو هڪ مثال.
  3. ڊجيٽل تبديليءَ بابت اسان جو ٽيليگرام چينل.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو