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

📄 internal.html

📁 Shall高级编程
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Internal Commands and Builtins</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Commands"HREF="part4.html"><LINKREL="PREVIOUS"TITLE="Commands"HREF="part4.html"><LINKREL="NEXT"TITLE="External Filters, Programs and Commands"HREF="external.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="part4.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="external.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="INTERNAL"></A>Chapter 14. Internal Commands and Builtins</H1><P><ANAME="BUILTINREF"></A>A <ICLASS="FIRSTTERM">builtin</I>	is a <BCLASS="COMMAND">command</B> contained within the Bash tool	set, literally <ICLASS="FIRSTTERM">built in</I>. This is either	for performance reasons -- builtins execute faster than external	commands, which usually require <ICLASS="FIRSTTERM">forking off</I>	a separate process -- or because a particular builtin needs	direct access to the shell internals.</P><P><ANAME="FORKREF"></A></P><TABLECLASS="SIDEBAR"BORDER="1"CELLPADDING="5"><TR><TD><DIVCLASS="SIDEBAR"><ANAME="AEN7770"></A><P>When a command or		   the shell itself initiates (or		   <ICLASS="FIRSTTERM">spawns</I>) a new		   subprocess to carry out a task, this is called		   <ICLASS="FIRSTTERM">forking</I>. This new process		   is the <ICLASS="FIRSTTERM">child</I>, and the process		   that <ICLASS="FIRSTTERM">forked</I> it off is the		   <ICLASS="FIRSTTERM">parent</I>. While the <ICLASS="FIRSTTERM">child		   process</I> is doing its work, the		   <ICLASS="FIRSTTERM">parent process</I> is still		   executing.</P><P>Note that while a <ICLASS="FIRSTTERM">parent		   process</I> gets the <ICLASS="FIRSTTERM">process		   ID</I> of the <ICLASS="FIRSTTERM">child		   process</I>, and can thus pass arguments to it,		   <SPANCLASS="emphasis"><ICLASS="EMPHASIS">the reverse is not true</I></SPAN>. <AHREF="gotchas.html#PARCHILDPROBREF">This can create problems		   that are subtle and hard to track down.</A></P><DIVCLASS="EXAMPLE"><HR><ANAME="SPAWNSCR"></A><P><B>Example 14-1. A script that forks off multiple instances of itself</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# spawn.sh   3&nbsp;   4&nbsp;   5&nbsp;PIDS=$(pidof sh $0)  # Process IDs of the various instances of this script.   6&nbsp;P_array=( $PIDS )    # Put them in an array (why?).   7&nbsp;echo $PIDS           # Show process IDs of parent and child processes.   8&nbsp;let "instances = ${#P_array[*]} - 1"  # Count elements, less 1.   9&nbsp;                                      # Why subtract 1?  10&nbsp;echo "$instances instance(s) of this script running."  11&nbsp;echo "[Hit Ctl-C to exit.]"; echo  12&nbsp;  13&nbsp;  14&nbsp;sleep 1              # Wait.  15&nbsp;sh $0                # Play it again, Sam.  16&nbsp;  17&nbsp;exit 0               # Not necessary; script will never get to here.  18&nbsp;                     # Why not?  19&nbsp;  20&nbsp;#  After exiting with a Ctl-C,  21&nbsp;#+ do all the spawned instances of the script die?  22&nbsp;#  If so, why?  23&nbsp;  24&nbsp;# Note:  25&nbsp;# ----  26&nbsp;# Be careful not to run this script too long.  27&nbsp;# It will eventually eat up too many system resources.  28&nbsp;  29&nbsp;#  Is having a script spawn multiple instances of itself  30&nbsp;#+ an advisable scripting technique.  31&nbsp;#  Why or why not?</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="BLTINFRK"></A></P><P>Generally, a Bash <ICLASS="FIRSTTERM">builtin</I>		   does not fork a subprocess when it executes within		   a script. An external system command or filter in		   a script usually <SPANCLASS="emphasis"><ICLASS="EMPHASIS">will</I></SPAN> fork a		   subprocess.</P></DIV></TD></TR></TABLE><P>A builtin may be a synonym to a system command of the same	name, but Bash reimplements it internally.  For example,	the Bash <BCLASS="COMMAND">echo</B> command is not the same as	<TTCLASS="FILENAME">/bin/echo</TT>, although their behavior is	almost identical.	   <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;   3&nbsp;echo "This line uses the \"echo\" builtin."   4&nbsp;/bin/echo "This line uses the /bin/echo system command."</PRE></TD></TR></TABLE>	</P><P><ANAME="KEYWORDREF"></A>A <ICLASS="FIRSTTERM">keyword</I>	is a <ICLASS="FIRSTTERM">reserved</I> word, token or	operator. Keywords have a special meaning to the shell,	and indeed are the building blocks of the shell's	syntax. As examples, <SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">for</SPAN>"</SPAN>,	<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">while</SPAN>"</SPAN>, <SPANCLASS="QUOTE">"do"</SPAN>, and	<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">!</SPAN>"</SPAN> are keywords. Similar to a <AHREF="internal.html#BUILTINREF">builtin</A>, a keyword is hard-coded into	Bash, but unlike a <ICLASS="FIRSTTERM">builtin</I>, a keyword is	not in itself a command, but <SPANCLASS="emphasis"><ICLASS="EMPHASIS">a subunit of a larger	command structure</I></SPAN>.	   <ANAME="AEN7811"HREF="#FTN.AEN7811">[1]</A>	</P><DIVCLASS="VARIABLELIST"><P><B><ANAME="INTIO1"></A>I/O</B></P><DL><DT><ANAME="ECHOREF"></A><BCLASS="COMMAND">echo</B></DT><DD><P>prints (to <TTCLASS="FILENAME">stdout</TT>) an expression	      or variable (see <AHREF="variables.html#EX9">Example 4-1</A>). 	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;echo Hello   2&nbsp;echo $a</PRE></TD></TR></TABLE></P><P>An <BCLASS="COMMAND">echo</B> requires the	      <TTCLASS="OPTION">-e</TT> option to print escaped characters. See	      <AHREF="escapingsection.html#ESCAPED">Example 5-2</A>.</P><P>Normally, each <BCLASS="COMMAND">echo</B> command prints	      a terminal newline, but the <TTCLASS="OPTION">-n</TT> option	      suppresses this.</P><P><ANAME="ECHOGREPREF"></A></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>An <BCLASS="COMMAND">echo</B> can be used to feed a	      sequence of commands down a pipe.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;if echo "$VAR" | grep -q txt   # if [[ $VAR = *txt* ]]   2&nbsp;then   3&nbsp;  echo "$VAR contains the substring sequence \"txt\""   4&nbsp;fi</PRE></TD></TR></TABLE></P></TD></TR></TABLE></DIV><P><ANAME="ECHOCS"></A></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>An <BCLASS="COMMAND">echo</B>, in combination with	      <AHREF="commandsub.html#COMMANDSUBREF">command substitution</A>	      can set a variable.</P><P><TTCLASS="USERINPUT"><B>a=`echo	      "HELLO" | tr A-Z a-z`</B></TT></P><P>See also <AHREF="textproc.html#LOWERCASE">Example 15-21</A>, <AHREF="moreadv.html#EX57">Example 15-3</A>, <AHREF="mathc.html#MONTHLYPMT">Example 15-45</A>, and <AHREF="mathc.html#BASE">Example 15-46</A>.</P></TD></TR></TABLE></DIV><P>Be aware that <BCLASS="COMMAND">echo `command`</B>	      deletes any linefeeds that the output	      of <TTCLASS="REPLACEABLE"><I>command</I></TT>	      generates.</P><P>The <AHREF="variables2.html#IFSREF">$IFS</A> (internal field	      separator) variable normally contains	      <SPANCLASS="TOKEN">\n</SPAN> (linefeed) as one of its set of	      <AHREF="special-chars.html#WHITESPACEREF">whitespace</A>	      characters. Bash therefore splits the output of	      <TTCLASS="REPLACEABLE"><I>command</I></TT> at linefeeds	      into arguments to <BCLASS="COMMAND">echo</B>.  Then	      <BCLASS="COMMAND">echo</B> outputs these arguments,	      separated by spaces.</P><P>	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>ls -l /usr/share/apps/kjezz/sounds</B></TT> <TTCLASS="COMPUTEROUTPUT">-rw-r--r--    1 root     root         1407 Nov  7  2000 reflect.au -rw-r--r--    1 root     root          362 Nov  7  2000 seconds.au</TT>     <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>echo `ls -l /usr/share/apps/kjezz/sounds`</B></TT> <TTCLASS="COMPUTEROUTPUT">total 40 -rw-r--r-- 1 root root 716 Nov 7 2000 reflect.au -rw-r--r-- 1 root root ...</TT> 	      </PRE></TD></TR></TABLE>	    </P><P>              So, how can we embed a linefeed within an	      <AHREF="internal.html#ECHOREF">echoed</A> character string?	     <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;# Embedding a linefeed?   2&nbsp;echo "Why doesn't this string \n split on two lines?"   3&nbsp;# Doesn't split.   4&nbsp;   5&nbsp;# Let's try something else.   6&nbsp;   7&nbsp;echo   8&nbsp;	        9&nbsp;echo $"A line of text containing  10&nbsp;a linefeed."  11&nbsp;# Prints as two distinct lines (embedded linefeed).  12&nbsp;# But, is the "$" variable prefix really necessary?  13&nbsp;  14&nbsp;echo  15&nbsp;  16&nbsp;echo "This string splits  17&nbsp;on two lines."  18&nbsp;# No, the "$" is not needed.  19&nbsp;  20&nbsp;echo  21&nbsp;echo "---------------"  22&nbsp;echo  23&nbsp;  24&nbsp;echo -n $"Another line of text containing  25&nbsp;a linefeed."  26&nbsp;# Prints as two distinct lines (embedded linefeed).  27&nbsp;# Even the -n option fails to suppress the linefeed here.  28&nbsp;  29&nbsp;echo  30&nbsp;echo  31&nbsp;echo "---------------"  32&nbsp;echo  33&nbsp;echo  34&nbsp;  35&nbsp;# However, the following doesn't work as expected.  36&nbsp;# Why not? Hint: Assignment to a variable.  37&nbsp;string1=$"Yet another line of text containing  38&nbsp;a linefeed (maybe)."  39&nbsp;  40&nbsp;echo $string1  41&nbsp;# Yet another line of text containing a linefeed (maybe).  42&nbsp;#                                    ^  43&nbsp;# Linefeed becomes a space.  44&nbsp;  45&nbsp;# Thanks, Steve Parker, for pointing this out.</PRE></TD></TR></TABLE>            </P><P><ANAME="BINECHO"></A></P><DIVCLASS="NOTE"

⌨️ 快捷键说明

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