system.html

来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 4,056 行 · 第 1/5 页

HTML
4,056
字号
BORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;# 某些命令.   4&nbsp;sudo cp /root/secretfile /home/bozo/secret  5&nbsp;# 其余的命令. </PRE></FONT></TD></TR></TABLE></P><P>文件<TTCLASS="FILENAME">/etc/sudoers</TT>中保存有允许调用<BCLASS="COMMAND">sudo</B>命令的用户名. </P></DD><DT><BCLASS="COMMAND">passwd</B></DT><DD><P>设置, 修改, 或者管理用户的密码. </P><P><BCLASS="COMMAND">passwd</B>命令可以用在脚本中, 	      但是<EM>估计你不想这么用</EM>, 呵呵. </P><DIVCLASS="EXAMPLE"><HR><ANAME="SETNEWPW"></A><P><B>例子 13-1. 设置一个新密码</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;#  setnew-password.sh: 这个脚本仅仅用于说明passwd命令.   3&nbsp;#                      如果你真想运行这个脚本, 很遗憾, 这可不是个好主意.   4&nbsp;#  这个脚本必须以root身份来运行.   5&nbsp;  6&nbsp;ROOT_UID=0         # Root的$UID为0.  7&nbsp;E_WRONG_USER=65    # 不是root用户?  8&nbsp;  9&nbsp;E_NOSUCHUSER=70 10&nbsp;SUCCESS=0 11&nbsp; 12&nbsp; 13&nbsp;if [ "$UID" -ne "$ROOT_UID" ] 14&nbsp;then 15&nbsp;  echo; echo "Only root can run this script."; echo 16&nbsp;  exit $E_WRONG_USER 17&nbsp;else 18&nbsp;  echo 19&nbsp;  echo "You should know better than to run this script, root." 20&nbsp;  echo "Even root users get the blues... " 21&nbsp;  echo 22&nbsp;fi   23&nbsp; 24&nbsp; 25&nbsp;username=bozo 26&nbsp;NEWPASSWORD=security_violation 27&nbsp; 28&nbsp;# 检查bozo是否在这里.  29&nbsp;grep -q "$username" /etc/passwd 30&nbsp;if [ $? -ne $SUCCESS ] 31&nbsp;then 32&nbsp;  echo "User $username does not exist." 33&nbsp;  echo "No password changed." 34&nbsp;  exit $E_NOSUCHUSER 35&nbsp;fi   36&nbsp; 37&nbsp;echo "$NEWPASSWORD" | passwd --stdin "$username" 38&nbsp;#  'passwd'命令的'--stdin'选项允许 39&nbsp;#+ 从stdin(或者管道)中获得一个新的密码.  40&nbsp; 41&nbsp;echo; echo "User $username's password changed!" 42&nbsp; 43&nbsp;# 在脚本中使用'passwd'命令是非常危险的.  44&nbsp; 45&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><BCLASS="COMMAND">passwd</B>命令的<CODECLASS="OPTION">-l</CODE>,				<CODECLASS="OPTION">-u</CODE>, 和<CODECLASS="OPTION">-d</CODE>选项允许锁定, 				解锁, 和删除一个用户的密码. 只有root用户可以使用这些选项. 			</P></DD><DT><BCLASS="COMMAND">ac</B></DT><DD><P>显示用户登录的连接时间, 			  就像从<TTCLASS="FILENAME">/var/log/wtmp</TT>中读取一样. 			  这是一个GNU统计工具. 	      </P><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">ac</KBD><SAMPCLASS="COMPUTEROUTPUT">        total       68.08</SAMP></PRE></FONT></TD></TR></TABLE></DD><DT><BCLASS="COMMAND">last</B></DT><DD><P>用户<EM>最后</EM>登录的信息, 			  就像从<TTCLASS="FILENAME">/var/log/wtmp</TT>中读出来一样. 			  这个命令也可以用来显示远端登录. 	      </P><P>比如, 显示最后几次系统的重启信息: </P><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">last reboot</KBD><SAMPCLASS="COMPUTEROUTPUT">reboot   system boot  2.6.9-1.667      Fri Feb  4 18:18          (00:02)     reboot   system boot  2.6.9-1.667      Fri Feb  4 15:20          (01:27)     reboot   system boot  2.6.9-1.667      Fri Feb  4 12:56          (00:49)     reboot   system boot  2.6.9-1.667      Thu Feb  3 21:08          (02:17)     . . . wtmp begins Tue Feb  1 12:50:09 2005</SAMP></PRE></FONT></TD></TR></TABLE></DD><DT><BCLASS="COMMAND">newgrp</B></DT><DD><P>不用登出就可以修改用户的组ID. 并且允许访问新组的文件. 			  因为用户可能同时属于多个组, 这个命令很少被使用. 	      </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="TERMINALSSYS1"></A>终端类命令</B></P><DL><DT><BCLASS="COMMAND">tty</B></DT><DD><P>显示当前用户终端的名字. 			  注意每一个单独的<ICLASS="FIRSTTERM">xterm</I>窗口都被算作一个不同的终端.	      </P><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">tty</KBD><SAMPCLASS="COMPUTEROUTPUT">/dev/pts/1</SAMP></PRE></FONT></TD></TR></TABLE></DD><DT><ANAME="STTYREF"></A><BCLASS="COMMAND">stty</B></DT><DD><P>显示并(或)修改终端设置. 这个复杂命令可以用在脚本中, 			  并可以用来控制终端的行为和其显示输出的方法. 参见这个命令的info页, 并仔细学习它.	      </P><DIVCLASS="EXAMPLE"><HR><ANAME="ERASE"></A><P><B>例子 13-2. 设置一个擦除字符</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# erase.sh: 在读取输入时使用"stty"来设置一个擦除字符.   3&nbsp;  4&nbsp;echo -n "What is your name? "  5&nbsp;read name                      #  试试用退格键  6&nbsp;                               #+ 来删除输入的字符.   7&nbsp;                               #  有什么问题?   8&nbsp;echo "Your name is $name."  9&nbsp; 10&nbsp;stty erase '#'                 #  将"hashmark"(#)设置为退格字符.  11&nbsp;echo -n "What is your name? " 12&nbsp;read name                      #  使用#来删除最后键入的字符.  13&nbsp;echo "Your name is $name." 14&nbsp; 15&nbsp;# 警告: 即使在脚本退出后, 新的键值还是保持着这个设置. (译者: 可以使用stty erase '^?'进行恢复) 16&nbsp; 17&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="SECRETPW"></A><P><B>例子 13-3. <BCLASS="COMMAND">保密密码</B>: 关闭终端对于密码的echo</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# secret-pw.sh: 保护密码不被显示  3&nbsp;  4&nbsp;echo  5&nbsp;echo -n "Enter password "  6&nbsp;read passwd  7&nbsp;echo "password is $passwd"  8&nbsp;echo -n "If someone had been looking over your shoulder, "  9&nbsp;echo "your password would have been compromised." 10&nbsp; 11&nbsp;echo &#38;&#38; echo  # 在一个"与列表"中产生两个换行.  12&nbsp; 13&nbsp; 14&nbsp;stty -echo    # 关闭屏幕的echo.  15&nbsp; 16&nbsp;echo -n "Enter password again " 17&nbsp;read passwd 18&nbsp;echo 19&nbsp;echo "password is $passwd" 20&nbsp;echo 21&nbsp; 22&nbsp;stty echo     # 恢复屏幕的echo.  23&nbsp; 24&nbsp;exit 0 25&nbsp; 26&nbsp;# 详细的阅读stty命令的info页, 以便于更好的掌握这个有用并且狡猾的工具. </PRE></FONT></TD></TR></TABLE><HR></DIV><P>一个创造性的<BCLASS="COMMAND">stty</B>命令的用法, 			检测用户所按的键(不用敲<BCLASS="KEYCAP">回车</B>). 		</P><DIVCLASS="EXAMPLE"><HR><ANAME="KEYPRESS"></A><P><B>例子 13-4. 按键检测</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# keypress.sh: 检测用户按键("hot keys").  3&nbsp;  4&nbsp;echo  5&nbsp;  6&nbsp;old_tty_settings=$(stty -g)   # 保存老的设置(为什么?).   7&nbsp;stty -icanon  8&nbsp;Keypress=$(head -c1)          # 或者使用$(dd bs=1 count=1 2&#62; /dev/null)  9&nbsp;                              # 在非GNU系统上 10&nbsp; 11&nbsp;echo 12&nbsp;echo "Key pressed was \""$Keypress"\"." 13&nbsp;echo 14&nbsp; 15&nbsp;stty "$old_tty_settings"      # 恢复老的设置.  16&nbsp; 17&nbsp;# 感谢, Stephane Chazelas. 18&nbsp; 19&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>请参考<AHREF="internalvariables.html#TIMEOUT">例子 9-3</A>. </P><TABLECLASS="SIDEBAR"BORDER="1"CELLPADDING="5"><TR><TD><DIVCLASS="SIDEBAR"><ANAME="AEN11305"></A><P><B>终端与模式terminals and modes</B></P><P>一般情况下, 一个终端都是工作在<EM>canonical</EM>(标准)模式下. 				当用户按键后, 事实上所产生的字符并没有马上传递到运行在当前终端上的程序. 				终端上的一个本地缓存保存了这些按键. 当用按下<BCLASS="KEYCAP">回车</B>键的时候, 				才会将所有保存的按键信息传递到运行的程序中. 				这就意味着在终端内部存在一个基本的行编辑器. 			</P><P>	        <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">stty -a</KBD><SAMPCLASS="COMPUTEROUTPUT">speed 9600 baud; rows 36; columns 96; line = 0; intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = &#60;undef&#62;; eol2 = &#60;undef&#62;; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; ... isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt</SAMP>                </PRE></FONT></TD></TR></TABLE>	    </P><P>在使用canonical模式的时候, 可以对本地终端行编辑器所定义的特殊按键进行重新定义. 	        <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">cat &#62; filexxx</KBD><KBDCLASS="USERINPUT">wha&#60;ctl-W&#62;I&#60;ctl-H&#62;foo bar&#60;ctl-U&#62;hello world&#60;ENTER&#62;</KBD><KBDCLASS="USERINPUT">&#60;ctl-D&#62;</KBD><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">cat filexxx</KBD><SAMPCLASS="COMPUTEROUTPUT">hello world</SAMP>		<SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">wc -c &#60; filexxx</KBD><SAMPCLASS="COMPUTEROUTPUT">12</SAMP>		                </PRE></FONT></TD></TR></TABLE>				控制终端的进程只保存了12个字符(11个字母加上一个换行), 				虽然用户敲了26个按键.             </P><P>在non-canonical((<SPANCLASS="QUOTE">"raw"</SPAN>)模式下, 				每次按键(包括特殊定义的按键, 				比如<BCLASS="KEYCAP">ctl-H</B>)都将会立即发送一个字符到控制进程中.               </P><P>Bash提示符禁用了<CODECLASS="OPTION">icanon</CODE>和<CODECLASS="OPTION">echo</CODE>, 				  因为它用自己的行编辑器代替了终端的基本行编辑器, 因为Bash的行编辑器更好. 				  比如, 当你在Bash提示符下敲<BCLASS="KEYCAP">ctl-A</B>的时候, 				  终端将不会显示<BCLASS="KEYCAP">^A</B>, 				  但是Bash将会获得<BCLASS="KEYCAP">\1</B>字符, 				  然后解释这个字符, 这样光标就移动到行首了.              </P><P><EM>Stephane Chazelas</EM></P></DIV></TD></TR></TABLE></DD><DT><BCLASS="COMMAND">setterm</B></DT><DD><P>设置特定的终端属性. 			这个命令将向它所在终端的<TTCLASS="FILENAME">stdout</TT>发送一个字符串, 			这个字符串将修改终端的行为.	      </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">setterm -cursor off</KBD><SAMPCLASS="COMPUTEROUTPUT">bash$</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P><P><BCLASS="COMMAND">setterm</B>命令可以放在脚本中用来修改写入到<TTCLASS="FILENAME">stdout</TT>上的文本的外观. 			当然, 如果你只想完成这个目的的话, 			还有<AHREF="colorizing.html#COLORIZINGREF">更合适的工具</A>可以用. </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;setterm -bold on  2&nbsp;echo bold hello  3&nbsp;  4&nbsp;setterm -bold off  5&nbsp;echo normal hello</PRE></FONT></TD></TR></TABLE></P></DD><DT><BCLASS="COMMAND">tset</B></DT><DD><P>显示或初始化终端设置. 	      可以把它看成一个功能比较弱的<BCLASS="COMMAND">stty</B>命令. </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">tset -r</KBD><SAMPCLASS="COMPUTEROUTPUT">Terminal type is xterm-xfree86. Kill is control-U (^U). Interrupt is control-C (^C).</SAMP>	      </PRE></FONT></TD></TR></TABLE>	    </P></DD><DT><BCLASS="COMMAND">setserial</B></DT><DD><P>设置或者显示串口参数. 			  这个脚本只能被root用户来运行, 			  并且通常都在系统安装脚本中使用.	      </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;# 来自于/etc/pcmcia/serial脚本:   2&nbsp;  3&nbsp;IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'`  4&nbsp;setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ</PRE></FONT></TD></TR></TABLE></P></DD><DT><BCLASS="COMMAND">getty</B>, <BCLASS="COMMAND">agetty</B></DT><DD><P>一个终端的初始化过程通常都是使用<BCLASS="COMMAND">getty</B>或<BCLASS="COMMAND">agetty</B>来建立, 			  这样才能让用户登录. 这些命令并不用在用户的shell脚本中. 			  它们的行为与<BCLASS="COMMAND">stty</B>很相似. 		  </P></DD><DT><ANAME="MESGREF"></A><BCLASS="COMMAND">mesg</B></DT><DD><P>启用或禁用当前用户终端的访问权限. 			  禁用访问权限将会阻止网络上的另一用户向这个终端<AHREF="communications.html#WRITEREF">写</A>消息. 	      </P><DIVCLASS="TIP"><P></P><TABLE

⌨️ 快捷键说明

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