नेटवर्किंग शुरू होने के बाद निष्पादित करने के लिए एक स्क्रिप्ट का कारण?


102

मैं सिस्टमड के लिए अपेक्षाकृत नया हूं और इसकी वास्तुकला सीख रहा हूं।

अभी, मैं यह जानने की कोशिश कर रहा हूं कि एक कस्टम शेल स्क्रिप्ट को चलाने का कारण कैसे बन सकता है। नेटवर्किंग स्क्रिप्ट के शुरू होने के बाद इस स्क्रिप्ट को चलाने की आवश्यकता है ।

मैं आर्च चला रहा हूं, सिस्टमड के साथ-साथ netctl का उपयोग कर रहा हूं।

परीक्षण करने के लिए, मैंने एक साधारण स्क्रिप्ट लिखी जो कि बस निष्पादित होती है ip addr list > /tmp/ip.txt। मैंने इस स्क्रिप्ट के लिए निम्न सेवा फ़ाइल बनाई है।

(/etc/systemd/system/test.service)
[Unit]
Description=test service

[Service]
ExecStart=/root/test.script

[Install]
WantedBy=multi-user.target

मैंने तब स्क्रिप्ट को सक्षम किया,

systemctl enable test

पुनरारंभ करने पर, स्क्रिप्ट वास्तव में चलती है, लेकिन यह नेटवर्क शुरू होने से पहले चलती है। दूसरे शब्दों में, ip.txtप्राथमिक इंटरफ़ेस को निर्दिष्ट IPv4 पता प्रदर्शित करने में आउटपुट । जब तक मैं लॉगिन करता हूं, तब तक आईपीवी 4 पता वास्तव में सौंपा गया है और नेटवर्किंग चालू है।

मैं अनुमान लगा रहा हूं कि मैं उस बिंदु को बदल सकता हूं जिस पर WantedByपैरामीटर के साथ खिलवाड़ करके स्क्रिप्ट चलती है , लेकिन मुझे यकीन नहीं है कि यह कैसे करना है।

क्या कोई मुझे सही दिशा बतला सकता है?

जवाबों:


126

सिस्टमड नेटवर्क कॉन्फ़िगरेशन निर्भरता पर

सिस्टमड की यूनिट ऑर्डरिंग को प्रभावित करना बहुत आसान है। दूसरी ओर आपको इस बात से सावधान रहने की आवश्यकता है कि एक पूर्ण इकाई क्या गारंटी देती है।

अपनी सेवा को कॉन्फ़िगर करें

वर्तमान प्रणालियों पर, आदेश देने के बाद network.targetबस गारंटी दी जाती है कि नेटवर्क सेवा शुरू की गई है, न कि कुछ वास्तविक कॉन्फ़िगरेशन। आपको network-online.targetइसे प्राप्त करने के लिए ऑर्डर करने और इसे खींचने की आवश्यकता है।

[Unit]
Wants=network-online.target
After=network-online.target

पुराने सिस्टम के साथ संगतता के लिए, आपको network.target के बाद भी ऑर्डर करना पड़ सकता है।

[Unit]
Wants=network-online.target
After=network.target network-online.target

यह आपकी सेवा की इकाई फ़ाइल के लिए और सिस्टमड के लिए है।

सॉफ्टवेयर के वर्तमान संस्करणों में कार्यान्वयन

अब आपको यह सुनिश्चित करने की आवश्यकता है कि network-online.targetअपेक्षा के अनुसार काम करता है (या जिसे आप कम से कम उपयोग कर सकते हैं network.target)।

NetworkManager का वर्तमान संस्करण प्रदान करता है NetworkManager-wait-online.serviceजो network-online.targetआपकी सेवा के द्वारा और इस तरह से खींचा जाता है । यह विशेष सेवा यह सुनिश्चित करती है कि आपकी सेवा तब तक प्रतीक्षा करेगी जब तक कि कॉन्फ़िगर किए गए सभी कनेक्शन स्वचालित रूप से सफल, विफल या समय समाप्त न होने लगें।

