⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subshells.html

📁 Shall高级编程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
	    variable</A> lies only within the function,	    block of code, or subshell within which it is defined.</P></DIV></TD></TR></TABLE><P><ANAME="SUBSHNLEVREF"></A></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>While the <AHREF="variables2.html#BASHSUBSHELLREF">$BASH_SUBSHELL</A>	      internal variable indicates the nesting level of a	      subshell, the <AHREF="variables2.html#SHLVLREF">$SHLVL</A>	      variable <SPANCLASS="emphasis"><ICLASS="EMPHASIS">shows no change</I></SPAN> within	      a subshell.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;echo " \$BASH_SUBSHELL outside subshell       = $BASH_SUBSHELL"           # 0   2&nbsp;  ( echo " \$BASH_SUBSHELL inside subshell        = $BASH_SUBSHELL" )     # 1   3&nbsp;  ( ( echo " \$BASH_SUBSHELL inside nested subshell = $BASH_SUBSHELL" ) ) # 2   4&nbsp;# ^ ^                           *** nested ***                        ^ ^   5&nbsp;   6&nbsp;echo   7&nbsp;   8&nbsp;echo " \$SHLVL outside subshell = $SHLVL"       # 3   9&nbsp;( echo " \$SHLVL inside subshell  = $SHLVL" )   # 3 (No change!)</PRE></TD></TR></TABLE>            </P></TD></TR></TABLE></DIV><P>Directory changes made in a subshell do not carry over to the        parent shell.</P><DIVCLASS="EXAMPLE"><HR><ANAME="ALLPROFS"></A><P><B>Example 20-2. List User Profiles</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# allprofs.sh: print all user profiles   3&nbsp;   4&nbsp;# This script written by Heiner Steven, and modified by the document author.   5&nbsp;   6&nbsp;FILE=.bashrc  #  File containing user profile,   7&nbsp;              #+ was ".profile" in original script.   8&nbsp;   9&nbsp;for home in `awk -F: '{print $6}' /etc/passwd`  10&nbsp;do  11&nbsp;  [ -d "$home" ] || continue    # If no home directory, go to next.  12&nbsp;  [ -r "$home" ] || continue    # If not readable, go to next.  13&nbsp;  (cd $home; [ -e $FILE ] &#38;&#38; less $FILE)  14&nbsp;done  15&nbsp;  16&nbsp;#  When script terminates, there is no need to 'cd' back to original directory,  17&nbsp;#+ because 'cd $home' takes place in a subshell.  18&nbsp;  19&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>A subshell may be used to set up a <SPANCLASS="QUOTE">"dedicated	      environment"</SPAN> for a command group.	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;COMMAND1   2&nbsp;COMMAND2   3&nbsp;COMMAND3   4&nbsp;(   5&nbsp;  IFS=:   6&nbsp;  PATH=/bin   7&nbsp;  unset TERMINFO   8&nbsp;  set -C   9&nbsp;  shift 5  10&nbsp;  COMMAND4  11&nbsp;  COMMAND5  12&nbsp;  exit 3 # Only exits the subshell!  13&nbsp;)  14&nbsp;# The parent shell has not been affected, and the environment is preserved.  15&nbsp;COMMAND6  16&nbsp;COMMAND7</PRE></TD></TR></TABLE>    As seen here, the <AHREF="internal.html#EXITREF">exit</A>    command only terminates the subshell in which it is running,    <SPANCLASS="emphasis"><ICLASS="EMPHASIS">not</I></SPAN> the parent shell or script.</P><P>One application of such a <SPANCLASS="QUOTE">"dedicated environment"</SPAN>        is testing whether a variable is defined.              <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;if (set -u; : $variable) 2&#62; /dev/null   2&nbsp;then   3&nbsp;  echo "Variable is set."   4&nbsp;fi     #  Variable has been set in current script,   5&nbsp;       #+ or is an an internal Bash variable,   6&nbsp;       #+ or is present in environment (has been exported).   7&nbsp;   8&nbsp;# Could also be written [[ ${variable-x} != x || ${variable-y} != y ]]   9&nbsp;# or                    [[ ${variable-x} != x$variable ]]  10&nbsp;# or                    [[ ${variable+x} = x ]]  11&nbsp;# or                    [[ ${variable-x} != x ]]</PRE></TD></TR></TABLE></P><P>Another application is checking for a lock file:	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;if (set -C; : &#62; lock_file) 2&#62; /dev/null   2&nbsp;then   3&nbsp;  :   # lock_file didn't exist: no user running the script   4&nbsp;else   5&nbsp;  echo "Another user is already running that script."   6&nbsp;exit 65   7&nbsp;fi   8&nbsp;   9&nbsp;#  Code snippet by St閜hane Chazelas,  10&nbsp;#+ with modifications by Paulo Marcel Coelho Aragao.</PRE></TD></TR></TABLE>      </P><P>+</P><P>Processes may execute in parallel within different        subshells. This permits breaking a complex task into subcomponents        processed concurrently.</P><DIVCLASS="EXAMPLE"><HR><ANAME="PARALLEL-PROCESSES"></A><P><B>Example 20-3. Running parallel processes in subshells</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;	(cat list1 list2 list3 | sort | uniq &#62; list123) &#38;   2&nbsp;	(cat list4 list5 list6 | sort | uniq &#62; list456) &#38;   3&nbsp;	# Merges and sorts both sets of lists simultaneously.   4&nbsp;	# Running in background ensures parallel execution.   5&nbsp;	#   6&nbsp;	# Same effect as   7&nbsp;	#   cat list1 list2 list3 | sort | uniq &#62; list123 &#38;   8&nbsp;	#   cat list4 list5 list6 | sort | uniq &#62; list456 &#38;   9&nbsp;	  10&nbsp;	wait   # Don't execute the next command until subshells finish.  11&nbsp;	  12&nbsp;	diff list123 list456</PRE></TD></TR></TABLE><HR></DIV><P>Redirecting I/O to a subshell uses the <SPANCLASS="QUOTE">"|"</SPAN> pipe	  operator, as in <TTCLASS="USERINPUT"><B>ls -al | (command)</B></TT>.</P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>A command block between <TTCLASS="REPLACEABLE"><I>curly	  braces</I></TT> does <SPANCLASS="emphasis"><ICLASS="EMPHASIS">not</I></SPAN> launch	  a subshell.</P><P>{ command1; command2; command3; . . . commandN; }</P></TD></TR></TABLE></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN16686"HREF="subshells.html#AEN16686">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>An external command invoked with an <AHREF="internal.html#EXECREF">exec</A> does <SPANCLASS="emphasis"><ICLASS="EMPHASIS">not</I></SPAN>             (usually) fork off a subprocess / subshell.</P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="redirapps.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="restricted-sh.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Applications</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Restricted Shells</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -