Faɗuwar Ramin Zomo: Labarin kuskuren sake yi na varnish ɗaya - Sashe na 1

Ghostinushanka, Bayan bugawa a kan maɓallai na minti 20 da suka gabata kamar dai rayuwarsa ta dogara da shi, ya juya gare ni tare da maganganun daji a idanunsa da murmushi mai ban dariya - "Dude, ina tsammanin na fahimta."

"Duba nan," in ji shi, yana nuni ga ɗaya daga cikin alamomin da ke kan allon, "Na ci amanar ku jar hula, idan muka ƙara abin da na aiko muku a nan," yana nuna wani sashe na lambar, "kuskuren ba za a sake nunawa ba."

A dan daure da gajiya, na canza sed statement din da muka dade muna aiki akai, na ajiye file din, na gudu. systemctl varnish reload. Sakon kuskure ya bace...

Abokin aikina ya ci gaba da cewa: "Saikon imel ɗin da na yi musanya da ɗan takarar," in ji abokin aikin nasa, yayin da murmushinsa ya faɗo cikin wani murmushi na gaske mai cike da farin ciki, "Ba zato ba tsammani na gane cewa wannan matsala ɗaya ce!"

Yaya aka fara

Labarin yana ɗaukar fahimtar yadda bash, awk, sed da tsarin aiki. An fi son sanin varnish amma ba a buƙata ba.
An canza tambura a cikin snippets.
An rubuta da Ghostinushanka.
Wannan rubutu fassarar asali ce da aka buga a Turanci makonni biyu da suka gabata; fassarar boyikoden.

Rana ta haskaka ta cikin tagogin panoramic a wani sanyin kaka mai dumi, ƙoƙon abin sha mai ɗanɗano mai kafeyin yana hutawa daga maballin, sautin da aka fi so yana wasa akan rustle na maɓallan maɓalli a cikin belun kunne, kuma shigarwa ta farko a cikin jerin tikitin baya akan allon kanban cikin wasa da wasa tare da taken fatty "Bincike / binciko kuskure" load sh : echo: I/O kuskure" a mataki). Lokacin da yazo da varnish, babu kuma ba zai iya zama kuskure ba, koda kuwa ba su haifar da wata matsala ba, kamar yadda a cikin wannan yanayin.

Ga wadanda basu saba ba varnishreload, wannan rubutun harsashi ne mai sauƙi da ake amfani da shi don sake loda tsarin varnish - kuma ake kira VCL.

Kamar yadda taken tikitin ya nuna, kuskuren ya faru a ɗaya daga cikin sabobin a cikin mataki, kuma tun da na kasance da tabbacin cewa hanyar da aka yi amfani da varnish a cikin matakin tana aiki da kyau, na ɗauka cewa wannan zai zama ƙaramin kuskure. Don haka, kawai saƙon da ya shiga cikin rafin fitarwa wanda aka riga aka rufe. Na ɗauki tikitin don kaina, cikin cikakken kwarin gwiwa cewa zan yi alama a shirye a cikin ƙasa da mintuna 30, buga kaina a kan kafada don share allo na ɓarna na gaba kuma in dawo ga abubuwa masu mahimmanci.

Faduwa cikin bango a gudun kilomita 200 / h

Buɗe fayil varnishreload, A daya daga cikin sabar da ke tafiyar da Debian Stretch, na ga rubutun harsashi kasa da layin 200.

Gudu cikin rubutun, ban ga wani abu da zai iya haifar da matsala ba lokacin gudanar da shi sau da yawa kai tsaye daga tashar.

Bayan haka, wannan mataki ne, ko da ya karye, ba wanda zai yi gunaguni, da kyau ... ba da yawa ba. Ina gudanar da rubutun kuma in ga abin da za a rubuta zuwa tashar tashar, amma kurakurai ba a iya gani.

Wasu ma'aurata suna gudu don tabbatar da cewa ba zan iya sake haifar da kuskure ba tare da ƙarin ƙoƙari ba, kuma na fara gano yadda za a canza wannan rubutun kuma in sa shi har yanzu jefa kuskure.

Shin rubutun zai iya toshe STDOUT (amfani da > &-)? Ya da STDERR? Babu wani aiki a ƙarshe.

Babu shakka tsarin yana canza yanayin gudu ta wata hanya, amma ta yaya, kuma me yasa?
Na kunna vim da gyara varnishreload, ƙara set -x daidai a ƙarƙashin shebang, da fatan cewa cire kayan aikin rubutun zai ba da haske.

