Systemd सेवा में पर्यावरण चर कैसे सेट करें?


162

मेरे पास सिस्टम के साथ एक आर्क लिनक्स सिस्टम है और मैंने अपनी सेवा बनाई है। कॉन्फ़िगरेशन सेवा /etc/systemd/system/myservice.serviceइस तरह दिखती है:

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

अब मैं एक पर्यावरण चर सेट करना चाहता हूं /bin/myforegroundcmd। मैं उसको कैसे करू?

जवाबों:


196

समय बदल जाता है और इसलिए सर्वोत्तम अभ्यास करते हैं।

इसे करने का वर्तमान सबसे अच्छा तरीका है systemctl edit myservice, जो आपके लिए एक ओवरराइड फ़ाइल बनाएगा या आपको किसी मौजूदा को संपादित करने देगा।

सामान्य प्रतिष्ठानों में इस एक निर्देशिका का निर्माण करेगा /etc/systemd/system/myservice.service.d, और कहा कि निर्देशिका के अंदर एक फ़ाइल जिसका नाम में समाप्त होता है बनाने के .conf(आमतौर पर, override.conf), और इस फाइल में आप के लिए जोड़ सकते हैं या इकाई वितरण द्वारा भेज दिया के किसी भी भाग को ओवरराइड कर सकते हैं।

उदाहरण के लिए, एक फ़ाइल में /etc/systemd/system/myservice.service.d/myenv.conf:

[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"

यह भी ध्यान दें कि यदि निर्देशिका मौजूद है और खाली है, तो आपकी सेवा अक्षम हो जाएगी! यदि आप निर्देशिका में कुछ डालने का इरादा नहीं रखते हैं, तो सुनिश्चित करें कि यह मौजूद नहीं है।


संदर्भ के लिए, पुराना तरीका था:

ऐसा करने का अनुशंसित तरीका एक फ़ाइल बनाना है /etc/sysconfig/myserviceजिसमें आपके चर शामिल हैं, और फिर उन्हें लोड करें EnvironmentFile

संपूर्ण विवरण के लिए, सिस्टम स्क्रिप्ट लिखने के तरीके पर फेडोरा का प्रलेखन देखें ।


4
मुझे लगता है कि sysconfigपथ फेडोरा के लिए विशिष्ट है लेकिन सवाल आर्क लिनक्स के बारे में है। Paluh द्वारा जवाब मुझे लगता है कि और अधिक दिलचस्प है
लुडोविक Kuty

1
/etc/sysconfigफेडोरा-विशिष्ट है। एएफएआईआर आर्क लिनक्स /etcफेडोरा-विशिष्ट स्थान के बजाय संकुल-विशिष्ट को कॉन्फिगर करने के लिए जोर दे रहा था । जैसा /etc/myservice.confहै, हालांकि अतिरिक्त फ़ाइल का उपयोग यहाँ सही तरीके से नहीं लगता है।
माइकल गोरी

5
नहीं नहीं नहीं। / etc / sysconfig को पुनः शामिल नहीं किया गया है। डेबियन से / आदि / डिफ़ॉल्ट / * के साथ इसे हतोत्साहित किया जाता है, क्योंकि वे व्यर्थ हैं, और नाम व्यर्थ हैं और केवल पश्चगामी संगतता कारणों के लिए समझ में आता है (सभी / आदि सिस्टम के कॉन्फ़िगरेशन के बारे में है, न कि केवल / आदि / के लिए) sysconfig, और / etc / defaults ओवरराइड्स के लिए है, डिफ़ॉल्ट नहीं)। बस परिभाषाओं को सीधे यूनिट फ़ाइल में डालें, या यदि यह संभव नहीं है, तो एक एनवायरनमेंट फ़ाइल में पैकेज विशिष्ट स्थान है (जैसे कि मिचेल की टिप्पणी से पता चलता है)।
zbyszek

1
@FrederickNord यह केवल चर = मान जोड़े, जैसे DJANGO_SETTINGS_MODULE=project.settings, प्रति पंक्ति एक है।
माइकल हैम्पटन

1
@Michael Hampton क्या आप "वर्तमान सर्वोत्तम तरीके" के लिए दस्तावेज़ लिंक जोड़ सकते हैं?
जेबी

77

उत्तर इस बात पर निर्भर करता है कि क्या चर स्थिर माना जाता है (अर्थात, इकाई प्राप्त करने वाले उपयोगकर्ता द्वारा संशोधित नहीं होना चाहिए) या चर (उपयोगकर्ता द्वारा निर्धारित किया जाना चाहिए)।

चूंकि यह आपकी स्थानीय इकाई है, इसलिए सीमा काफी धुंधली है और किसी भी तरह से काम करेगी। हालांकि, अगर आपने इसे वितरित करना शुरू कर दिया और यह खत्म /usr/lib/systemd/systemहो जाएगा, तो यह महत्वपूर्ण हो जाएगा।

नियत मान

यदि मूल्य को प्रति उदाहरण बदलने की आवश्यकता नहीं है, तो पसंदीदा तरीका इसे Environment=सीधे, यूनिट फ़ाइल में रखा जाएगा:

[Unit]
Description=My Daemon

[Service]
Environment="FOO=bar baz"
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

