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

📄 ch45_36.htm

📁 the unix power tools
💻 HTM
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 45] 45.36 Shell Lockfile </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly &amp; Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:55:24Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-260-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch45_01.htm"TITLE="45. Shell Programming for the Initiated"><LINKREL="prev"HREF="ch45_35.htm"TITLE="45.35 Using a Control Character in a Script "><LINKREL="next"HREF="ch46_01.htm"TITLE="46. Shell Script Debugging and Gotchas"></HEAD><BODYBGCOLOR="#FFFFFF"TEXT="#000000"><DIVCLASS="htmlnav"><H1><IMGSRC="gifs/smbanner.gif"ALT="UNIX Power Tools"USEMAP="#srchmap"BORDER="0"></H1><MAPNAME="srchmap"><AREASHAPE="RECT"COORDS="0,0,466,58"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="467,0,514,18"HREF="jobjects/fsearch.htm"ALT="Search this book"></MAP><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_35.htm"TITLE="45.35 Using a Control Character in a Script "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.35 Using a Control Character in a Script "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 45<BR>Shell Programming for the Initiated</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="CHAPTER"HREF="ch46_01.htm"TITLE="46. Shell Script Debugging and Gotchas"><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 46. Shell Script Debugging and Gotchas"BORDER="0"></A></TD></TR></TABLE>&nbsp;<HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-9914">45.36 Shell Lockfile </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-55238"></A><ACLASS="indexterm"NAME="AUTOID-55241"></A><ACLASS="indexterm"NAME="AUTOID-55243"></A><ACLASS="indexterm"NAME="AUTOID-55246"></A>Here's an efficient and portable way to create a lockfile from a shellscript.[6]It's also an interesting demonstration of the way that UNIX<SPANCLASS="link">umasks (<ACLASS="linkend"HREF="ch22_04.htm"TITLE="Setting an Exact umask ">22.4</A>)</SPAN>and<SPANCLASS="link">file permissions (<ACLASS="linkend"HREF="ch22_02.htm"TITLE="Tutorial on File and Directory Permissions ">22.2</A>)</SPAN>are handled.</P><BLOCKQUOTECLASS="footnote"><PCLASS="para">[6] Greg Ubben sent this idea.</P></BLOCKQUOTE><PCLASS="para">A <EMCLASS="emphasis">lockfile</EM> can be used if a particular program might be run morethan once at the same time&nbsp;- and you need to be sure that only oneinstance of the program can do something (like modify some file,access a printer, etc.).  Let's say you have a script called<EMCLASS="emphasis">edmaster</EM>; it edits a master configuration file named<EMCLASS="emphasis">config</EM>.  To be sure that two users can't modify the <EMCLASS="emphasis">config</EM>file at the same time, the first <EMCLASS="emphasis">edmaster</EM> would check whetherthe lockfile exists.  If the lockfile doesn't exist, <EMCLASS="emphasis">edmaster</EM>will create it and modify the <EMCLASS="emphasis">config</EM> file.  When it's doneediting, it removes the lockfile.  If someone tries to run a second<EMCLASS="emphasis">edmaster</EM> process, it will see the lockfile from the first<EMCLASS="emphasis">edmaster</EM>, wait and check every few seconds to see if thelockfile is gone.  Once the first <EMCLASS="emphasis">edmaster</EM> removes the lockfile,the second <EMCLASS="emphasis">edmaster</EM> can create the lockfile and do its editingof <EMCLASS="emphasis">config</EM>.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-55267"></A><ACLASS="indexterm"NAME="AUTOID-55270"></A>Here are pieces of a script that check the lock, create it, and(later) remove it:</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist">&#13;<ACLASS="co"HREF="ch45_21.htm"TITLE="45.21 n&gt;&amp;m: Swap Standard Output and Standard Error ">2&gt;</A> <ACLASS="co"HREF="ch13_14.htm"TITLE="13.14 What Can You Do with an Empty File? ">/dev/null</A> <ACLASS="co"HREF="ch44_19.htm"TITLE="44.19 The Bourne Shell set Command ">set</A> &#13;</PRE></TH><TDVALIGN="TOP"><PRECLASS="screen"># set name of this program's lockfile:myname=`basename $0`LOCKFILE=/tmp/lock.$myname   ...# Loop until we get a lock:until (umask 222; echo $$ &gt;$LOCKFILE) 2&gt;/dev/null   # test &amp; set<ACLASS="indexterm"NAME="AUTOID-55277"></A><ACLASS="indexterm"NAME="AUTOID-55281"></A>do   # Optional message - show lockfile owner and creation time:   set x `ls -l $LOCKFILE`   echo &quot;Waiting for user $4 (working since $7 $8 $9)...&quot;   sleep 5done# Do whatever we need exclusive access to do...   ...rm -f $LOCKFILE            # unlock</PRE></TD></TR></TABLE></P><PCLASS="para">So if another user tried to run <EMCLASS="emphasis">edconfig</EM>, and <EMCLASS="emphasis">jpeek</EM>had run <EMCLASS="emphasis">edconfig</EM> first, she might see:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>edconfig</B></CODE>Waiting for user jpeek (working since Aug 23 14:05)...   <ICLASS="lineannotation">...a 5-second pause</I>Waiting for user jpeek (working since Aug 23 14:05)...   <EMCLASS="emphasis">another 5-second pause...</EM>   <ICLASS="lineannotation">...then jpeek finishes and she can edit the file.</I></PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-55296"></A>How does it work?Almost all of the action is in the first line of the loop.A umask of 222 creates files that are read-only(mode <CODECLASS="literal">r--r--r--</CODE>).Because the <EMCLASS="emphasis">umask&nbsp;222</EM> command is run in a<SPANCLASS="link">subshell (<ACLASS="linkend"HREF="ch38_04.htm"TITLE="Subshells ">38.4</A>)</SPAN>,it only affects the lockfile that's created in the subshell at the topof the loop.The rest of the shell script keeps its normal umask.</P><PCLASS="para">If the lockfile already exists (because another process has created it),the loop executes <CODECLASS="literal">sleep&nbsp;5</CODE>; five seconds later, it tries to createthe lock.If the lockfile exists, it will be read-only&nbsp;- so, the command<CODECLASS="literal">echo&nbsp;$$&nbsp;&gt;$LOCKFILE</CODE> will return a nonzero status.A nonzero status is what keeps an<SPANCLASS="link"><EMCLASS="emphasis">until</EM> loop (<ACLASS="linkend"HREF="ch44_10.htm"TITLE="Loops That Test Exit Status ">44.10</A>)</SPAN>running.Once the other process (which has the lock) removes the lockfile,the <EMCLASS="emphasis">echo</EM> command in the subshell will write the shell's processID number into the lockfile and the <EMCLASS="emphasis">until</EM> loop will terminate.</P><PCLASS="para">But, if the lockfile is read-only, how can it ever be created?That's the other interesting part of this technique.The umask only applies to the file <EMCLASS="emphasis">as</EM> it's created; if the filedoesn't exist, the umask doesn't apply to it (yet) and the file can becreated.In fact, you can create a file with mode 000 by typing:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="userinput"><B>(umask 666; echo hi &gt; afile)</B></CODE>$ <CODECLASS="userinput"><B>ls -l afile</B></CODE>----------  1 jpeek   wheel   3 Aug 23 14:08 afile</PRE></BLOCKQUOTE></P><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">JP</SPAN></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_35.htm"TITLE="45.35 Using a Control Character in a Script "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.35 Using a Control Character in a Script "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="book"HREF="index.htm"TITLE="UNIX Power Tools"><IMGSRC="gifs/txthome.gif"SRC="gifs/txthome.gif"ALT="UNIX Power Tools"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="CHAPTER"HREF="ch46_01.htm"TITLE="46. Shell Script Debugging and Gotchas"><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 46. Shell Script Debugging and Gotchas"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">45.35 Using a Control Character in a Script </TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="index"HREF="index/idx_0.htm"TITLE="Book Index"><IMGSRC="gifs/index.gif"SRC="gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172">46. Shell Script Debugging and Gotchas</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><IMGSRC="gifs/smnavbar.gif"SRC="gifs/smnavbar.gif"USEMAP="#map"BORDER="0"ALT="The UNIX CD Bookshelf Navigation"><MAPNAME="map"><AREASHAPE="RECT"COORDS="0,0,73,21"HREF="../index.htm"ALT="The UNIX CD Bookshelf"><AREASHAPE="RECT"COORDS="74,0,163,21"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="164,0,257,21"HREF="../unixnut/index.htm"ALT="UNIX in a Nutshell"><AREASHAPE="RECT"COORDS="258,0,321,21"HREF="../vi/index.htm"ALT="Learning the vi Editor"><AREASHAPE="RECT"COORDS="322,0,378,21"HREF="../sedawk/index.htm"ALT="sed &amp; awk"><AREASHAPE="RECT"COORDS="379,0,438,21"HREF="../ksh/index.htm"ALT="Learning the Korn Shell"><AREASHAPE="RECT"COORDS="439,0,514,21"HREF="../lrnunix/index.htm"ALT="Learning the UNIX Operating System"></MAP></DIV></BODY></HTML>

⌨️ 快捷键说明

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