Fayil ɗin yana gyarawa, don haka sai na sake loda varnish kuma na ga cewa canjin ya karya komai gaba ɗaya ... Shaye-shaye cikakke ne, tare da tarin lambar C-like a ciki. Ko gungurawa a cikin tashar bai isa a gano inda aka fara ba. Na rude gaba daya. Shin yanayin gyara kuskure zai iya shafar aikin shirye-shiryen da ke gudana a cikin rubutun? A'a, ban tsoro. Bug a cikin harsashi? Abubuwa da yawa masu yuwuwa suna yawo a kaina kamar kyankyasai a wurare daban-daban. Kofin abin sha mai cike da maganin kafeyin ya zubo nan take, tafiya da sauri zuwa kicin don sake kawowa kuma… mu je. Na bude rubutun kuma na dubi shebang: #!/bin/sh.

/bin/sh - wannan bash symlink ne kawai, don haka ana fassara rubutun a cikin yanayin da ya dace da POSIX, daidai? Ba a can ba! Tsohuwar harsashi akan Debian shine dash, wanda shine ainihin menene yana nufin /bin/sh.

# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24  2017 /bin/sh -> dash

Saboda fitina, na canza shebang zuwa #!/bin/bash, cire set -x kuma ya sake gwadawa. A ƙarshe, akan sake shigar da varnish na gaba, kuskuren jurewa ya bayyana a cikin fitarwa:

Jan 01 12:00:00 hostname varnishreload[32604]: /usr/sbin/varnishreload: line 124: echo: write error: Broken pipe
Jan 01 12:00:00 hostname varnishreload[32604]: VCL 'reload_20190101_120000_32604' compiled

Layin 124, ga shi nan!

114 find_vcl_file() {
115         VCL_SHOW=$(varnishadm vcl.show -v "$VCL_NAME" 2>&1) || :
116         VCL_FILE=$(
117                 echo "$VCL_SHOW" |
118                 awk '$1 == "//" && $2 == "VCL.SHOW" {print; exit}' | {
119                         # all this ceremony to handle blanks in FILE
120                         read -r DELIM VCL_SHOW INDEX SIZE FILE
121                         echo "$FILE"
122                 }
123         ) || :
124
125         if [ -z "$VCL_FILE" ]
126         then
127                 echo "$VCL_SHOW" >&2
128                 fail "failed to get the VCL file name"
129         fi
130
131         echo "$VCL_FILE"
132 }

Amma kamar yadda ya juya, layin 124 ya zama fanko kuma ba shi da sha'awa. Zan iya ɗauka kawai cewa kuskuren ya faru a matsayin wani ɓangare na multiline wanda ya fara akan layi 116.
Abin da a ƙarshe aka rubuta zuwa ga m VCL_FILE a sakamakon aiwatar da karamin harsashi na sama?

A farkon, yana aika abubuwan da ke cikin m VLC_SHOW, halitta a kan layi 115, zuwa umarni na gaba ta hanyar bututu. Sannan me ya faru a can?

Na farko, yana amfani varnishadm, wanda shine ɓangare na kunshin shigarwa na varnish, don saita varnish ba tare da sake farawa ba.

babban umarni vcl.show -v ana amfani da shi don fitar da duk tsarin VCL da aka ƙayyade a ciki ${VCL_NAME}, zuwa STDOUT.

Don nuna saitin VCL mai aiki a halin yanzu da kuma nau'ikan da yawa na baya na jeri na jeri na varnish waɗanda har yanzu suke cikin ƙwaƙwalwar ajiya, zaku iya amfani da umarnin. varnishadm vcl.list, abin da za a fitar zai yi kama da haka:

discarded   cold/busy       1 reload_20190101_120000_11903
discarded   cold/busy       2 reload_20190101_120000_12068
discarded   cold/busy       16 reload_20190101_120000_12259
discarded   cold/busy       16 reload_20190101_120000_12299
discarded   cold/busy       28 reload_20190101_120000_12357
active      auto/warm       32 reload_20190101_120000_12397
available   auto/warm       0 reload_20190101_120000_12587

Ƙimar canzawa ${VCL_NAME} saita a wani bangare na rubutun varnishreload zuwa sunan VCL mai aiki a halin yanzu, idan akwai. A wannan yanayin zai zama "sake saukewa_20190101_120000_12397".

To, m. ${VCL_SHOW} ya ƙunshi cikakken tsari don varnish, ya zuwa yanzu bayyananne. Yanzu na fahimci dalilin da yasa fitarwar dash tare da set -x ya juya ya zama karya sosai - ya haɗa da abubuwan da ke cikin sakamakon sanyi.

