एक समान स्क्रिप्ट, बिना sudo
, लेकिन समान परिणाम:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
के साथ bash
, बाकी स्क्रिप्ट इनपुट के रूप में जाती है sed
, के साथ dash
, शेल इसकी व्याख्या करता है।
strace
उन पर चल रहा है: dash
स्क्रिप्ट का एक ब्लॉक पढ़ता है (आठ केबी यहां, पूरी स्क्रिप्ट को पकड़ने के लिए पर्याप्त से अधिक), और उसके बाद sed
:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 8192) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
जिसका अर्थ है कि फ़ाइलहैंड फ़ाइल के अंत में है, और sed
कोई इनपुट नहीं देखेगा। शेष भाग को बफ़र किया जा रहा है dash
। (यदि स्क्रिप्ट 8 केबी के ब्लॉक आकार से अधिक लंबी थी, तो शेष भाग को पढ़ा जाएगा sed
।)
दूसरी ओर, बैश, अंतिम कमांड के अंत में वापस आ जाता है:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 36) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
...
lseek(0, -7, SEEK_CUR) = 29
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
यदि इनपुट पाइप से आता है, तो यहां:
$ cat script.sh | bash
रिवाइंडिंग नहीं किया जा सकता है, क्योंकि पाइप और सॉकेट्स खोजने योग्य नहीं हैं। इस मामले में, बैश फैलने से बचने के लिए एक समय में इनपुट एक चरित्र को पढ़ने के लिए वापस गिर जाता है । ( fd_to_buffered_stream()
इनinput.c
) प्रत्येक बाइट के लिए एक पूर्ण प्रणाली कॉल करना सिद्धांत रूप में बहुत प्रभावी नहीं है। व्यवहार में, मुझे नहीं लगता कि इस तथ्य की तुलना में रीड्स एक महान ओवरहेड होगा, जो कि ज्यादातर चीजों को खोल देता है जिसमें नई प्रक्रियाएं शामिल हैं।
इसी तरह की स्थिति यह है:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
उपधारा को यह सुनिश्चित करना होता है कि read
केवल पहली नई head
पंक्ति पढ़ी जाए, ताकि अगली पंक्ति दिखाई दे। (यह dash
भी साथ काम करता है।)
दूसरे शब्दों में, बैश स्क्रिप्ट के लिए एक ही स्रोत को पढ़ने के लिए और इससे निष्पादित होने वाले आदेशों का समर्थन करने के लिए अतिरिक्त लंबाई पर जाता है। dash
ऐसा नहीं करता। और zsh
, ksh93
डेबियन में पैक इस पर बैश के साथ चलते हैं।
sudo su
: unix.stackexchange.com/questions/218169/...