यदि आप उपयोग करते हैं strace
तो आप देख सकते हैं कि एक शेल स्क्रिप्ट को कैसे चलाया जाता है।
उदाहरण
कहो कि मेरे पास यह शेल स्क्रिप्ट है।
$ cat hello_ul.bash
#!/bin/bash
echo "Hello Unix & Linux!"
इसका उपयोग करके चल रहा है strace
:
$ strace -s 2000 -o strace.log ./hello_ul.bash
Hello Unix & Linux!
$
strace.log
फ़ाइल के अंदर देखने से निम्नलिखित का पता चलता है।
...
open("./hello_ul.bash", O_RDONLY) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff0b6e3330) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR) = 0
read(3, "#!/bin/bash\n\necho \"Hello Unix & Linux!\"\n", 80) = 40
lseek(3, 0, SEEK_SET) = 0
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
fcntl(255, F_GETFD) = -1 EBADF (Bad file descriptor)
dup2(3, 255) = 255
close(3)
...
एक बार फ़ाइल में पढ़ने के बाद, इसे निष्पादित किया जाता है:
...
read(255, "#!/bin/bash\n\necho \"Hello Unix & Linux!\"\n", 40) = 40
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc0b38ba000
write(1, "Hello Unix & Linux!\n", 20) = 20
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(255, "", 40) = 0
exit_group(0) = ?
उपरोक्त में हम स्पष्ट रूप से देख सकते हैं कि पूरी स्क्रिप्ट एक ही इकाई के रूप में पढ़ी जा रही है, और उसके बाद वहां निष्पादित की जाती है। तो यह कम से कम बाश के मामले में "दिखाई" देगा कि यह फ़ाइल को पढ़ता है, और फिर इसे निष्पादित करता है। तो आपको लगता है कि आप स्क्रिप्ट को संपादित कर सकते हैं जबकि यह चल रहा है?
नोट: हालांकि, नहीं! यह समझने के लिए पढ़ें कि आपको रनिंग स्क्रिप्ट फ़ाइल में गड़बड़ क्यों नहीं करनी चाहिए।
अन्य दुभाषियों के बारे में क्या?
लेकिन आपका सवाल थोड़ा हटकर है। यह लिनक्स नहीं है जो आवश्यक रूप से फ़ाइल की सामग्री को लोड कर रहा है, यह सामग्री को लोड करने वाला दुभाषिया है, इसलिए यह वास्तव में ऊपर है कि दुभाषिया को कैसे लागू किया जाता है चाहे वह एक बार में पूरी तरह से या ब्लॉक या लाइनों में फ़ाइल लोड करता है।
तो हम फ़ाइल को संपादित क्यों नहीं कर सकते?
यदि आप एक बहुत बड़ी स्क्रिप्ट का उपयोग करते हैं, तो आप देखेंगे कि उपरोक्त परीक्षण थोड़ा भ्रामक है। वास्तव में अधिकांश दुभाषियों ने अपनी फ़ाइलों को ब्लॉक में लोड किया है। यह बहुत से यूनिक्स उपकरणों के साथ मानक है जहां वे एक फाइल के ब्लॉक को लोड करते हैं, इसे प्रोसेस करते हैं, और फिर दूसरे ब्लॉक को लोड करते हैं। आप इस व्यवहार को इस U & L Q & A के साथ देख सकते हैं, जिसे मैंने कुछ समय पहले लिखा था grep
, जिसका शीर्षक है: प्रत्येक बार grep / egrep कितना पाठ उपभोग करता है? ।
उदाहरण
कहें कि हम निम्नलिखित शेल स्क्रिप्ट बनाते हैं।
$ (
echo '#!/bin/bash';
for i in {1..100000}; do printf "%s\n" "echo \"$i\""; done
) > ascript.bash;
$ chmod +x ascript.bash
इस फ़ाइल में परिणाम:
$ ll ascript.bash
-rwxrwxr-x. 1 saml saml 1288907 Mar 23 18:59 ascript.bash
जिसमें निम्न प्रकार की सामग्री शामिल है:
$ head -3 ascript.bash ; echo "..."; tail -3 ascript.bash
#!/bin/bash
echo "1"
echo "2"
...
echo "99998"
echo "99999"
echo "100000"
अब जब आप इसे उसी तकनीक का उपयोग करके ऊपर से चलाते हैं strace
:
$ strace -s 2000 -o strace_ascript.log ./ascript.bash
...
read(255, "#!/bin/bash\necho \"1\"\necho \"2\"\necho \"3\"\necho \"4\"\necho \"5\"\necho \"6\"\necho \"7\"\necho \"8\"\necho \"9\"\necho \"10\"\necho
...
...
\"181\"\necho \"182\"\necho \"183\"\necho \"184\"\necho \"185\"\necho \"186\"\necho \"187\"\necho \"188\"\necho \"189\"\necho \"190\"\necho \""..., 8192) = 8192
आप देखेंगे कि फ़ाइल को 8KB वेतन वृद्धि पर पढ़ा जा रहा है, इसलिए बैश और अन्य गोले संभवतः किसी फ़ाइल को उसकी संपूर्णता में लोड नहीं करेंगे, बल्कि वे उन्हें ब्लॉक में पढ़ते हैं।
संदर्भ