Yana da mahimmanci a fahimci cewa ana iya haɗa cikakken tsarin VCL sau da yawa tare daga fayiloli da yawa. Ana amfani da maganganun nau'ikan C-style don ayyana inda aka haɗa fayil ɗin sanyi ɗaya a cikin wani, kuma shine ainihin abin da layin snippet mai zuwa ke game da shi.
Rubutun kalmomin da ke kwatanta fayilolin da aka haɗa suna da tsari mai zuwa:

// VCL.SHOW <NUM> <NUM> <FILENAME>

Lambobin da ke cikin wannan mahallin ba su da mahimmanci, muna sha'awar sunan fayil.

Don haka menene ya faru a cikin fadamar umarni da ke farawa akan layi 116?
Bari mu tsara shi.
Umurnin ya ƙunshi sassa huɗu:

  1. Mai sauki echo, wanda ke nuna darajar canjin ${VCL_SHOW}
    echo "$VCL_SHOW"
  2. awk, wanda ke neman layi (rikodi), inda filin farko, bayan raba rubutun, zai zama "//", na biyu kuma zai zama "VCL.SHOW".
    Awk zai rubuta layin farko wanda ya dace da waɗannan alamu sannan ya daina aiki nan da nan.

    awk '$1 == "//" && $2 == "VCL.SHOW" {print; exit}'
  3. Tushe na lamba wanda ke adana ƙimar filin a cikin masu canji guda biyar, waɗanda ke raba su ta sarari. FILE mai canzawa na biyar yana karɓar sauran layin. A ƙarshe, echo na ƙarshe yana rubuta abubuwan da ke cikin m ${FILE}.
    { read -r DELIM VCL_SHOW INDEX SIZE FILE; echo "$FILE" }
  4. Tunda duk matakai na 1 zuwa 3 an rufe su a cikin ƙaramin harsashi, fitowar ƙimar $FILE za a rubuta zuwa wani m VCL_FILE.

Kamar yadda sharhin da ke kan layi na 119 ya nuna, wannan yana yin amfani da manufar dogaro da kai kawai inda VCL za ta koma ga fayiloli tare da haruffan sararin samaniya a cikin sunayensu.

Na yi tsokaci game da ainihin dabarun sarrafawa don ${VCL_FILE} kuma yayi ƙoƙarin canza jerin umarni, amma hakan bai kai ga komai ba. Duk abin ya yi aiki da tsabta a gare ni, kuma a cikin yanayin fara sabis ɗin, ya ba da kuskure.

Da alama kuskuren ba zai iya sake bugawa ba yayin gudanar da rubutun da hannu, yayin da kimanin mintuna 30 sun riga sun ƙare sau shida kuma, ƙari, babban aikin fifiko ya bayyana, yana tura sauran lokuta a gefe. Sauran satin an cika su da ayyuka iri-iri kuma an dan shafe su da magana akan sed da hira da dan takara. Kuskuren matsala a ciki varnishreload wanda ba a iya warwarewa ba ya ɓace a cikin yashi na lokaci.

Abin da ake kira sed-fu ... a zahiri ... sharar gida

Mako mai zuwa yana da rana ɗaya daidai gwargwado, don haka na yanke shawarar sake ɗaukar wannan tikitin. Ina fatan cewa a cikin kwakwalwata, wani tsari na asali duk tsawon wannan lokacin yana neman mafita ga wannan matsala, kuma a wannan lokacin zan fahimci abin da ke damun.

Tun lokacin da kawai canza lambar bai taimaka ba, kawai na yanke shawarar sake rubuta shi daga layin 116. A kowane hali, lambar data kasance wauta ce. Kuma babu shakka babu buƙatar amfani read.

Ana sake kallon kuskuren:
sh: echo: broken pipe - A cikin wannan umarnin, amsawar yana cikin wurare biyu, amma ina zargin cewa na farko shine mafi kusantar mai laifi (da kyau, ko aƙalla mai haɗin gwiwa). Awk baya kara kwarin gwiwa shima. Kuma idan da gaske ne awk | {read; echo} zane yana haifar da duk waɗannan matsalolin, me yasa ba maye gurbin shi ba? Wannan umarnin layi ɗaya baya amfani da duk fasalulluka na awk, har ma da wannan ƙarin read a cikin appendage.

Tun a makon jiya aka samu rahoto sedIna so in gwada sabbin dabarun da na samu kuma in sauƙaƙa echo | awk | { read; echo} cikin mafi fahimta echo | sed. Duk da yake wannan ba shakka ba shine hanya mafi kyau don kama kwaro ba, Ina tsammanin zan aƙalla gwada sed-fu na kuma watakila koya wani sabon abu game da matsalar. A kan hanyar, na tambayi abokin aikina, marubucin sed talk, ya taimake ni in fito da rubutun sed mai inganci.

