system.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 4,056 行 · 第 1/5 页
HTML
4,056 行
><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">readelf -h /bin/bash</KBD><SAMPCLASS="COMPUTEROUTPUT">ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) . . .</SAMP></PRE></FONT></TD></TR></TABLE></DD><DT><BCLASS="COMMAND">size</B></DT><DD><P><BCLASS="COMMAND">size [/path/to/binary]</B>命令可以显示2进制可执行文件或归档文件每部分的尺寸. 这个工具主要提供给程序员使用. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">size /bin/bash</KBD><SAMPCLASS="COMPUTEROUTPUT"> text data bss dec hex filename 495971 22496 17392 535859 82d33 /bin/bash</SAMP> </PRE></FONT></TD></TR></TABLE> </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="SYSLOG1"></A>系统日志类</B></P><DL><DT><BCLASS="COMMAND">logger</B></DT><DD><P>附加一个用户产生的消息到系统日志中(<TTCLASS="FILENAME">/var/log/messages</TT>). 即使不是root用户, 也可以调用<BCLASS="COMMAND">logger</B>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 logger Experiencing instability in network connection at 23:10, 05/21. 2 # 现在, 运行'tail /var/log/messages'.</PRE></FONT></TD></TR></TABLE></P><P>通过在脚本中调用<BCLASS="COMMAND">logger</B>命令, 就可以将调试信息写到<TTCLASS="FILENAME">/var/log/messages</TT>中. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 logger -t $0 -i Logging at line "$LINENO". 2 # "-t"选项可以为日志入口指定标签. 3 # "-i"选项记录进程ID. 4 5 # tail /var/log/message 6 # ... 7 # Jul 7 20:48:58 localhost ./test.sh[1712]: Logging at line 3.</PRE></FONT></TD></TR></TABLE> </P></DD><DT><BCLASS="COMMAND">logrotate</B></DT><DD><P>这个工具用来管理系统的log文件, 可以在合适的时候轮换, 压缩, 删除, 或(和)e-mail它们. 这个工具将从旧的log文件中取得一些杂乱的记录, 并保存到<TTCLASS="FILENAME">/var/log</TT>中. 一般的, 每天都是通过<AHREF="system.html#CRONREF">cron</A>来运行<BCLASS="COMMAND">logrotate</B>. </P><P>在<TTCLASS="FILENAME">/etc/logrotate.conf</TT>中添加合适的入口就可以管理自己的log文件了, 就像管理系统log文件一样. </P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Stefano Falsetto创造了<AHREF="http://www.gnu.org/software/rottlog/"TARGET="_top">rottlog</A>, 他认为这是<BCLASS="COMMAND">logrotate</B>的改进版本. </P></TD></TR></TABLE></DIV></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="JOBCONTROLSYS1"></A>作业控制类</B></P><DL><DT><ANAME="PPSSREF"></A><BCLASS="COMMAND">ps</B></DT><DD><P>进程统计(<TTCLASS="REPLACEABLE"><I>P</I></TT>rocess <TTCLASS="REPLACEABLE"><I>S</I></TT>tatistics): 通过进程宿主或PID(进程ID)来列出当前正在执行的进程. 通常都是使用<CODECLASS="OPTION">ax</CODE>或<CODECLASS="OPTION">aux</CODE>选项来调用这个命令, 并且结果可以通过管道传递到<AHREF="textproc.html#GREPREF">grep</A>或<AHREF="sedawk.html#SEDREF">sed</A>中来搜索特定的进程(请参考<AHREF="internal.html#EX44">例子 11-12</A>和<AHREF="procref1.html#PIDID">例子 27-2</A>). </P><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT"> ps ax | grep sendmail</KBD><SAMPCLASS="COMPUTEROUTPUT">295 ? S 0:00 sendmail: accepting connections on port 25</SAMP></PRE></FONT></TD></TR></TABLE><P>如果想使用<SPANCLASS="QUOTE">"树"</SPAN>的形式来显示系统进程: 那么就使用<BCLASS="COMMAND">ps afjx</B>或<BCLASS="COMMAND">ps ax --forest</B>. </P></DD><DT><BCLASS="COMMAND">pgrep</B>, <BCLASS="COMMAND">pkill</B></DT><DD><P><BCLASS="COMMAND">ps</B>命令可以与<AHREF="textproc.html#GREPREF">grep</A>或<AHREF="x6756.html#KILLREF">kill</A>结合使用. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">ps a | grep mingetty</KBD><SAMPCLASS="COMPUTEROUTPUT">2212 tty2 Ss+ 0:00 /sbin/mingetty tty2 2213 tty3 Ss+ 0:00 /sbin/mingetty tty3 2214 tty4 Ss+ 0:00 /sbin/mingetty tty4 2215 tty5 Ss+ 0:00 /sbin/mingetty tty5 2216 tty6 Ss+ 0:00 /sbin/mingetty tty6 4849 pts/2 S+ 0:00 grep mingetty</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">pgrep mingetty</KBD><SAMPCLASS="COMPUTEROUTPUT">2212 mingetty 2213 mingetty 2214 mingetty 2215 mingetty 2216 mingetty</SAMP> </PRE></FONT></TD></TR></TABLE> </P></DD><DT><BCLASS="COMMAND">pstree</B></DT><DD><P>使用<SPANCLASS="QUOTE">"树"</SPAN>形式列出当前执行的进程. <CODECLASS="OPTION">-p</CODE>选项显示PID, 也就是进程名字. </P></DD><DT><BCLASS="COMMAND">top</B></DT><DD><P>连续不断的显示cpu占有率最高的进程. <CODECLASS="OPTION">-b</CODE>选项将会以文本方式来显示, 以便于可以在脚本中进行分析或访问. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">top -b</KBD><SAMPCLASS="COMPUTEROUTPUT"> 8:30pm up 3 min, 3 users, load average: 0.49, 0.32, 0.13 45 processes: 44 sleeping, 1 running, 0 zombie, 0 stopped CPU states: 13.6% user, 7.3% system, 0.0% nice, 78.9% idle Mem: 78396K av, 65468K used, 12928K free, 0K shrd, 2352K buff Swap: 157208K av, 0K used, 157208K free 37244K cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND 848 bozo 17 0 996 996 800 R 5.6 1.2 0:00 top 1 root 8 0 512 512 444 S 0.0 0.6 0:04 init 2 root 9 0 0 0 0 SW 0.0 0.0 0:00 keventd ...</SAMP> </PRE></FONT></TD></TR></TABLE> </P></DD><DT><BCLASS="COMMAND">nice</B></DT><DD><P>使用经过修改的优先级来运行一个后台作业. 优先级从19(最低)到-20(最高) 只有<EM>root</EM>用户可以设置负的(相对比较高的)优先级. 相关的命令还有<BCLASS="COMMAND">renice</B>, <BCLASS="COMMAND">snice</B>, 和<BCLASS="COMMAND">skill</B>. </P></DD><DT><BCLASS="COMMAND">nohup</B></DT><DD><P>保持一个命令进程处于运行状态, 即使这个命令进程所属的用户登出系统. 这个命令进程将会运行在前台, 除非在它前面加上<SPANCLASS="TOKEN">&</SPAN>. 如果你在脚本中使用<BCLASS="COMMAND">nohup</B>命令, 那么你最好同时使用<AHREF="x6756.html#WAITREF">wait</A>命令, 这样就可以避免产生孤儿进程或僵尸进程. </P></DD><DT><ANAME="PIDOFREF"></A><BCLASS="COMMAND">pidof</B></DT><DD><P>获取一个正在运行作业的<EM>进程ID(PID)</EM>. 因为一些作业控制命令, 比如<AHREF="x6756.html#KILLREF">kill</A>和<BCLASS="COMMAND">renice</B>只能使用进程的<EM>PID</EM>(而不是它的名字)作为参数, 所以有的时候必须得取得<EM>PID</EM>. <BCLASS="COMMAND">pidof</B>命令与<AHREF="internalvariables.html#PPIDREF">$PPID</A>内部变量非常相似. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">pidof xclock</KBD><SAMPCLASS="COMPUTEROUTPUT">880</SAMP> </PRE></FONT></TD></TR></TABLE> </P><DIVCLASS="EXAMPLE"><HR><ANAME="KILLPROCESS"></A><P><B>例子 13-6. 使用<BCLASS="COMMAND">pidof</B>命令帮忙kill一个进程</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # kill-process.sh 3 4 NOPROCESS=2 5 6 process=xxxyyyzzz # 使用不存在的进程. 7 # 只不过是为了演示... 8 # ... 并不想在这个脚本中杀掉任何真正的进程. 9 # 10 # 举个例子, 如果你想使用这个脚本来断线Internet, 11 # process=pppd 12 13 t=`pidof $process` # 取得$process的pid(进程id). 14 # 'kill'只能使用pid(不能用程序名)作为参数. 15 16 if [ -z "$t" ] # 如果没这个进程, 'pidof' 返回空. 17 then 18 echo "Process $process was not running." 19 echo "Nothing killed." 20 exit $NOPROCESS 21 fi 22 23 kill $t # 对于某些顽固的进程可能需要使用'kill -9'. 24 25 # 这里需要做一个检查, 看看进程是否允许自身被kill. 26 # 或许另一个 " t=`pidof $process` " 或许 ... 27 28 29 # 整个脚本都可以使用下边这句来替换: 30 # kill $(pidof -x process_name) 31 # 或者 32 # killall process_name 33 # 但是这就没有教育意义了. 34 35 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">fuser</B></DT><DD><P>或取一个正在访问某个或某些文件(或目录)的进程ID. 使用<CODECLASS="OPTION">-k</CODE>选项将会kill这些进程. 对于系统安全来说, 尤其是在脚本中想阻止未被授权的用户访问系统服务的时候, 这个命令就显得非常有用了. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">fuser -u /usr/bin/vim</KBD><SAMPCLASS="COMPUTEROUTPUT">/usr/bin/vim: 3207e(bozo)</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">fuser -u /dev/null</KBD><SAMPCLASS="COMPUTEROUTPUT">/dev/null: 3009(bozo) 3010(bozo) 3197(bozo) 3199(bozo)</SAMP> </PRE></FONT></TD></TR></TABLE> </P><P>在进行正常插入或删除保存的媒体(比如CD ROM或者USB闪存设备)的时候, <BCLASS="COMMAND">fuser</B>命令非常的有用. 某些情况下, 也就是当你<AHREF="system.html#UMOUNTREF">umount</A>一个设备失败的时候, 会出现<SPANCLASS="ERRORNAME">设备忙</SPAN>错误消息. 这意味着某些用户或进程正在访问这个设备. 可以使用<BCLASS="COMMAND">fuser -um /dev/device_name</B>来解决这种问题, 这样你就可以kill所有相关的进程. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">umount /mnt/usbdrive</KBD><SAMPCLASS="COMPUTEROUTPUT">umount: /mnt/usbdrive: device is busy</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">fuser -um /dev/usbdrive</KBD><SAMPCLASS="COMPUTEROUTPUT">/mnt/usbdrive: 1772c(bozo)</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">kill -9 1772</KBD><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">umount /mnt/usbdrive</KBD> </PRE></FONT></TD></TR></TABLE> </P><P><BCLASS="COMMAND">fuser</B>命令的<CODECLASS="OPTION">-n</CODE>选项可以获得正在访问某一<EM>端口</EM>的进程. 当和<AHREF="system.html#NMAPREF">nmap</A>命令结合使用的时候尤其有用. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">root# </SAMP><KBDCLASS="USERINPUT">nmap localhost.localdomain</KBD><SAMPCLASS="COMPUTEROUTPUT">PORT STATE SERVICE 25/tcp open smtp</SAMP><SAMPCLASS="PROMPT">root# </SAMP><KBDCLASS="USERINPUT">fuser -un tcp 25</KBD><SAMPCLASS="COMPUTEROUTPU
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?