ExecStart-ը shell չէ. VPN-ի օժանդակ միավորի ուղղում
ExecStart-ը գործարկում է ծրագիր արգումենտներով, ոչ թե shell-ի խողովակաշար։ Օգտագործեք բացահայտ ինտերպրետատոր կամ իրական սկրիպտ, ապա ստուգեք միավորը և կարդացեք մատյանը։
Պատճենեք աշխատող հրամանի տողը ExecStart-ի մեջ, վերաբեռնեք, և միավորը ձախողվում է կամ լուռ դուրս գալիս՝ արգումենտները որպես ֆայլերի անուններ մեկնաբանելով։ systemd-ում ոչինչ կոտրված չէ։ ExecStart-ը արգումենտների ցանկ է, ոչ shell, ուստի խողովակները, վերահասցեավորումը և պայմանները կորցնում են իմաստը այն պահին, երբ լքում են ձեր տերմինալը։ Որոշեք, թե որտեղ պետք է լինի shell-ը, ապա գրեք միավոր, որը հստակ ասում է, թե ինչ պետք է կատարվի։
Ինչու ExecStart-ի խողովակաշարը ոչինչ չի անում
Երբ հրամանը մուտքագրվում է տերմինալում, shell-ը նախ վերլուծում է այն։ Այն կառուցում է խողովակաշար, բացում ֆայլեր վերահասցեավորման համար և ընդլայնում փոփոխականները մինչև որևէ ծրագրի մեկնարկը։ systemd-ը ոչինչ չի անում դրանից. այն բաժանում է ExecStart-ը իր կանոններով և կատարում ստացված ծրագիրը այդ արգումենտներով։ Այդ պատճառով > գալիս է որպես բառացի արգումենտ, իսկ | հանձնվում է ծրագրին՝ երկու պրոցես միացնելու փոխարեն։ Միավորը սխալ չի վարվում. շարահյուսությունը այլ բան էր նշանակում։
Դա դիտավորյալ է, ոչ անփութություն, որովհետև արգումենտների կանխատեսելի մշակումն է միավորները ստուգելի դարձնում։ Դա զարմացնում է միայն նրանց, ովքեր ենթադրում են, որ shell կա։
Գրեք միավոր, որը հստակ ասում է, թե ինչ է գործարկվում
Սկսեք փոքր միավորից, որի նպատակը երևում է մատյանում, որպեսզի վերլուծման խնդիրները առանձին մնան թունելի խնդիրներից։ Այս մեկը միայն հաղորդում է բինար ֆայլի տարբերակը։
[Unit]
Description=Report the installed OpenVPN version
[Service]
Type=oneshot
ExecStart=/usr/sbin/openvpn --version
StandardOutput=journal
StandardError=journalՈւղին տեղապահ է, ուստի փոխարինեք այն իրականում տեղադրված բինարով։ Type=oneshot հարմար է հրամանի համար, որը աշխատում է մինչև ավարտ, իսկ մատյանի կարգավորումները դնում են դրա ելքը այնտեղ, որտեղ կարող եք կարդալ առանց տերմինալի։ Տեղադրման բաժին դիտավորյալ չկա, ուստի միավորը կանչվում է ձեռքով՝ բեռնման պահին միացնելու փոխարեն։ Ստուգեք ֆայլը նախքան գործարկելը, որովհետև հրահանգի անվան սխալը տարբեր կերպ է ձախողվում, քան ուղու սխալը։
systemd-analyze verify /etc/systemd/system/openvpn-version.service
systemctl start openvpn-version.serviceShell-ի տրամաբանությունը պահեք սկրիպտում
Երբ օժանդակը իսկապես պայմանական տրամաբանության կարիք ունի, դրեք այդ տրամաբանությունը սկրիպտի մեջ և կանչեք այն բացահայտ։ Սկրիպտին պետք են ինտերպրետատորի տող, կատարման թույլտվություն և ելքի կոդեր, որոնք ծառայությունը կարող է հաղորդել։ /bin/sh -c գործարկելը մեջբերված հրամանով աշխատում է, բայց թաքցնում է մեջբերման կանոնները միավորի ներսում և դժվարացնում վերանայումը։ Անվանված սկրիպտը կարելի է ձեռքով փորձարկել և ավելի ուշ փոխարինել՝ առանց միավորը խմբագրելու։ Մի հենվեք ինտերակտիվ օգտատիրոջ shell-ի պրոֆիլի վրա, որովհետև ծառայությունը սկսվում է իր սեփական միջավայրով։
Սահմանեք WorkingDirectory, երբ հարաբերական ուղիները կարևոր են, և միջավայրը փոխանցեք միավորի աջակցվող հրահանգներով՝ տերմինալում արտահանելու փոխարեն։ Գաղտնիքները պատկանում են պաշտպանված ֆայլերին կամ հավատարմագրերին, ոչ թե արգումենտների ցանկերին, որոնք մատյանը կարող է գրանցել։
Ստուգեք այն միավորը, որն իրականում գոյություն ունի
drop-in ֆայլերը փոխում են վարքը՝ չդիպչելով այն ֆայլին, որը հիշում եք, որ խմբագրել եք։ Կարդացեք, թե ինչ բեռնեց կառավարիչը և ինչ հաղորդեց վերջին գործարկումը։
systemctl cat vpn-helper.service
journalctl -u vpn-helper.service -n 20 --no-pagerՄիավորի արտապատկերը ներառում է drop-in ֆայլերը բեռնման հերթականությամբ, և սովորաբար հենց այնտեղից է գալիս անսպասելի ExecStart-ը։ Ցանկացած փոփոխությունից հետո վերաբեռնեք կառավարիչը և համոզվեք, որ նոր սահմանումը հենց այն է, ինչ տպում է systemctl cat-ը։ Մատյանը ցույց է տալիս ճշգրիտ հրամանի տողը և ելքի կարգավիճակը, ինչը բաժանում է արգումենտի խնդիրը բացակայող բինարից կամ թույլտվության սխալից։ Ապա որոշեք՝ օժանդակը պատկանում է գոյություն ունեցող VPN-ի կենսացիկլին, թե պետք է մնա ձեռքով ախտորոշում, որովհետև երկրորդ ֆոնային թունելի պրոցեսը ստեղծում է մրցակից տեր։
Միավորը, որը պահանջով տպում է ճիշտ ելքը, լավ առաջին նշաձող է։ Այն դեռ թունել չէ և չպետք է ձևացնի, թե այդպիսին է։