एक comment on another post में, @JonathanLeffler कहा कि:बैश सबहेल/पाइपलाइन - कौन सा भाग सबहेल में निष्पादित कर रहे हैं?
{...} | कुछ कमांड एक उप-खोल में चलाया जाता है और पैरेंट शैल को प्रभावित नहीं करता है। डेमो:
X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
(उत्पादन PQR, एबीसी, पीक्यूआर तीन लाइनों पर साथ)
और वास्तव में:
[email protected]:tmp$X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
PQR
ABC
PQR
हालांकि, man bash
का कहना है कि { .. }
करता है एक सबहेल में निष्पादित नहीं:
{ list; }
list is simply executed in the current shell environment. list must be
terminated with a newline or semicolon. This is known as a group command.
तो यहां क्या हो रहा है? man bash
गलत है? मुझे पता है कि पाइपलाइन के प्रत्येक हिस्से को सबहेल में निष्पादित किया जाता है; लेकिन मुझे नहीं लगता कि यह किस तरह के व्यवहार का कारण बनता है। उदाहरण के लिए:
[email protected]:tmp$X=PQR; echo $X | sed; X=ABC; echo $X | sed; echo $X
PQR
ABC
ABC
संपादित जोड़ने के लिए:
कुछ लोगों echo $$
का उपयोग कर पता चलता है कि चीजें हैं (या नहीं कर रहे हैं) एक subshell के कुछ हिस्सों का सुझाव दिया है। यह बिल्कुल उपयोगी नहीं है, क्योंकि $$
पैरामीटर विस्तार चरण के दौरान विस्तारित हो जाता है, जो कि किसी भी आदेश को निष्पादित करने से पहले होता है।
एक उदाहरण के रूप:
[email protected]:tmp$echo 1$$; ps; (echo 2$$; ps); echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
7894 ttys000 0:00.00 -bash
31194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
[email protected]:tmp$
आप देख सकते हैं कि ps
के दूसरे मंगलाचरण पीआईडी 7894
के साथ, एक subshell अंदर हुआ; लेकिन echo 2$$
अभी भी मूल्य है कि चर विस्तार चरण में प्रतिस्थापित बैश, इससे पहले कि यह subshell
इसके विपरीत के लिए पैदा की दिखाता है, और प्रदर्शन है कि { .. }
नहीं अंडे एक subshell करता है:
[email protected]:tmp$echo 1$$; ps; { echo 2$$; ps; }; echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
31194
PID TTY TIME CMD
1194 ttys000 0:00.23 -bash
बस साबित होता है कि @nos सही है, इसके बाद के संस्करण के लिए एक पाइप लाइन को जोड़ने:
[email protected]:tmp$echo 1$$; ps; { echo 2$$; ps; } | sed ; echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
7945 ttys000 0:00.00 -bash
7946 ttys000 0:00.00 sed
31194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
जैसी उम्मीद थी, खोल दो subshells, पाइप लाइन के प्रत्येक पक्ष के लिए एक spawns।
मुझे लगता है कि हमारे पास विजेता है। यह '{..}' नहीं है जो सबशेल बना रहा है, यह पाइपलाइन है। मैं व्यावहारिक रूप से बाहर आया और कहा कि शुरुआत में सही है। –
आपको '{', कम से कम 'bash' के मेरे संस्करण में 'के बाद एक स्थान की आवश्यकता है। – krlmlr
$ (cmd args) निर्माण भी एक सबहेल बनाते हैं: 'echo $ (echo $ BASH_SUBSHELL) ' –