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


मेरे पास है एक Systemd के साथ आर्क लिनक्स प्रणाली और मैंने अपनी खुद की सेवा बनाई है। पर विन्यास सेवा /etc/systemd/system/myservice.service इस तरह दिखता है:

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

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


119
2017-08-01 19:43


मूल




जवाब:


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

वर्तमान ऐसा करने का सबसे अच्छा तरीका है दौड़ना 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

पूर्ण विवरण के लिए, फेडोरा के दस्तावेज को देखें एक systemd स्क्रिप्ट कैसे लिखें


143
2017-08-01 20:07



मुझे लगता है sysconfig पथ फेडोरा के लिए विशिष्ट है लेकिन सवाल आर्क लिनक्स के बारे में है। पलह का जवाब मुझे लगता है कि दिलचस्प है - Ludovic Kuty
/etc/sysconfig फेडोरा-विशिष्ट है। AFAIR आर्क लिनक्स कॉन्फ़िगरेशन फ़ाइलों को कहीं पैकेज-विशिष्ट के बजाय दबा रहा था /etc फेडोरा-विशिष्ट स्थान की बजाय। पसंद /etc/myservice.conf, हालांकि अतिरिक्त फ़ाइल का उपयोग करना सही तरीका नहीं लगता है। - Michał Górny
नहीं नहीं नहीं। / etc / sysconfig की सिफारिश नहीं की जाती है। यह डेबियन से / etc / default / * के साथ निराश है, क्योंकि वे व्यर्थ हैं, और नाम व्यर्थ हैं और केवल पीछे की संगतता कारणों के लिए समझ में आते हैं (सभी / etc सिस्टम की कॉन्फ़िगरेशन के बारे में है, न केवल / etc / sysconfig, और / etc / डिफ़ॉल्ट ओवरराइड के लिए है, डिफ़ॉल्ट नहीं)। केवल परिभाषाओं को यूनिट फ़ाइल में सीधे डालें, या यदि यह संभव नहीं है, तो एक enviornment फ़ाइल में जिसमें पैकेज विशिष्ट स्थान है (जैसे माइकल की टिप्पणी बताती है)। - zbyszek
@FrederickNord यह सिर्फ परिवर्तनीय = मूल्य जोड़े, जैसे कि DJANGO_SETTINGS_MODULE=project.settings, प्रति पंक्ति एक। - Michael Hampton♦
@MichaelHampton क्या आप कृपया "वर्तमान सर्वोत्तम तरीके" के लिए दस्तावेज़ लिंक जोड़ सकते हैं? - jb.


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

चूंकि यह आपकी स्थानीय इकाई है, सीमा काफी धुंधली है और कोई भी रास्ता काम करेगा। हालांकि, अगर आप इसे वितरित करना शुरू कर देते हैं और यह समाप्त हो जाएगा /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= इसके लिए।

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


67
2018-04-23 07:48



systemctl daemon-reload systemd पुनः लोड करने के लिए आदेश है - Dmitry Buzolin
EnvironmentFile= बेहतर है जब मूल्य पासवर्ड जैसे रहस्य हैं। देख मेरा जवाब ब्योरा हेतु। - Don Kirkby


http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - आपके पास दो विकल्प हैं (एक पहले से ही माइकल द्वारा इंगित किया गया है):

Environment=

तथा

EnvironmentFile=

34
2017-10-16 13:55





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

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

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

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

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

6
2017-07-23 13:31



यह कई कारणों से काम नहीं करेगा (जब तक कि यह "एक-शॉट" सेवा न हो, जो कि व्यर्थ है)। मैं काम करने के लिए निम्नलिखित प्राप्त करने में कामयाब रहे: /bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program'। -a यह सुनिश्चित करता है कि पर्यावरण उप-प्रक्रिया में निर्यात किया जाता है (जब तक आप सभी चरों को उपसर्ग करना नहीं चाहते हैं whatever साथ में export ) - Otheus
यह क्यों काम नहीं करेगा? इसे हमेशा पूरे आदेश को ट्रिगर करना चाहिए जिसमें स्क्रिप्ट निष्पादित करना शामिल है, है ना? - user1830432
शायद ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd इस मामले में थोड़ा बेहतर समाधान है। - kstep
@ ओथस: ग्रेट उत्तर, उस दिन बचाया गया जब मुझे टॉमकैट 8 यूनिट फ़ाइल बनाना पड़ा। - Daniel
सिस्टम सिस्टम सेवा में "बैश कमांड" को निष्पादित करने का एक तरीका है। यह लिंक देखें: coreos.com/os/docs/latest/... - Mark Lakata


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

यदि यही कारण है कि आप अपनी सेवा में एक पर्यावरण चर पारित करना चाहते हैं, ऐसा न करें उपयोग 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। बेशक, अपने सिस्टम पर जांचें।


6
2018-05-04 00:29