40_custom फ़ाइल में "निष्पादित टेल-एन +3 $ 0" लाइन का अर्थ


17

मैं grub config फ़ाइलों को समझने की कोशिश कर रहा हूँ। इसलिए, इस प्रक्रिया के दौरान मैं फ़ाइल /etc/grub.d/40_custom के साथ आया । मेरी फ़ाइल में निम्नलिखित पंक्तियाँ हैं:

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry "Windows 10" --class windows --class os {
insmod part_msdos
savedefault
insmod ntfs
insmod ntldr
set root='(hd0,msdos1)'
ntldr ($root)/bootmgr
}

के रूप में मेरी प्रणाली दोहरी बूट है और जाहिरा तौर पर यह विंडोज़ 10 के लिए बूट लोडर है।

मेरा सवाल हालांकि यह हिस्सा है exec tail -n +3 $0
अगर मैं इसे सही ढंग से डिक्रिप्ट कर रहा हूं तो इसका मतलब +3है कि फाइल की तीसरी लाइन ( ) से शुरू होने वाली आखिरी लाइनें प्रिंट करें $0$0बेशक इस मामले में वास्तविक फ़ाइल /etc/grub.d/40_custom है

तो, हम 40_custom फ़ाइल में इस कमांड का उपयोग क्यों करते हैं ? जैसा कि मुझे लगता है कि आउटपुट समान होगा यदि ιt पूरी तरह से छोड़ा गया था। केवल एक अलग चीज जो मैं सोच सकता हूं वह है पहली पंक्ति जो दुभाषिया की पहचान करती है:

#!/bin/sh

लेकिन तब से इसे फिर से निष्पादित किया जाता exec tail -n +3 $0है। तो, क्या यह सिर्फ (बेकार) सम्मेलन है?

जवाबों:


16

चाल क्या execहै:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

इसका मतलब है कि यह execइस मामले में, जो कुछ भी दिया गया है , उसके साथ शेल को बदल देगा tail। यहां इसका एक उदाहरण कार्रवाई में है:

$ cat ~/foo.sh
#!/bin/sh
exec tail -n +3 "$0"
echo foo

$ ./foo.sh
echo foo

इसलिए echoकमांड को निष्पादित नहीं किया गया है क्योंकि हमने शेल को बदल दिया है और tailइसके बजाय उपयोग कर रहे हैं । यदि हम हटा दें exec tail:

$ cat ~/foo.sh
#!/bin/sh
echo foo
$ ./foo.sh
foo

तो, यह एक साफ-सुथरी चाल है जिससे आप एक स्क्रिप्ट लिख सकते हैं, जिसका एकमात्र काम अपनी सामग्री का उत्पादन करना है। संभवतः, जो भी कॉल 40_customकरता है वह अपनी सामग्री को आउटपुट के रूप में देखता है। बेशक, यह सवाल है कि सिर्फ tail -n +3 /etc/grub.d/40_customसीधे क्यों नहीं चल रहा है।

मैं उत्तर का अनुमान लगा रहा हूं क्योंकि grub इसकी अपनी स्क्रिप्टिंग भाषा का उपयोग किया जाता है और इससे इसे इस वर्कअराउंड की आवश्यकता होती है।


अच्छा उत्तर! लेकिन क्या होगा अगर हम #!/bin/tail -n +2एक शेलबैंग के रूप में लिखेंगे? क्या यह बाकी फाइल को प्रिंट करेगा?
वैल का कहना है कि मोनिका

@val इसे आज़माएं और देखें :) पता चलता है कि यह पूरी तरह से एक शेबंग के रूप में काम नहीं करता है, ऐसा -n +2लगता है कि इसकी व्याख्या की जा रही है -n 2और केवल अंतिम दो पंक्तियों को मुद्रित किया जाता है। यह शायद अपने सवाल के लायक है, हालांकि।
टेराडॉन

3
@val ... शेबंग व्यवहार बहुत कम मानकीकृत और पोर्टेबल है जितना आप उम्मीद कर सकते हैं। En.wikipedia.org/wiki/Shebang_(Unix)#Portability
चार्ल्स डफी

@ यदि आप nऔर के बीच की जगह को हटाते हैं तो लिनक्स में काम करता है +। लिनक्स में कम से कम, निष्पादन योग्य पथ और एक स्थान के बाद, निम्न वर्णों को एक ही तर्क के रूप में माना जाता है। इसलिए अंतरिक्ष के साथ, पूंछ इसे देखती है और संभवत: जो भी पूर्व उपसर्ग -nका तर्क है, उसे हटाने का फैसला करती है (इस मामले में, एक स्थान और एक +) जब तक यह संख्या तक नहीं पहुंच जाती। हालांकि, जैसे चार्ल्स डफी ने कहा, वर्तमान में उन्होंने जो किया वह शायद अन्य यूनियनों के लिए अधिक पोर्टेबल है।
जोएल

1
@fluffy वे यहाँ डॉक्टर का उपयोग कर सकते हैं। मेरे जवाब में फेडोरा प्रलेखन से लिंक देखें। वे वास्तव में उपयोग करने cat <<EOF ...EOFवहाँ
सर्गी Kolodyazhnyy

9

निर्देशिका /etc/grub.d/में कई निष्पादक होते हैं (आमतौर पर शेल स्क्रिप्ट, लेकिन कोई अन्य निष्पादन योग्य प्रकार भी संभव है)। जब भी grub-mkconfigनिष्पादित किया जाता है (जैसे यदि आप चलाते हैं update-grub, लेकिन यह भी जब आप एक अद्यतन कर्नेल पैकेज स्थापित करते हैं, जिसमें आमतौर पर एक पोस्ट-इंस्टॉल हुक होता है जो पैकेज प्रबंधक को अपडेट करने के लिए कहता है grub.cfg), तो वे सभी वर्णमाला क्रम में निष्पादित होते हैं। उनके आउटपुट सभी संक्षिप्त हो जाते हैं, और फ़ाइल में समाप्त हो जाते हैं /boot/grub/grub.cfg, साफ-सुथरा अनुभाग हेडर के साथ जो यह दर्शाता है कि कौन सा हिस्सा किस /etc/grub.d/फ़ाइल से आता है ।

यह एक विशेष फ़ाइल 40_customआपको आसानी से प्रविष्टियाँ / लाइनें जोड़ने की अनुमति देने के लिए डिज़ाइन की grub.cfgगई है, बस उन्हें इस फ़ाइल में टाइप / पेस्ट करके। एक ही निर्देशिका में अन्य स्क्रिप्ट अधिक जटिल कार्य करते हैं जैसे कि गुठली या गैर-लिनक्स ऑपरेटिंग सिस्टम की तलाश और उनके लिए मेनू प्रविष्टियां बनाना।

grub-mkconfigएक ही तरह से उन सभी फ़ाइलों का इलाज करने की अनुमति देने के लिए (आउटपुट को निष्पादित करें और लें), 40_customएक स्क्रिप्ट है और इस exec tail -n +3 $0सामग्री का उपयोग अपनी सामग्री ("हेडर" को घटाकर) करने के लिए करता है। यदि यह एक निष्पादन योग्य नहीं था, update-grubतो इसे अन्य सभी की तरह निष्पादित करने के बजाय इस फ़ाइल के शाब्दिक पाठ सामग्री को लेने के लिए एक विशेष हार्ड-कोडित अपवाद की आवश्यकता होगी। लेकिन तब क्या अगर आप (या किसी अन्य लिनक्स वितरण के निर्माता) इस फाइल को एक अलग नाम देना चाहते हैं? या क्या होगा यदि आप अपवाद के बारे में नहीं जानते हैं और एक शेल स्क्रिप्ट का नाम बनाया है 40_custom?

आप GNU GRUB नियमावली के बारे में grub-mkconfigऔर अधिक पढ़ सकते हैं (हालांकि यह ज्यादातर उन विकल्पों के बारे में बात करता है/etc/grub.d/* जिन्हें आप सेट कर सकते हैं ), और एक फाइल भी होनी चाहिए जिसमें कहा गया हो कि इन फ़ाइलों को बनाने के लिए निष्पादित किया जाए ।/etc/default/grub/etc/grub.d/READMEgrub.cfg


1
जबकि टेर्डन का उत्तर बताता है कि रेखा कैसे काम करती है, यह एक और अधिक प्रशंसनीय डिज़ाइन कारण देता है क्योंकि GRUB इस तरह से चीजें क्यों करता है।
जोएल

बहुत बढ़िया जवाब। विशेष अपवादों के बारे में अपनी बात करने के लिए - "सरल" अपवाद दो निर्देशिकाएं हो सकती हैं जैसे /etc/grub.d/execकि एक्सटेक्टेबल फ़ाइलों / लिपियों के लिए, और /etc/grub.d/staticसादे पाठ फ़ाइलों के लिए, या कुछ अन्य संकेतक इनको अलग करने के लिए। हालांकि, यह डिजाइन निर्णय था जो वे साथ गए थे।
Stobor

3

TL; DR : यह फ़ाइल में नई प्रविष्टियाँ जोड़ने को सरल बनाने की एक चाल है

पूरे बिंदु को उबंटू के विकी पृष्ठों में से एक ग्रब पर वर्णित किया गया है :

  1. केवल निष्पादन योग्य फाइलें अपडेट-ग्रब के निष्पादन के दौरान grub.cfg में आउटपुट उत्पन्न करती हैं।

स्क्रिप्ट की आउटपुट फाइल /etc/grub.d/की सामग्री बन जाती है grub.cfg

अब, क्या करता execहै? यह पूरी स्क्रिप्ट के लिए आउटपुट को री-वायर कर सकता है या यदि कोई कमांड प्रदान की जाती है - उल्लिखित कमांड स्क्रिप्ट प्रक्रिया से आगे निकल जाती है और बदल जाती है। PID 1234 के साथ एक बार शेल स्क्रिप्ट क्या था अब tailPID 1234 के साथ कमांड है।

अब आप पहले से ही जानते हैं कि tail -n +3 $0स्क्रिप्ट में तीसरी पंक्ति के बाद ही सब कुछ प्रिंट होता है। तो हमें ऐसा करने की आवश्यकता क्यों है? अगर ग्रब केवल आउटपुट के बारे में परवाह करता है तो हम भी कर सकते हैं

cat <<EOF
    menuentry {
    ...
    }
EOF

वास्तव में, आप एक अलग उद्देश्य के लिए, फेडोरा प्रलेखनcat <<EOF में उदाहरण पाएंगे । संपूर्ण बिंदु टिप्पणियों में है - उपयोगकर्ताओं के लिए उपयोग में आसानी:

# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.

execचाल के साथ , आपको यह जानने की ज़रूरत नहीं है कि क्या करता cat <<EOFहै (स्पॉइलर, जिसे यहाँ-डॉक्टर कहा जाता है ), और न ही आपको EOFअंतिम पंक्ति में जोड़ने के लिए याद रखना होगा । बस फ़ाइल में मेनेंट्री जोड़ें और इसके साथ किया जाए। इसके अलावा, यदि आप एक मेनेंट्री जोड़कर स्क्रिप्टिंग कर रहे हैं, तो आप केवल >>इस फ़ाइल में शेल के माध्यम से जोड़ सकते हैं ।

यह सभी देखें:


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

@terdon मुझे नहीं लगता कि यह ग्रब भाषा के साथ कुछ भी करना है। आपको #!/bin/shउस मामले में जरूरत नहीं होगी । मुझे संदेह है कि यह केवल ऐतिहासिक कारण है ( PUPA कोडबेस से लिया गया) और SysV प्रकार की पटकथा से प्रेरित एक डिजाइन निर्णय।
सेर्गेई कोलोडियाज़नी

@terdon यह वास्तव में एक सवाल प्रेरित करता है: unix.stackexchange.com/q/492966/85039
Sergiy Kolodyazhnyy
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.