इसका फायदा यह है कि वेरिएबल को यूनिट के साथ सिंगल फाइल में रखा जाता है। इसलिए, सिस्टम के बीच इकाई फ़ाइल को स्थानांतरित करना आसान है।

चर मान

हालाँकि, उपरोक्त समाधान अच्छी तरह से काम नहीं करता है जब स्थानीय स्तर पर पर्यावरण चर के मान को बदलने के लिए sysadmin माना जाता है। विशेष रूप से, यूनिट फ़ाइल अपडेट होने पर हर बार नए मूल्य को सेट करना होगा।

इस स्थिति के लिए, एक अतिरिक्त फ़ाइल का उपयोग किया जाना है। कैसे - आमतौर पर वितरण नीति पर निर्भर करता है।

एक विशेष रूप से दिलचस्प समाधान /etc/systemd/system/myservice.service.dनिर्देशिका का उपयोग करना है । अन्य समाधानों के विपरीत, यह निर्देशिका स्वयं systemd द्वारा समर्थित है और इसलिए बिना वितरण-विशिष्ट पथों के साथ आती है।

इस स्थिति में, आप एक ऐसी फ़ाइल रखते हैं /etc/systemd/system/myservice.service.d/local.confजो यूनिट फ़ाइल के लापता भागों को जोड़ती है:

[Service]
Environment="FOO=bar baz"

बाद में, सिस्टमड ने सेवा शुरू करते समय दो फाइलों को मर्ज कर दिया (याद रखें systemctl daemon-reloadकि उनमें से किसी को बदलने के बाद)। और चूंकि इस पथ का उपयोग सीधे systemd द्वारा किया जाता है, आप इसके EnvironmentFile=लिए उपयोग नहीं करते हैं ।

यदि मान केवल कुछ प्रभावित प्रणालियों पर बदला जाना है, तो आप दोनों समाधानों को जोड़ सकते हैं, यूनिट में सीधे डिफ़ॉल्ट और दूसरी फ़ाइल में एक स्थानीय ओवरराइड प्रदान कर सकते हैं।


systemctl daemon-reload
सिस्टमड

EnvironmentFile=जब मान पासवर्ड की तरह रहस्य होते हैं तो बेहतर होता है। देखें मेरा उत्तर जानकारी के लिए।
डॉन किर्कबी


17

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

यदि इसीलिए आप अपनी सेवा के लिए एक पर्यावरण चर पास करना चाहते हैं, तोEnvironment= यूनिट कॉन्फ़िगरेशन फ़ाइल में उपयोग करें । EnvironmentFile=किसी अन्य कॉन्फ़िगरेशन फ़ाइल का उपयोग करें और उसे इंगित करें जो केवल सेवा खाते (और रूट एक्सेस वाले उपयोगकर्ता) द्वारा पठनीय है।

यूनिट कॉन्फ़िगरेशन फ़ाइल का विवरण इस कमांड वाले किसी भी उपयोगकर्ता को दिखाई देता है:

systemctl show my_service

मैंने एक कॉन्फ़िगरेशन फ़ाइल यहां पर /etc/my_service/my_service.confरखी और अपने रहस्य दर्ज किए:

MY_SECRET=correcthorsebatterystaple

तब मेरी सेवा इकाई फ़ाइल में, मैंने उपयोग किया EnvironmentFile=:

[Unit]
Description=my_service

[Service]
ExecStart=/usr/bin/python /path/to/my_service.py
EnvironmentFile=/etc/my_service/my_service.conf
User=myservice

[Install]
WantedBy=multi-user.target

मैंने जाँच की कि ps auxeउन पर्यावरण चर को नहीं देख सकते हैं, और अन्य उपयोगकर्ताओं के लिए उपयोग नहीं है /proc/*/environ। अपने सिस्टम पर, निश्चित रूप से जाँच करें।


8

माइकल ने एक स्वच्छ समाधान दिया, लेकिन मैं स्क्रिप्ट से अद्यतन एनवी चर प्राप्त करना चाहता था। दुर्भाग्य से सिस्टम यूनिट फ़ाइल में बैश कमांड निष्पादित करना संभव नहीं है। सौभाग्य से आप ExecStart के अंदर बैश ट्रिगर कर सकते हैं:

http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&sect=5

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

हमारे मामले में उदाहरण तब है:

[Service]
ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"

7
यह कई कारणों से काम नहीं करेगा (जब तक कि यह "वन-शॉट" सेवा नहीं है, जो कि व्यर्थ है)। मैं निम्नलिखित काम करने में कामयाब रहा /bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program':। यह -aसुनिश्चित करता है कि पर्यावरण को उप-प्रक्रिया में निर्यात किया जाता है (जब तक कि आप सभी whateverexport
प्रकारों के

यह काम क्यों नहीं करेगा? यह हमेशा पूरी कमांड को ट्रिगर करना चाहिए जिसमें स्क्रिप्ट निष्पादित करना शामिल है, यह नहीं है?
user1830432

शायद ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmdइस मामले में थोड़ा बेहतर समाधान है।
kstep

@ ओटस: महान जवाब, दिन के हिसाब से जब मुझे टॉमकैट 8 यूनिट फाइल बनानी थी।
डैनियल

1
वहाँ "एक systemd सेवा फ़ाइल" में bash कमांड निष्पादित करने का एक तरीका है। इस लिंक को देखें: coreos.com/os/docs/latest/…
Mark Lakata
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.