Na sauke abun ciki varnishadm vcl.show -v "$VCL_NAME" zuwa fayil don haka zan iya mai da hankali kan rubuta rubutun sed ba tare da wata wahala ta sake farawa sabis ba.

Takaitaccen bayanin yadda za'a iya samun shigarwar sed a ciki GNU manual. A cikin sed kafofin, alamar n bayyananne a matsayin mai raba layi.

A lokuta da yawa, kuma tare da shawarar abokin aikina, mun rubuta rubutun sed wanda ya ba da sakamako iri ɗaya da duka ainihin layi na 116.

A ƙasa akwai samfurin fayil tare da bayanan shigarwa:

> cat vcl-example.vcl
Text
// VCL.SHOW 0 1578 file with 3 spaces.vcl
More text
// VCL.SHOW 0 1578 file.vcl
Even more text
// VCL.SHOW 0 1578 file with TWOspaces.vcl
Final text

Yana iya zama ba a bayyane daga bayanin da ke sama ba, amma muna sha'awar sharhin farko kawai // VCL.SHOW, kuma ana iya samun su da yawa a cikin bayanan shigarwa. Wannan shine dalilin da yasa asalin awk ya ƙare bayan wasan farko.

# шаг первый, вывести только строки с комментариями
# используя возможности sed, определяется символ-разделитель с помощью конструкции '#' вместо обычно используемого '/', за счёт этого не придётся экранировать косые в искомом комментарии
# определяется регулярное выражение “// VCL.SHOW”, для поиска строк с определенным шаблоном
# флаг -n позаботится о том, чтобы sed не выводил все входные данные, как он это делает по умолчанию (см. ссылку выше)
# -E позволяет использовать расширенные регулярные выражения
> cat vcl-processor-1.sed
#// VCL.SHOW#p
> sed -En -f vcl-processor-1.sed vcl-example.vcl
// VCL.SHOW 0 1578 file with 3 spaces.vcl
// VCL.SHOW 0 1578 file.vcl
// VCL.SHOW 0 1578 file with TWOspaces.vcl

# шаг второй, вывести только имя файла
# используя команду “substitute”, с группами внутри регулярных выражений, отображается только нужная группa
# и это делается только для совпадений, ранее описанного поиска
> cat vcl-processor-2.sed
#// VCL.SHOW# {
    s#.* [0-9]+ [0-9]+ (.*)$#1#
    p
}
> sed -En -f vcl-processor-2.sed vcl-example.vcl
file with 3 spaces.vcl
file.vcl
file with TWOspaces.vcl

# шаг третий, получить только первый из результатов
# как и в случае с awk, добавляется немедленное завершения после печати первого найденного совпадения
> cat vcl-processor-3.sed
#// VCL.SHOW# {
    s#.* [0-9]+ [0-9]+ (.*)$#1#
    p
    q
}
> sed -En -f vcl-processor-3.sed vcl-example.vcl
file with 3 spaces.vcl

# шаг четвертый, схлопнуть всё в однострочник, используя двоеточия для разделения команд
> sed -En -e '#// VCL.SHOW#{s#.* [0-9]+ [0-9]+ (.*)$#1#p;q;}' vcl-example.vcl
file with 3 spaces.vcl

Don haka abin da ke cikin rubutun varnishreload zai yi kama da haka:

VCL_FILE="$(echo "$VCL_SHOW" | sed -En '#// VCL.SHOW#{s#.*[0-9]+ [0-9]+ (.*)$#1#p;q;};')"

Za a iya taƙaita mahangar da ke sama kamar haka:
Idan kirtani ya dace da magana ta yau da kullun // VCL.SHOW, sannan a zari rubutun da ya ƙunshi lambobi biyu a cikin wannan layin, kuma a adana duk abin da ya rage bayan wannan aikin. Ba da ƙimar da aka adana kuma ƙare shirin.

Sauƙaƙan, ba haka ba?

Mun yi farin ciki da rubutun sed da gaskiyar cewa ya maye gurbin duk ainihin lambar. Duk gwaje-gwaje na sun ba da sakamakon da ake so, don haka na canza "varnishreload" akan uwar garken kuma na sake gudu systemctl reload varnish. Kuskure mai kazanta echo: write error: Broken pipe dariya muka sake yi. Wani siginan ƙyalli yana jiran a shigar da sabon umarni a cikin duhun duhun tashar...

source: www.habr.com

Add a comment