सिस्टमड-नेटवर्कड का वर्तमान संस्करण आपकी सेवा को तब तक अवरुद्ध करता है जब तक कि सभी डिवाइस अनुरोध के अनुसार कॉन्फ़िगर न हो जाएं। यह आसान है कि यह वर्तमान में केवल उन कॉन्फ़िगरेशन का समर्थन करता है जो बूट समय पर लागू होते हैं (विशेष रूप से `systemd-networkd.service का स्टार्टअप समय)।

पूर्णता के लिए, /etc/init.d/networkफेडोरा में सेवा, सिस्टमड, ब्लॉकों के वर्तमान संस्करणों network.targetऔर इस प्रकार अप्रत्यक्ष रूप से ब्लॉक network-online.targetऔर आपकी सेवा के रूप में व्याख्या की गई है । यह स्क्रिप्ट आधारित कार्यान्वयन का एक उदाहरण है।

यदि आपका कार्यान्वयन, चाहे डेमन बेस्ड या स्क्रिप्ट आधारित हो, ऊपर नेटवर्क प्रबंधन सेवाओं में से एक के रूप में व्यवहार करता है, तो यह आपकी सेवा के शुरू होने में देरी करेगा जब तक कि नेटवर्क कॉन्फ़िगरेशन या तो सफलतापूर्वक पूरा नहीं हो जाता है, एक अच्छे कारण के लिए विफल हो जाता है, या एक उचित समय के बाद समाप्त हो जाता है। पूरा करने के लिए फ्रेम।

आप जांच सकते हैं कि क्या netctl उसी तरह काम करता है और यह जानकारी इस उत्तर के लिए एक मूल्यवान अतिरिक्त होगी।

सॉफ्टवेयर के पुराने संस्करणों में कार्यान्वयन

मुझे नहीं लगता कि आपको सिस्टमड का एक पुराना संस्करण दिखाई देगा जहां यह अच्छी तरह से काम नहीं करेगा। लेकिन आप जांच सकते हैं कि कम से कम network-online.targetमौजूद है और इसके बाद आदेश दिया जाता है network.target

पहले NetworkManager ने केवल गारंटी दी थी कि कम से कम एक कनेक्शन लागू होगा। और यहां तक ​​कि काम करने के लिए, आपको NetworkManager-wait-online.serviceस्पष्ट रूप से सक्षम करना होगा । यह लंबे समय से फेडोरा में तय किया गया था लेकिन हाल ही में अपस्ट्रीम में लागू किया गया था।

systemctl enable NetworkManager-wait-online.service

Network.target और network-online.target कार्यान्वयन पर नोट्स

आपको कभी भी अपने सॉफ़्टवेयर को NetworkManager.serviceया NetworkManager-wait-online.serviceकिसी अन्य विशिष्ट सेवाओं पर निर्भर रहने की आवश्यकता नहीं होनी चाहिए । इसके बजाय, सभी नेटवर्क प्रबंधन सेवाओं को पहले network.targetऔर वैकल्पिक रूप से खुद को आदेश देना चाहिए network-online.target

एक सरल स्क्रिप्ट आधारित नेटवर्क प्रबंधन सेवा को बाहर निकलने से पहले नेटवर्क कॉन्फ़िगरेशन को समाप्त करना चाहिए network.targetऔर इससे पहले कि अप्रत्यक्ष रूप से पहले खुद को आदेश देना चाहिए network-online.target

[Unit]
Before=network.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

एक डेमन बेस्ड नेटवर्क मैनेजमेंट सर्विस को इससे पहले network.targetभी खुद ऑर्डर करना चाहिए , हालांकि यह बहुत उपयोगी नहीं है।

[Unit]
Before=network.target

[Service]
Type=simple
ExecStart=...

एक सेवा जो डेमॉन के खत्म होने का इंतजार करती है उसे विशिष्ट सेवा के बाद और उससे पहले खुद को ऑर्डर करना चाहिए network-online.target। यह Requisiteडेमॉन सेवा पर उपयोग करना चाहिए ताकि संबंधित नेटवर्क प्रबंधन सेवा का उपयोग नहीं होने पर यह तुरंत विफल हो जाए।

[Unit]
Requisite=...
After=...
Before=network-online.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

पैकेज को wantsनिर्देशिका में प्रतीक्षा सेवा के लिए एक सिमलिंक स्थापित करना चाहिए network-online.targetताकि यह उन सेवाओं द्वारा खींचा जाए जो कॉन्फ़िगर किए गए नेटवर्क के लिए इंतजार करना चाहते हैं।

ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/

संबंधित दस्तावेज

अंतिम नोट्स

मुझे आशा है कि मैंने न केवल आपके द्वारा पूछे गए समय पर आपके प्रश्न का उत्तर देने में मदद की, बल्कि अपस्ट्रीम और लिनक्स वितरण में स्थिति को बेहतर बनाने में भी योगदान दिया, ताकि मैं अब मूल उत्तर लिखने के समय की तुलना में बेहतर उत्तर दे सकूं ।


क्या आपका मतलब है कि "सभी कनेक्शनों के स्वचालित रूप से सफल होने के लिए कॉन्फ़िगर किए जाने तक प्रतीक्षा करें" द्वारा ऑटोकनेक्ट विकल्प? क्या मैं इसका लाभ तब उठा सकता हूं जब मैंने नो-ऑटो-डिफॉल्ट = * सेट किया है, लेकिन मेरे किसी एक कनेक्शन पर मेरा ऑटो-कनेक्ट = हां है? और आखिरी सवाल - मुझे समझ नहीं आ रहा है - nm-online और मैन्युअल पेज का -wait-for-स्टार्टअप विकल्प ज्यादा मदद नहीं करता है। इस राइटअप के लिए धन्यवाद, बहुत सराहना की गई!
११:३३

जहाँ तक मुझे पता है, एनएम-ऑनलाइन के बारे में परवाह नहीं है no-auto-default, केवल auto। क्या आपके पास कोई विशिष्ट प्रश्न है? मेरी राय में एनएम-ऑनलाइन मैनपेज में स्पष्ट रूप से कहा गया है कि इसके साथ -sसभी ऑटो कनेक्शनों के लिए प्रतीक्षा करने का प्रयास किया गया है, अर्थात कनेक्ट या असफल।
पावेल Paमरदा

एक घंटे के लिए इस बकवास के साथ खिलवाड़ करने के बाद, मुझे समाधान मिला: apt-get install sysv-init। :-) जटिलता प्रणाली कुछ शेल स्क्रिप्ट के प्रतिस्थापन के रूप में जुड़ती है, जो दिमाग से टकरा रही है।
किसी ने

@ मुझे लगता है कि initscripts इस मामले में एक जवाब नहीं है डर है। यदि आप NetworkManager या किसी अन्य डायनेमिक कॉन्फ़िगरेशन टूल का उपयोग कर रहे हैं, तो initscripts पूरी तरह से कॉन्फ़िगर किए गए नेटवर्क के बाद खुद को ऑर्डर नहीं कर सकते। आप एक सीमित गतिशील विन्यास का उपयोग करके /etc/init.d/networkया समान प्राप्त कर सकते हैं लेकिन यह सार्वभौमिक रूप से काम नहीं करता है।
पावेल Paमेरदा

@Pavel daimerda Init क्रमिक रूप से कार्यान्वित होता है, और एक उचित init स्क्रिप्ट तब तक वापस नहीं आएगी जब तक कि यह पूरा नहीं कर लेती है कि बाद की स्क्रिप्ट पर भरोसा करने की आवश्यकता है। नेटवर्किंग के लिए जिसका अर्थ होगा सभी लागू एडेप्टर अप और रेडी। जब तक यह सिर्फ भाग्यशाली समय नहीं था, एनएम उस संदर्भ में अच्छा व्यवहार करता है। पाठ्यक्रम की वास्तविक समस्या मौजूदा सरल और आजमाए गए और परीक्षण किए गए संरचनाओं पर निर्माण के बजाय एनएम के नेटवर्क हैंडलिंग को सुदृढ़ करना है। डेस्कटॉप लोगों को लगता है कि जटिलता के खतरों की कोई अवधारणा नहीं है। ;-)
कोई

9

आप एक सेवा को परिभाषित करने के लिए अनुभाग Afterमें उपयोग कर सकते हैं [Unit]जिसे आपकी सेवा शुरू होने से पहले शुरू किया जाना चाहिए। उदाहरण के लिए यदि आप NetworkManager का उपयोग कर रहे हैं, तो आप NetworkManager शुरू होने के बाद अपनी सेवा शुरू कर सकते हैं।

[Unit]
Description=test service
After=NetworkManager.service

BindsToयहाँ ऐसा उचित नहीं है क्योंकि सेवा एक बार बंद होने वाली घटना है और न कि एक निरंतर सेवा (जब तक कि इसमें ExecStopनेटवर्किंग शामिल नहीं हो जाती है जब नेटवर्किंग नीचे जाती है)।
गोल्डीलॉक्स

निकाल दिया गयाBindsTo
फूप्स

आप बदलने के लिए कुछ जोड़ सकते हैं BindsTo, हालांकि, उदाहरण के लिए Requires, यदि आप केवल सेवा चलाना चाहते हैं तो NetworkManager करता है। Afterवास्तव में ऐसा नहीं करता है - इसका मतलब सिर्फ इतना है कि यदि एनएम भी चल रहा है, तो बाद में इसे चलाएं। यदि NM चलाया नहीं जा रहा है, तो सेवा एक मनमाने स्थान पर चलाई जाएगी।
गोल्डीलॉक्स

4
After = network.target After = NetworkManager.service से बेहतर है क्योंकि यह अधिक सामान्य है।
पावेल Paमेरदा

7
ध्यान दें कि निर्दिष्ट करने After=fooसे इकाई शुरू होने का कारण नहीं होगा fooयदि यह पहले से ही शुरू नहीं हुआ है, यह केवल सिस्टम को बताएगा कि यदि दोनों एक ही समय में शुरू होते हैं तो इकाइयों को कैसे ऑर्डर करना है । दोनों का उपयोग करने के After=fooसाथ Wants=fooया Requires=fooखींचने का प्रभाव होगा fooअगर यह शुरू नहीं हुआ है, और सिस्टमड को सही ढंग से इकाइयों का आदेश दे रहा है।
एमिल लुंडबर्ग

8

यदि आपकी सेवा एक सर्वर प्रदान करती है, जो किसी को इसे कनेक्ट करने के लिए निष्क्रिय रूप से प्रतीक्षा कर सकता है, तो इसका उपयोग करें:

[Unit]
After=network.target

आपकी सेवा को वाइल्डकार्ड इंटरफ़ेस पर बाँधना चाहिए। यदि यह सॉकेट सक्रियण (अनुशंसित) का उपयोग करता है, या यदि यह केवल स्थानीय है, तो आप नेटवर्क लक्ष्य को पूरी तरह से अनदेखा कर सकते हैं।

यदि आपकी सेवा एक ग्राहक के रूप में कार्य करती है, या सहकर्मी से सहकर्मी है, तो यह अधिक उपयुक्त है:

[Unit]
After=network-online.target
Requires=network-online.target

सिस्टम 213 से पहले , network-online.target को वर्कअवे की आवश्यकता होती है Pavel का उल्लेख किया गया है (आपको मैन्युअल रूप से उस सेवा को सक्षम करने की आवश्यकता है जो नेटवर्क के उठने का इंतजार करेगी)। सिस्टमड 213 के रूप में यह डिफ़ॉल्ट रूप से किया जाता है। systemd-networkd-wait-onlineगैर-लूपबैक इंटरफ़ेस पर कॉन्फ़िगर किए जाने के लिए कम से कम एक पते (या तो रूट करने योग्य या लिंक-स्थानीय) की प्रतीक्षा करेगा।

Systemd-networkd, NetworkManager या समकक्ष को कॉन्फ़िगर करना एक स्वतंत्र कार्य है। डीएचसीपी (आईपीवी 4 के लिए) और एनडीपी (आईपीवी 6 के लिए) बॉक्स से बाहर काम करते हैं, लेकिन आपको उन्हें कॉन्फ़िगर करना चाहिए ताकि "नेटवर्क अप हो" की आपकी सटीक परिभाषा ट्रिगर हो network-online.target

प्रलेखन:


बस जिज्ञासु क्यों एक नया जवाब और न केवल मौजूदा और (उम्मीद है) अच्छी तरह से संरचित जवाब के लिए छोटे सुधार।
पावेल Paमिरदा

पहले दो दस्तावेज़ लिंक वर्तमान में ख़राब हैं।
पीटर हैनसेन

क्यों चाहते हैं के बजाय उपयोग की आवश्यकता है?
कार्ल मॉरिसन

4

मैं अनुमान लगा रहा हूं कि मैं उस बिंदु को बदल सकता हूं जिस पर स्क्रिप्ट वांटेडबी पैरामीटर के साथ गड़बड़ करके चलती है

आप जो चाहते हैं उसका विपरीत प्रभाव पड़ेगा। से man systemd.unit:

WantedBy =, RequiredBy =

[...] एक प्रतीकात्मक लिंक .wants / या .requires / निर्देशिका में से प्रत्येक को सूचीबद्ध इकाइयों द्वारा बनाया जाता है जब यह इकाई systemctl सक्षम द्वारा स्थापित की जाती है। इस प्रकार की एक निर्भरता चाहता = या = जोड़ा जाता है आवश्यक है कि प्रभाव पड़ता है से सूचीबद्ध इकाई को चालू इकाई

इसके आधार पर, हम देख सकते हैं कि उचित इकाई विकल्प "चाहता है" या "आवश्यकता है"; उन लोगों के विवरण के आधार पर, "आवश्यकता" संभवत: सही है, "बाद" के अतिरिक्त के साथ न केवल यह सुनिश्चित करने के लिए कि नेटवर्किंग सेवा को चलाया जाए, लेकिन यह इस इकाई से पहले चलता है।

इकाई विकल्पों में से कोई भी, AFAIK, वह शर्त शामिल नहीं कर सकता है जो एक आरंभिक अनुलाभ पूरा हो गया है, या एक निश्चित बिंदु पर पहुंच गया है (नेटवर्किंग संभवतः एक डेमन सेवा है), केवल यह कि यह पहले शुरू होता है । इसे ध्यान में रखते हुए, आप अपनी स्क्रिप्ट बनाना Type=forkingऔर स्वस्थ देरी (30 सेकंड कहना) में फेंक सकते हैं , या किसी प्रकार का निकास-सहित-सफलता लूप में देरी कर सकते हैं, यह सुनिश्चित करने के लिए कि आपके पास पहले डीएचसीपी पट्टा है।


1
न तो वांटेडबी और न ही आवश्यक आदेश को प्रभावित करते हैं।
पावेल Paमरदा

1
@ Pavel theyimerda: यहां किसी ने भी दावा नहीं किया कि उन्होंने ऐसा किया। ऑर्डर करना इसीलिए मैंने स्पष्ट Afterरूप से Requires"न केवल यह सुनिश्चित करने के लिए उल्लेख किया कि नेटवर्किंग सेवा चलाई जाए, बल्कि यह कि इस इकाई से पहले चला जाए"।
गोल्डीलॉक्स

1
हां, Afterएक साथ Wantsया Requiresउस तरह से काम करता है । दूसरी ओर स्पष्ट विलंब निर्भरता आधारित साधनों में एक बुरी आदत है, खासकर जब सिस्टमडॉक प्रलेखन द्वारा निर्दिष्ट नेटवर्क को कॉन्फ़िगर किए जाने तक प्रतीक्षा करने का एक स्पष्ट तरीका है, इसलिए मुझे डाउनवोट पर जोर देना होगा।
पावेल Paमिरदा

3

अपनी सेवा से पहले क्या शुरू किया जाना चाहिए यह निर्दिष्ट करने के Afterलिए [Unit]अनुभाग में उपयोग करें । (पिछले उत्तर का यह बहुत सही है।)

नेटवर्क के उठने के बाद अपनी सेवा शुरू करने के लिए, नेटवर्क लक्ष्य का उपयोग करें, जिसे लागू करना चाहिए कि क्या आप NetworkManager, Arch में conf.d / netctl सिस्टम का उपयोग करते हैं, या कुछ अन्य सेवा जो सिस्टमड के बारे में जानते हैं।

[Unit]
#.....
After=network.target

एक संक्षिप्त लुक इस बात की पुष्टि करेगा कि आपके सिस्टम की हर दूसरी सेवा जो नेटवर्क कनेक्टिविटी पर निर्भर है, में यह निर्देश है।

यह किसी भी वितरण के लिए पोर्टेबल है जो सिस्टमड का उपयोग करता है। आपकी यूनिट फ़ाइल आर्क, फेडोरा, आरएचईएल 7, डेबियन के भविष्य के संस्करणों के लिए समान होगी ...


ऐसी सेवाएँ जो नेटवर्क कनेक्शन शुरू करती हैं , जैसे कि आर्क की स्क्रिप्ट या आपकी अपनी, उन्हें अपनी यूनिट फाइलों में निर्दिष्ट करना चाहिए ।

[Unit]
Wants=network.target
Before=network.target

मैं पूरी तरह से इस Wantsभाग को पसंद नहीं करता क्योंकि इसका अन्य पैकेजों पर दुष्प्रभाव है। कृपया मेरे उत्तर को देखें।
पावेल Paमरदा

बस एहसास हुआ कि Wantsयहाँ पर network.targetएक अच्छा विचार है।
पावेल Paमेरदा

आप वास्तव में network-online.target का उपयोग करना चाहते हैं। रेफरी
एडवर्ड टोर्वाल्ड

1

मैं इस लेख में एक बिंदु जोड़ना चाहता था। वर्तमान में (गर्मी 2015) RHEL7 / CentOS 7 में, नेटवर्क-online.target IPv6 नेटवर्किंग के शुरू होने से पहले गलत तरीके से सेट किया गया है, इसलिए डेमन

Wants=network-online.target
After=network-online.target

उनकी सेवा परिभाषा में जो IPv6 पतों को भी स्पष्ट रूप से बाँधते हैं, संभवतः IPv6 उठने और चलने से पहले शुरू हो जाएंगे, जिससे वे विफल हो जाएंगे।


मुझे लगता है कि यह केवल कर्नेल आधारित IPv6 स्वचालित कॉन्फ़िगरेशन के साथ मामला है जो वैसे भी त्रुटिपूर्ण है। यदि आप IPv6 के बाद ठीक से ऑर्डर करना चाहते हैं, तो आपको निश्चित रूप से इसके बजाय NetworkManager का उपयोग करना चाहिए /etc/init.d/network। यदि आपको एनएम के साथ भी यही मुद्दा मिलता है, तो यह एक अच्छा कारण होगा कि आप एक सुविधा अनुरोध दर्ज करें। मैंने आरएचईएल / सेंटोस के साथ जांच नहीं की है, यदि आप रुचि रखते हैं तो मैं विवरण के साथ आपकी मदद कर सकता हूं।
पावेल Paमेरदा

0
[Unit]
After=systemd-networkd.service

मेरे लिये कार्य करता है।


यकीन नहीं होता कि यह कुछ विशेष मामलों में काम करता है लेकिन यह कुछ कारणों से गलत है। उनमें से एक यह है कि networkdअपनी खुद की / प्रतीक्षा-ऑनलाइन / सेवा प्रदान करता है। अंदर खींचने और ऑर्डर करने के बाद network-online.targetकिसी भी सेवा के साथ जाने का सही तरीका है जो उस का समर्थन करता है।
पावेल Paमेरदा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.