"Gade isit la," li di, lonje dwèt sou youn nan senbòl yo sou ekran an, "Mwen parye chapo wouj mwen an ke si nou ajoute isit la sa mwen sot voye ba ou," lonje dwèt sou yon lòt seksyon nan kòd, "erè a pa pral ankò. pral parèt."
Yon ti kras pè e fatige, mwen modifye ekspresyon sed nou t ap travay sou yon ti tan, sove fichye a epi kouri systemctl varnish reload
. Mesaj erè a disparèt...
"Imel yo mwen echanje ak kandida a," kòlèg mwen an te kontinye, pandan y ap souri li te grandi nan yon souri otantik lajwa, "Li toudenkou parèt sou mwen ke sa a se egzakteman menm pwoblèm nan!"
Ki jan tout bagay te kòmanse
Atik la sipoze yon konpreyansyon sou fason bash, awk, sed ak systemd travay. Konesans nan vèni pi pito, men se pa obligatwa.
Timestamps nan snippets yo te chanje.
Ekri ak
Tèks sa a se yon tradiksyon orijinal ki te pibliye an Angle de semèn de sa; tradiksyon
Solèy la klere nan fenèt panoramic yo nan yon lòt maten cho otòn, yon tas bwason ki fèk prepare ki gen anpil kafeyin repoze lwen klavye a, senfoni pi renmen ou nan son son nan kas ekoutè ou a, nwaye soti bruilement nan klavye mekanik, ak premye antre a. nan lis la nan tikè anreta sou tablo Kanban an jwe byen klere ak tit la fatal "Envestige varnishreload" sh: eko: I/O erè nan staging" (Envestige "varnishreload sh: eko: I/O erè" nan sèn). Lè li rive vèni, pa gen okenn plas pou erè, menm si yo pa lakòz okenn pwoblèm tankou nan ka sa a.
Pou moun ki pa abitye ak
Kòm tit la nan tikè a sijere, erè a te fèt sou youn nan sèvè yo sou sèn nan, e depi mwen te asire w ke wout la vèni sou sèn nan te travay byen, mwen sipoze ke sa a ta dwe yon ti erè. Se konsa, jis yon mesaj ki te fini nan yon kouran pwodiksyon deja fèmen. Mwen pran tikè a pou tèt mwen, ak tout konfyans mwen pral make li pare nan mwens pase 30 minit, tape tèt mwen sou do a pou netwaye tablo a nan yon lòt fatra ankò epi retounen nan zafè ki pi enpòtan.
Kraze nan yon miray a 200 km / h
Louvri dosye a varnishreload
, sou youn nan sèvè ki kouri Debian Stretch, mwen te wè yon script shell mwens pase 200 liy longè.
Èske w te pase nan script la, mwen pa t remake anyen ki ta ka lakòz pwoblèm lè w ap kouri li plizyè fwa dirèkteman nan tèminal la.
Apre yo tout, sa a se yon etap, menm si li kraze, pèsonn pa pral plenyen, byen ... pa twòp. Mwen kouri script la epi wè sa ki pral ekri nan tèminal la, men erè yo pa vizib ankò.
Yon koup plis kouri pou asire w ke mwen pa ka repwodui erè a san okenn efò adisyonèl, epi mwen kòmanse konnen ki jan yo chanje script sa a epi fè li toujou voye yon erè.
Èske script la ka depase STDOUT (itilize > &-
)? Oswa STDERR? Okenn nan sa yo te travay nan fen an.
Aparamman systemd yon jan kanmenm modifye anviwònman an demaraj, men ki jan, e poukisa?
Mwen ouvri vim epi edite varnishreload
, ajoute set -x
dwa anba shebang la, espere ke pwodiksyon an debug nan script la pral koule kèk limyè.
Fichye a korije, Se konsa, mwen rechaje vèni ak wè ke chanjman an konplètman kraze tout bagay... Echapman an se yon dezòd konplè, nan ki gen tòn kòd ki tankou C. Menm defile nan tèminal la pa ase pou jwenn kote li kòmanse. Mwen konplètman konfonn. Èske mòd debogaj ka afekte operasyon pwogram ki lanse nan yon script? Non, se yon istwa san sans. Pinèz nan kokiy la? Plizyè senaryo posib ap kouri nan tèt mwen tankou ravèt nan diferan direksyon. Gode bwason ki gen kafeyin la imedyatman vide, yon vwayaj rapid nan kwizin nan ranplir stock la ak ... ale nou ale. Mwen louvri script la epi pran yon gade pi pre nan shebang la: #!/bin/sh
.
/bin/sh
- sa a se jis yon lyen senbolik bash, kidonk script la entèprete nan mòd POSIX-konpatib, dwa? Se pa konsa! Koki default sou Debian se priz, e se egzakteman sa li sanble. /bin/sh
.
# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24 2017 /bin/sh -> dash
Kòm yon tès, mwen chanje shebang la #!/bin/bash
, efase set -x
epi eseye ankò. Finalman, sou rdemare ki vin apre nan vèni, yon erè tolerab parèt nan pwodiksyon an:
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
Liy 124, men li!
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 }
Men, kòm li vire soti, liy 124 se byen vid epi li pa gen okenn enterè. Mwen te kapab sèlman asime ke erè a te fèt kòm yon pati nan yon fisèl multiliy kòmanse sou liy 116.
Ki sa ki finalman ekri nan varyab la? VCL_FILE
kòm yon rezilta nan egzekite sub-koki ki anwo a?
Nan kòmansman an, li voye sa ki nan varyab la VLC_SHOW
, ki te kreye sou liy 115, swiv kòmandman an nan tiyo a. Lè sa a, sa k ap pase la?
Premyèman, li se itilize la varnishadm
, ki se yon pati nan pake enstalasyon vèni a, pou mete kanpe vèni san rekòmanse.
Sou-ekip vcl.show -v
itilize pou pwodiksyon tout konfigirasyon VCL espesifye nan ${VCL_NAME}
, pou STDOUT.
Pou montre aktyèl konfigirasyon VCL aktif la, ansanm ak plizyè vèsyon anvan konfigirasyon routage vèni ki toujou nan memwa, ou ka itilize kòmandman an. varnishadm vcl.list
, pwodiksyon an ki pral sanble ak youn ki anba a:
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
Valè varyab ${VCL_NAME}
enstale nan yon lòt pati nan script la varnishreload
nan non VCL aktif kounye a, si gen youn. Nan ka sa a li pral "reload_20190101_120000_12397".
Gwo, varyab ${VCL_SHOW}
gen konfigirasyon konplè pou vèni, klè pou kounye a. Koulye a, mwen finalman konprann poukisa pwodiksyon an priz se set -x
te tounen soti yo dwe tèlman kase - li enkli sa ki nan konfigirasyon an ki kapab lakòz.
Li enpòtan pou w konprann ke yon konfigirasyon VCL konplè ka souvan pave ansanm nan plizyè dosye. Kòmantè C-style yo itilize pou idantifye kote sèten fichye konfigirasyon yo te enkli nan lòt moun, e se sa ki liy sa a nan fragment kòd se tout sou.
Sentaks pou kòmantè ki dekri dosye enkli yo se nan fòma sa a:
// VCL.SHOW <NUM> <NUM> <FILENAME>
Nimewo yo pa enpòtan nan kontèks sa a, nou enterese nan non dosye a.
Ki sa ki finalman rive nan marekaj la nan kòmandman kòmanse sou liy 116?
Ann kalkile li.
Ekip la konsiste de kat pati:
- Senp
echo
, ki enprime valè varyab la${VCL_SHOW}
echo "$VCL_SHOW"
awk
, ki chèche yon liy (dosye) kote premye jaden an, apre yo fin kraze tèks la, se "//", ak dezyèm lan se "VCL.SHOW".
Awk pral ekri premye liy ki koresponn ak modèl sa yo epi li pral sispann travay imedyatman.awk '$1 == "//" && $2 == "VCL.SHOW" {print; exit}'
- Yon blòk kòd ki estoke valè jaden an senk varyab, separe pa espas. Senkyèm varyab FILE resevwa rès liy lan. Finalman, dènye eko ekri sa ki nan varyab la
${FILE}
.{ read -r DELIM VCL_SHOW INDEX SIZE FILE; echo "$FILE" }
- Depi tout etap 1 a 3 yo fèmen nan yon subshell, pwodiksyon valè a
$FILE
pral ekri nan yon varyabVCL_FILE
.
Jan kòmantè a sou liy 119 sijere, sa a sèvi sèlman objektif la nan jere seryezman ka kote VCL pral referans dosye ak espas nan non yo.
Mwen te fè kòmantè sou lojik pwosesis orijinal la pou ${VCL_FILE}
epi yo te eseye chanje sekans lòd la, men li pa t 'mennen nan anyen. Tout bagay te travay byen pou mwen, men lè mwen te kòmanse sèvis la li te bay yon erè.
Li sanble ke erè a se tou senpleman pa repwodiktif lè w ap kouri script la manyèlman, pandan y ap sipoze 30 minit yo te deja ekspire sis fwa epi, anplis, yon travay ki pi wo priyorite te parèt, pouse lòt zafè sou kote. Rès semèn nan te ranpli ak yon varyete travay epi li te sèlman yon ti kras dilye pa yon rapò sou sed ak yon entèvyou ak yon kandida. Pwoblèm ak erè nan varnishreload
te irevokabl pèdi nan sab yo nan tan.
Sa yo rele ou sed-fu... se aktyèlman... fatra
Semèn kap vini an mwen te gen yon jou san patipri gratis, kidonk mwen te deside atake tikè sa a ankò. Mwen te espere ke nan sèvo mwen an, kèk pwosesis background te ap chèche pou yon solisyon a pwoblèm sa a pandan tout tan sa a, ak fwa sa a mwen ta definitivman konprann sa k ap pase.
Depi tou senpleman chanje kòd la pa ede dènye fwa, mwen jis deside reekri li kòmanse nan liy 116. Nan nenpòt ka, kòd ki deja egziste a te estipid. Epi pa gen absoliman pa bezwen sèvi ak li read
.
Gade erè a ankò:
sh: echo: broken pipe
— eko parèt nan de kote nan lòd sa a, men mwen sispèk ke premye a se koupab ki gen plis chans (oswa omwen yon konplis). Awk pa enspire konfyans tou. Ak nan ka li vrèman se awk | {read; echo}
konsepsyon an mennen nan tout pwoblèm sa yo, poukisa pa ranplase li? Kòmand yon sèl-liy sa a pa sèvi ak tout karakteristik yo nan awk, e menm yon sèl siplemantè sa a read
an plis.
Depi semèn pase a te gen yon rapò sou sed
, Mwen te vle eseye konpetans mwen fèk akeri epi senplifye echo | awk | { read; echo}
nan yon pi konprann echo | sed
. Pandan ke sa a se definitivman pa apwòch ki pi bon yo idantifye ensèk la, mwen te panse mwen ta omwen eseye sed-fu mwen an e petèt aprann yon bagay nouvo sou pwoblèm nan. Sou wout la, mwen te mande kòlèg mwen an, otè diskou sed la, pou ede m vini ak yon script sed ki pi efikas.
Mwen lage kontni an varnishadm vcl.show -v "$VCL_NAME"
nan yon fichye, konsa mwen te kapab konsantre sou ekri script sed san okenn konplikasyon nan rdemare sèvis.
Ou ka jwenn yon deskripsyon kout sou egzakteman ki jan sed pwosesis opinyon ka jwenn nan n
espesifye klèman kòm yon separasyon liy.
Nan plizyè pas ak rekòmandasyon kòlèg mwen an, nou te ekri yon script sed ki te bay menm rezilta ak tout liy orijinal 116 la.
Anba a se yon echantiyon fichye ak done antre:
> 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
Sa a ka pa evidan nan deskripsyon ki anwo a, men nou sèlman enterese nan premye kòmantè a // VCL.SHOW
, epi ka gen plizyè nan yo nan done yo antre. Se poutèt sa awk orijinal la fini apre premye match la.
# шаг первый, вывести только строки с комментариями
# используя возможности 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
Se konsa, sa ki nan script varnishreload la pral gade yon bagay tankou sa a:
VCL_FILE="$(echo "$VCL_SHOW" | sed -En '#// VCL.SHOW#{s#.*[0-9]+ [0-9]+ (.*)$#1#p;q;};')"
Lojik ki anwo a ka eksprime yon ti tan jan sa a:
Si fisèl la matche ak yon ekspresyon regilye // VCL.SHOW
, Lè sa a, devore visye tèks ki gen ladan tou de nimewo nan liy sa a, epi sove tout sa ki rete apre operasyon sa a. Emèt valè ki estoke a epi fini pwogram nan.
Senp, pa vre?
Nou te kontan ak script sed ak lefèt ke li ranplase tout kòd orijinal la. Tout tès mwen yo te bay rezilta yo vle, se konsa mwen chanje "varnishreload" sou sèvè a epi kouri li ankò. systemctl reload varnish
. Move erè echo: write error: Broken pipe
ri nan figi nou ankò. Kursè a ap tann pou yon nouvo lòd yo dwe antre nan vid la fè nwa nan tèminal la ...
Sous: www.habr.com