第 17 章 系统和管理命令

位于以下目录的启动和关闭脚本/etc/rc.d展示了许多这些命令的用法(和实用性)。 这些命令通常由 root 调用,用于系统维护或紧急文件系统修复。 请谨慎使用,因为某些命令如果误用可能会损坏您的系统。

用户和组

users

显示所有已登录用户。 这大致相当于 who -q 命令。

groups

列出当前用户及其所属的组。 这对应于 $GROUPS 内部变量,但给出的是组名,而不是数字。

bash$ groups
bozita cdrom cdwriter audio xgrp

bash$ echo $GROUPS
501
chown, chgrp

chown 命令更改文件或文件的所有权。 此命令是 root 可以用来将文件所有权从一个用户转移到另一个用户的有用方法。 普通用户不能更改文件的所有权,即使是自己的文件也不行。 [1]

root# chown bozo *.txt

	      

chgrp 命令更改文件或文件的所有权。 您必须是文件所有者,并且是目标组的成员(或 root)才能使用此操作。

chgrp --recursive dunderheads *.data
#  The "dunderheads" group will now own all the "*.data" files
#+ all the way down the $PWD directory tree (that's what "recursive" means).

useradd, userdel

useradd 管理命令向系统添加用户帐户,并为该特定用户创建主目录(如果已指定)。 相应的 userdel 命令从系统中删除用户帐户 [2] 并删除关联的文件。

Note

adduser 命令是 useradd 的同义词,通常是指向它的符号链接。

usermod

修改用户帐户。 可以更改给定用户帐户的密码、组成员身份、到期日期和其他属性。 使用此命令,可以锁定用户密码,从而达到禁用帐户的效果。

groupmod

修改给定的组。 可以使用此命令更改组名和/或 ID 号。

id

id 命令列出与当前进程关联的用户的真实和有效用户 ID 以及组 ID。 这对应于 $UID$EUID$GROUPS 内部 Bash 变量。

bash$ id
uid=501(bozo) gid=501(bozo) groups=501(bozo),22(cdrom),80(cdwriter),81(audio)

bash$ echo $UID
501

Note

id 命令仅在 有效 ID 与 真实 ID 不同时才显示有效 ID。

另请参见 示例 9-5

lid

lid(list ID)命令显示给定用户所属的组,或者,属于给定组的用户。 只能由 root 调用。

root# lid bozo
 bozo(gid=500)


root# lid daemon
 bin(gid=1)
  daemon(gid=2)
  adm(gid=4)
  lp(gid=7)
	      

who

显示所有登录到系统的用户。

bash$ who
bozo  tty1     Apr 27 17:45
 bozo  pts/0    Apr 27 17:46
 bozo  pts/1    Apr 27 17:47
 bozo  pts/2    Apr 27 17:49
	      

The-m提供有关当前用户的详细信息。 向 who 传递任何两个参数都等同于 who -m,例如 who am iwho The Man

bash$ who -m
localhost.localdomain!bozo  pts/2    Apr 27 17:49
	      

whoami 类似于 who -m,但仅列出用户名。

bash$ whoami
bozo
	      

w

显示所有已登录用户以及属于他们的进程。 这是 who 的扩展版本。 w 的输出可以管道到 grep 以查找特定用户和/或进程。

bash$ w | grep startx
bozo  tty1     -                 4:22pm  6:41   4.47s  0.45s  startx
logname

显示当前用户的登录名(在/var/run/utmp中找到)。 这几乎等同于上面的 whoami

bash$ logname
bozo

bash$ whoami
bozo

然而...

bash$ su
Password: ......

bash# whoami
root
bash# logname
bozo

Note

虽然 logname 打印已登录用户的名称,但 whoami 给出附加到当前进程的用户的名称。 正如我们刚刚看到的,有时它们并不相同。

su

substitute user 身份运行程序或脚本。 su rjones 以用户 rjones 身份启动 shell。 不带参数的 su 默认为 root。 请参阅 示例 A-14

sudo

root(或其他用户)身份运行命令。 这可以在脚本中使用,从而允许 普通用户 运行该脚本。

#!/bin/bash

# Some commands.
sudo cp /root/secretfile /home/bozo/secret
# Some more commands.

文件/etc/sudoers保存允许调用 sudo 的用户的名称。

passwd

设置、更改或管理用户密码。

passwd 命令可以在脚本中使用,但可能不应该使用。

示例 17-1. 设置新密码

#!/bin/bash
#  setnew-password.sh: For demonstration purposes only.
#                      Not a good idea to actually run this script.
#  This script must be run as root.

ROOT_UID=0         # Root has $UID 0.
E_WRONG_USER=65    # Not root?

E_NOSUCHUSER=70
SUCCESS=0


if [ "$UID" -ne "$ROOT_UID" ]
then
  echo; echo "Only root can run this script."; echo
  exit $E_WRONG_USER
else
  echo
  echo "You should know better than to run this script, root."
  echo "Even root users get the blues... "
  echo
fi  


username=bozo
NEWPASSWORD=security_violation

# Check if bozo lives here.
grep -q "$username" /etc/passwd
if [ $? -ne $SUCCESS ]
then
  echo "User $username does not exist."
  echo "No password changed."
  exit $E_NOSUCHUSER
fi  

echo "$NEWPASSWORD" | passwd --stdin "$username"
#  The '--stdin' option to 'passwd' permits
#+ getting a new password from stdin (or a pipe).

echo; echo "User $username's password changed!"

# Using the 'passwd' command in a script is dangerous.

exit 0

passwd 命令的-l, -u-d选项允许锁定、解锁和删除用户密码。 只有 root 可以使用这些选项。

ac

显示用户的登录时间,从/var/log/wtmp读取。 这是 GNU 记帐实用程序之一。

bash$ ac
        total       68.08
last

列出 最近 登录的用户,从/var/log/wtmp读取。 此命令还可以显示远程登录。

例如,要显示系统最近几次重启的时间

bash$ last reboot
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
newgrp

更改用户的 组 ID 而无需注销。 这允许访问新组的文件。 由于用户可以同时是多个组的成员,因此此命令的用途有限。

Note

Kurt Glaesemann 指出,newgrp 命令可能有助于为用户写入的文件设置默认组权限。 但是,chgrp 命令可能更方便用于此目的。

终端

tty

回显当前用户终端的名称(文件名)。 请注意,每个单独的 xterm 窗口都算作一个不同的终端。

bash$ tty
/dev/pts/1
stty

显示和/或更改终端设置。 这个复杂的命令在脚本中使用时,可以控制终端行为和输出显示方式。 请参阅信息页,并仔细研究。

示例 17-2. 设置 擦除 字符

#!/bin/bash
# erase.sh: Using "stty" to set an erase character when reading input.

echo -n "What is your name? "
read name                      #  Try to backspace
                               #+ to erase characters of input.
                               #  Problems?
echo "Your name is $name."

stty erase '#'                 #  Set "hashmark" (#) as erase character.
echo -n "What is your name? "
read name                      #  Use # to erase last character typed.
echo "Your name is $name."

exit 0

# Even after the script exits, the new key value remains set.
# Exercise: How would you reset the erase character to the default value?

示例 17-3. 秘密密码:关闭终端回显

#!/bin/bash
# secret-pw.sh: secret password

echo
echo -n "Enter password "
read passwd
echo "password is $passwd"
echo -n "If someone had been looking over your shoulder, "
echo "your password would have been compromised."

echo && echo  # Two line-feeds in an "and list."


stty -echo    # Turns off screen echo.
#   May also be done with
#   read -sp passwd
#   A big Thank You to Leigh James for pointing this out.

echo -n "Enter password again "
read passwd
echo
echo "password is $passwd"
echo

stty echo     # Restores screen echo.

exit 0

# Do an 'info stty' for more on this useful-but-tricky command.

stty 的一个创造性用途是检测用户按键(无需按 ENTER 键)。

示例 17-4. 按键检测

#!/bin/bash
# keypress.sh: Detect a user keypress ("hot keys").

echo

old_tty_settings=$(stty -g)   # Save old settings (why?).
stty -icanon
Keypress=$(head -c1)          # or $(dd bs=1 count=1 2> /dev/null)
                              # on non-GNU systems

echo
echo "Key pressed was \""$Keypress"\"."
echo

stty "$old_tty_settings"      # Restore old settings.

# Thanks, Stephane Chazelas.

exit 0

另请参见 示例 9-3示例 A-43

setterm

设置某些终端属性。 此命令写入其终端的stdout一个字符串,用于更改该终端的行为。

bash$ setterm -cursor off
bash$
	      

setterm 命令可以在脚本中使用,以更改写入到stdout的文本的外观,尽管肯定有 更好的工具 可用于此目的。

setterm -bold on
echo bold hello

setterm -bold off
echo normal hello

tset

显示或初始化终端设置。 这是功能较弱的 stty 版本。

bash$ tset -r
Terminal type is xterm-xfree86.
 Kill is control-U (^U).
 Interrupt is control-C (^C).
	      

setserial

设置或显示串行端口参数。 此命令必须由 root 运行,通常在系统设置脚本中找到。

# From /etc/pcmcia/serial script:

IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'`
setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ

getty, agetty

终端的初始化过程使用 gettyagetty 将其设置为供用户登录。 这些命令不在用户 shell 脚本中使用。 它们的脚本对应命令是 stty

mesg

启用或禁用对当前用户终端的写入访问权限。 禁用访问权限将阻止网络上的另一个用户 写入 到终端。

Tip

当您正在编辑的文本文件中突然出现关于订购披萨的消息时,可能会非常烦人。 在多用户网络上,您可能因此希望在需要避免中断时禁用对终端的写入访问权限。

wall

这是 "write all" 的首字母缩写,即向登录到网络的每个终端的所有用户发送消息。 它主要是系统管理员的工具,例如,当警告所有人系统由于问题即将关闭时非常有用(请参阅 示例 19-1)。

bash$ wall System going down for maintenance in 5 minutes!
Broadcast message from bozo (pts/1) Sun Jul  8 13:53:27 2001...

 System going down for maintenance in 5 minutes!
	      

Note

如果使用 mesg 禁用了对特定终端的写入访问权限,则 wall 无法向该终端发送消息。

信息和统计

uname

将系统规范(OS、内核版本等)输出到stdout-a选项,提供详细的系统信息(请参阅 示例 16-5)。-s选项仅显示操作系统类型。

bash$ uname
Linux

bash$ uname -s
Linux


bash$ uname -a
Linux iron.bozo 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006
 i686 i686 i386 GNU/Linux
arch

显示系统架构。 等同于 uname -m。 请参阅 示例 11-27

bash$ arch
i686

bash$ uname -m
i686
lastcomm

提供有关先前命令的信息,存储在/var/account/pacct文件中。 可以通过选项指定命令名称和用户名。 这是 GNU 记帐实用程序之一。

lastlog

列出所有系统用户的上次登录时间。 这引用了/var/log/lastlog文件。

bash$ lastlog
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
 bin                                     **Never logged in**
 daemon                                  **Never logged in**
 ...
 bozo          tty1                      Sat Dec  8 21:14:29 -0700 2001



bash$ lastlog | grep root
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
	      

Caution

如果调用它的用户没有读取权限,则此命令将失败。/var/log/lastlog文件。

lsof

列出打开的文件。 此命令输出当前所有打开文件的详细表格,并提供有关其所有者、大小、与其关联的进程等信息。 当然,lsof 可以管道到 grep 和/或 awk 以解析和分析其结果。

bash$ lsof
COMMAND    PID    USER   FD   TYPE     DEVICE    SIZE     NODE NAME
 init         1    root  mem    REG        3,5   30748    30303 /sbin/init
 init         1    root  mem    REG        3,5   73120     8069 /lib/ld-2.1.3.so
 init         1    root  mem    REG        3,5  931668     8075 /lib/libc-2.1.3.so
 cardmgr    213    root  mem    REG        3,5   36956    30357 /sbin/cardmgr
 ...
	      

lsof 命令是一个有用的,但也很复杂的管理工具。 如果您无法卸载文件系统并收到错误消息,提示它仍在被使用,则运行 lsof 有助于确定哪些文件仍在该文件系统上打开。-i选项列出打开的网络套接字文件,这可以帮助跟踪入侵或黑客攻击尝试。

bash$ lsof -an -i tcp
COMMAND  PID USER  FD  TYPE DEVICE SIZE NODE NAME
 firefox 2330 bozo  32u IPv4   9956       TCP 66.0.118.137:57596->67.112.7.104:http ...
 firefox 2330 bozo  38u IPv4  10535       TCP 66.0.118.137:57708->216.79.48.24:http ...
	      

有关 lsof 的有效使用,请参阅 示例 30-2

strace

System trace:用于跟踪 系统调用 和信号的诊断和调试工具。 此命令和下面的 ltrace,可用于诊断给定程序或软件包无法运行的原因...可能是由于缺少库或相关原因。

bash$ strace df
execve("/bin/df", ["df"], [/* 45 vars */]) = 0
 uname({sys="Linux", node="bozo.localdomain", ...}) = 0
 brk(0)                                  = 0x804f5e4

 ...
	    

这是 Linux 等效于 Solaris truss 命令的命令。

ltrace

Library trace:用于跟踪给定命令调用的 库调用 的诊断和调试工具。

bash$ ltrace df
__libc_start_main(0x804a910, 1, 0xbfb589a4, 0x804fb70, 0x804fb68 <unfinished ...>:
 setlocale(6, "")                                 = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils")                          = "coreutils"
__cxa_atexit(0x804b650, 0, 0, 0x8052bf0, 0xbfb58908) = 0
getenv("DF_BLOCK_SIZE")                          = NULL

 ...
	    

nc

ncnetcat)实用程序是用于连接和侦听 TCP 和 UDP 端口的完整工具包。 它可用作诊断和测试工具,以及基于简单脚本的 HTTP 客户端和服务器中的组件。

bash$ nc localhost.localdomain 25
220 localhost.localdomain ESMTP Sendmail 8.13.1/8.13.1;
 Thu, 31 Mar 2005 15:41:35 -0700

一个真实的 用法示例

示例 17-5. 检查远程服务器上的 identd

#! /bin/sh
## Duplicate DaveG's ident-scan thingie using netcat. Oooh, he'll be p*ssed.
## Args: target port [port port port ...]
## Hose stdout _and_ stderr together.
##
##  Advantages: runs slower than ident-scan, giving remote inetd less cause
##+ for alarm, and only hits the few known daemon ports you specify.
##  Disadvantages: requires numeric-only port args, the output sleazitude,
##+ and won't work for r-services when coming from high source ports.
# Script author: Hobbit <hobbit@avian.org>
# Used in ABS Guide with permission.

# ---------------------------------------------------
E_BADARGS=65       # Need at least two args.
TWO_WINKS=2        # How long to sleep.
THREE_WINKS=3
IDPORT=113         # Authentication "tap ident" port.
RAND1=999
RAND2=31337
TIMEOUT0=9
TIMEOUT1=8
TIMEOUT2=4
# ---------------------------------------------------

case "${2}" in
  "" ) echo "Need HOST and at least one PORT." ; exit $E_BADARGS ;;
esac

# Ping 'em once and see if they *are* running identd.
nc -z -w $TIMEOUT0 "$1" $IDPORT || \
{ echo "Oops, $1 isn't running identd." ; exit 0 ; }
#  -z scans for listening daemons.
#     -w $TIMEOUT = How long to try to connect.

# Generate a randomish base port.
RP=`expr $$ % $RAND1 + $RAND2`

TRG="$1"
shift

while test "$1" ; do
  nc -v -w $TIMEOUT1 -p ${RP} "$TRG" ${1} < /dev/null > /dev/null &
  PROC=$!
  sleep $THREE_WINKS
  echo "${1},${RP}" | nc -w $TIMEOUT2 -r "$TRG" $IDPORT 2>&1
  sleep $TWO_WINKS

# Does this look like a lamer script or what . . . ?
# ABS Guide author comments: "Ain't really all that bad . . .
#+                            kinda clever, actually."

  kill -HUP $PROC
  RP=`expr ${RP} + 1`
  shift
done

exit $?

#  Notes:
#  -----

#  Try commenting out line 30 and running this script
#+ with "localhost.localdomain 25" as arguments.

#  For more of Hobbit's 'nc' example scripts,
#+ look in the documentation:
#+ the /usr/share/doc/nc-X.XX/scripts directory.

当然,还有 Andrew Tridgell 博士在 BitKeeper 事件中臭名昭著的单行脚本

echo clone | nc thunk.org 5000 > e2fsprogs.dat

free

以表格形式显示内存和缓存使用情况。 此命令的输出适合使用 grepawkPerl 进行解析。 procinfo 命令显示 free 命令显示的所有信息,以及更多信息。

bash$ free
                total       used       free     shared    buffers     cached
   Mem:         30504      28624       1880      15820       1608       16376
   -/+ buffers/cache:      10640      19864
   Swap:        68540       3128      65412

显示未使用的 RAM 内存

bash$ free | grep Mem | awk '{ print $4 }'
1880
procinfo

/proc 伪文件系统 中提取并列出信息和统计数据。 这提供了非常广泛和详细的列表。

bash$ procinfo | grep Bootup
Bootup: Wed Mar 21 15:15:50 2001    Load average: 0.04 0.21 0.34 3/47 6829
lsdev

列出设备,即显示已安装的硬件。

bash$ lsdev
Device            DMA   IRQ  I/O Ports
 ------------------------------------------------
 cascade             4     2 
 dma                          0080-008f
 dma1                         0000-001f
 dma2                         00c0-00df
 fpu                          00f0-00ff
 ide0                     14  01f0-01f7 03f6-03f6
 ...
	      

du

递归显示(磁盘)文件使用情况。 除非另有说明,否则默认为当前工作目录。

bash$ du -ach
1.0k    ./wi.sh
 1.0k    ./tst.sh
 1.0k    ./random.file
 6.0k    .
 6.0k    total
df

以表格形式显示文件系统使用情况。

bash$ df
Filesystem           1k-blocks      Used Available Use% Mounted on
 /dev/hda5               273262     92607    166547  36% /
 /dev/hda8               222525    123951     87085  59% /home
 /dev/hda7              1408796   1075744    261488  80% /usr
dmesg

将所有系统启动消息列出到stdout。 用于调试和确定安装了哪些设备驱动程序以及正在使用哪些系统中断非常方便。 当然,dmesg 的输出可以使用脚本中的 grepsedawk 进行解析。

bash$ dmesg | grep hda
Kernel command line: ro root=/dev/hda2
 hda: IBM-DLGA-23080, ATA DISK drive
 hda: 6015744 sectors (3080 MB) w/96KiB Cache, CHS=746/128/63
 hda: hda1 hda2 hda3 < hda5 hda6 hda7 > hda4
	      

stat

提供有关给定文件(甚至目录或设备文件)或文件集的详细和冗长的 statistic 信息。

bash$ stat test.cru
  File: "test.cru"
   Size: 49970        Allocated Blocks: 100          Filetype: Regular File
   Mode: (0664/-rw-rw-r--)         Uid: (  501/ bozo)  Gid: (  501/ bozo)
 Device:  3,8   Inode: 18185     Links: 1    
 Access: Sat Jun  2 16:40:24 2001
 Modify: Sat Jun  2 16:40:24 2001
 Change: Sat Jun  2 16:40:24 2001
	      

如果目标文件不存在,stat 将返回错误消息。

bash$ stat nonexistent-file
nonexistent-file: No such file or directory
	      

在脚本中,您可以使用 stat 提取有关文件(和文件系统)的信息,并相应地设置变量。

#!/bin/bash
# fileinfo2.sh

# Per suggestion of Jo�l Bourquard and . . .
# http://www.linuxquestions.org/questions/showthread.php?t=410766


FILENAME=testfile.txt
file_name=$(stat -c%n "$FILENAME")   # Same as "$FILENAME" of course.
file_owner=$(stat -c%U "$FILENAME")
file_size=$(stat -c%s "$FILENAME")
#  Certainly easier than using "ls -l $FILENAME"
#+ and then parsing with sed.
file_inode=$(stat -c%i "$FILENAME")
file_type=$(stat -c%F "$FILENAME")
file_access_rights=$(stat -c%A "$FILENAME")

echo "File name:          $file_name"
echo "File owner:         $file_owner"
echo "File size:          $file_size"
echo "File inode:         $file_inode"
echo "File type:          $file_type"
echo "File access rights: $file_access_rights"

exit 0

sh fileinfo2.sh

File name:          testfile.txt
File owner:         bozo
File size:          418
File inode:         1730378
File type:          regular file
File access rights: -rw-rw-r--

vmstat

显示虚拟内存统计信息。

bash$ vmstat
   procs                      memory    swap          io system         cpu
 r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy id
 0  0  0      0  11040   2636  38952   0   0    33     7  271    88   8   3 89
	    

uptime

显示系统已运行多长时间,以及相关的统计信息。

bash$ uptime
10:28pm  up  1:57,  3 users,  load average: 0.17, 0.34, 0.27

Note

1 或更小的 平均负载 表明系统立即处理进程。 大于 1 的平均负载意味着进程正在排队。 当平均负载超过 3(在单核处理器上)时,系统性能会显着下降。

hostname

列出系统的主机名。 此命令在/etc/rc.d设置脚本中设置主机名(/etc/rc.d/rc.sysinit或类似)。 它等同于 uname -n,并且是 $HOSTNAME 内部变量的对应项。

bash$ hostname
localhost.localdomain

bash$ echo $HOSTNAME
localhost.localdomain

hostname 命令类似的是 domainnamednsdomainnamenisdomainnameypdomainname 命令。 使用这些命令显示或设置系统 DNS 或 NIS/YP 域名。 hostname 的各种选项也执行这些功能。

hostid

回显主机 32 位十六进制数字标识符。

bash$ hostid
7f0100

Note

据称,此命令获取特定系统的 "唯一" 序列号。 某些产品注册程序使用此号码来标记特定的用户许可证。 不幸的是,hostid 仅以十六进制形式返回机器网络地址,并转置字节对。

典型的非联网 Linux 机器的网络地址可以在/etc/hosts.

bash$ cat /etc/hosts
127.0.0.1               localhost.localdomain localhost

中找到。 碰巧的是,转置字节127.0.0.1,我们得到0.127.1.0,它在十六进制中转换为007f0100,这与上面 hostid 返回的结果完全相同。 只有数百万其他 Linux 机器具有相同的 hostid

sar

调用 sar(系统活动报告器)可以非常详细地了解系统统计信息。 Santa Cruz Operation("Old" SCO)于 1999 年 6 月发布了开源的 sar

此命令不是基本 Linux 发行版的一部分,但可以作为 sysstat utilities 软件包的一部分获得,该软件包由 Sebastien Godard 编写。

bash$ sar
Linux 2.4.9 (brooks.seringas.fr) 	09/26/03

10:30:00          CPU     %user     %nice   %system   %iowait     %idle
10:40:00          all      2.21     10.90     65.48      0.00     21.41
10:50:00          all      3.36      0.00     72.36      0.00     24.28
11:00:00          all      1.12      0.00     80.77      0.00     18.11
Average:          all      2.23      3.63     72.87      0.00     21.27

14:32:30          LINUX RESTART

15:00:00          CPU     %user     %nice   %system   %iowait     %idle
15:10:00          all      8.59      2.40     17.47      0.00     71.54
15:20:00          all      4.07      1.00     11.95      0.00     82.98
15:30:00          all      0.79      2.94      7.56      0.00     88.71
Average:          all      6.33      1.70     14.71      0.00     77.26
           
readelf

显示有关指定 elf 二进制文件的信息和统计数据。 这是 binutils 软件包的一部分。

bash$ readelf -h /bin/bash
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)
   . . .
size

size [/path/to/binary] 命令给出二进制可执行文件或存档文件的段大小。 这主要对程序员有用。

bash$ size /bin/bash
   text    data     bss     dec     hex filename
  495971   22496   17392  535859   82d33 /bin/bash
	      

系统日志

logger

将用户生成的消息附加到系统日志(/var/log/messages)。 您不必是 root 才能调用 logger

logger Experiencing instability in network connection at 23:10, 05/21.
# Now, do a 'tail /var/log/messages'.

通过在脚本中嵌入 logger 命令,可以将调试信息写入到/var/log/messages.

logger -t $0 -i Logging at line "$LINENO".
# The "-t" option specifies the tag for the logger entry.
# The "-i" option records the process ID.

# tail /var/log/message
# ...
# Jul  7 20:48:58 localhost ./test.sh[1712]: Logging at line 3.

logrotate

此实用程序管理系统日志文件,根据需要轮换、压缩、删除和/或通过电子邮件发送它们。 这保持了/var/log目录免受旧日志文件 clutter 的影响。 通常,cron 每天运行 logrotate

/etc/logrotate.conf添加适当的条目可以管理个人日志文件以及系统范围的日志文件。

Note

Stefano Falsetto 创建了 rottlog,他认为它是 logrotate 的改进版本。

作业控制

ps

ProcessStatistics:按所有者和 PID(进程 ID)列出当前正在执行的进程。 这通常使用axaux选项调用,并且可以管道到 grepsed 以搜索特定进程(请参阅 示例 15-14示例 29-3)。

bash$  ps ax | grep sendmail
295 ?	   S	  0:00 sendmail: accepting connections on port 25

以图形 "树" 格式显示系统进程:ps afjxps ax --forest

pgrep, pkill

ps 命令与 grepkill 结合使用。

bash$ ps a | grep mingetty
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


bash$ pgrep mingetty
2212 mingetty
 2213 mingetty
 2214 mingetty
 2215 mingetty
 2216 mingetty
	      

比较 pkillkillall 的操作。

pstree

"树" 格式列出当前正在执行的进程。-p选项显示 PID 以及进程名称。

top

持续更新显示最占用 CPU 的进程。-b选项以文本模式显示,以便可以从脚本中解析或访问输出。

bash$ top -b
  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
   ...  
	      

nice

以更改的优先级运行后台作业。 优先级范围从 19(最低)到 -20(最高)。 只有 root 可以设置负(更高)优先级。 相关命令是 renicesnice,它们更改正在运行的进程或多个进程的优先级,以及 skill,它向一个或多个进程发送 kill 信号。

nohup

即使在用户注销后也保持命令运行。 除非后跟 &,否则该命令将作为前台进程运行。 如果在脚本中使用 nohup,请考虑将其与 wait 结合使用,以避免创建 孤立僵尸 进程。

pidof

标识正在运行的作业的 进程 ID (PID)。 由于作业控制命令(例如 killrenice)作用于进程的 PID(而不是其名称),因此有时需要标识该 PIDpidof 命令大致对应于 $PPID 内部变量。

bash$ pidof xclock
880
	      

示例 17-6. pidof 帮助终止进程

#!/bin/bash
# kill-process.sh

NOPROCESS=2

process=xxxyyyzzz  # Use nonexistent process.
# For demo purposes only...
# ... don't want to actually kill any actual process with this script.
#
# If, for example, you wanted to use this script to logoff the Internet,
#     process=pppd

t=`pidof $process`       # Find pid (process id) of $process.
# The pid is needed by 'kill' (can't 'kill' by program name).

if [ -z "$t" ]           # If process not present, 'pidof' returns null.
then
  echo "Process $process was not running."
  echo "Nothing killed."
  exit $NOPROCESS
fi  

kill $t                  # May need 'kill -9' for stubborn process.

# Need a check here to see if process allowed itself to be killed.
# Perhaps another " t=`pidof $process` " or ...


# This entire script could be replaced by
#        kill $(pidof -x process_name)
# or
#        killall process_name
# but it would not be as instructive.

exit 0
fuser

标识(按 PID)正在访问给定文件、文件集或目录的进程。 也可以使用-k选项调用,该选项会终止这些进程。 这对系统安全具有有趣的意义,尤其是在阻止未经授权的用户访问系统服务的脚本中。

bash$ fuser -u /usr/bin/vim
/usr/bin/vim:         3207e(bozo)



bash$ fuser -u /dev/null
/dev/null:            3009(bozo)  3010(bozo)  3197(bozo)  3199(bozo)
	      

fuser 的一个重要应用是在物理插入或移除存储介质(例如 CD ROM 光盘或 USB 闪存驱动器)时。 有时尝试 umount 会失败,并显示 设备繁忙 错误消息。 这意味着某些用户和/或进程正在访问该设备。 fuser -um /dev/device_name 将解开谜团,以便您可以终止任何相关进程。

bash$ umount /mnt/usbdrive
umount: /mnt/usbdrive: device is busy



bash$ fuser -um /dev/usbdrive
/mnt/usbdrive:        1772c(bozo)

bash$ kill -9 1772
bash$ umount /mnt/usbdrive
	      

使用-n选项调用的 fuser 命令,标识访问 端口 的进程。 这在与 nmap 结合使用时特别有用。

root# nmap localhost.localdomain
PORT     STATE SERVICE
 25/tcp   open  smtp



root# fuser -un tcp 25
25/tcp:               2095(root)

root# ps ax | grep 2095 | grep -v grep
2095 ?        Ss     0:00 sendmail: accepting connections
	      

cron

管理程序调度器,执行诸如清理和删除系统日志文件以及更新 slocate 数据库等任务。 这是 at超级用户 版本(尽管每个用户都可以有自己的crontab文件,可以使用 crontab 命令更改它)。 它作为 守护程序 运行,并从/etc/crontab.

Note

执行计划条目。 某些 Linux 版本运行 crond,即 Matthew Dillon 版本的 cron

进程控制和启动

init

init 命令是所有进程的 父进程。 在启动的最后一步调用,init/etc/inittab确定系统的运行级别。 由其别名 telinit 和仅由 root 调用。

telinit

符号链接到 init,这是一种更改系统运行级别的方法,通常用于系统维护或紧急文件系统修复。 仅由 root 调用。 此命令可能很危险 - 在使用前请务必充分理解它!

runlevel

显示当前和上次运行级别,即系统是否已停止(运行级别0),在单用户模式下(1),在多用户模式下(23),在 X Windows 中(5),或重启中(6)。 此命令访问/var/run/utmp文件。

halt, shutdown, reboot

命令集用于关闭系统,通常在断电之前。

Warning

在某些 Linux 发行版中,halt 命令具有 755 权限,因此可以由非 root 用户调用。 终端或脚本中不小心的 halt 可能会关闭系统!

service

启动或停止系统 服务。 位于/etc/init.d/etc/rc.d中的启动脚本使用此命令在启动时启动服务。

root# /sbin/service iptables stop
Flushing firewall rules:                                   [  OK  ]
 Setting chains to policy ACCEPT: filter                    [  OK  ]
 Unloading iptables modules:                                [  OK  ]
	      

网络

nmap

Network mapper 和端口扫描器。 此命令扫描服务器以查找打开的端口以及与这些端口关联的服务。 它还可以报告有关数据包过滤器和防火墙的信息。 这是一个重要的安全工具,用于锁定网络以防止黑客攻击。

#!/bin/bash

SERVER=$HOST                           # localhost.localdomain (127.0.0.1).
PORT_NUMBER=25                         # SMTP port.

nmap $SERVER | grep -w "$PORT_NUMBER"  # Is that particular port open?
#              grep -w matches whole words only,
#+             so this wouldn't match port 1025, for example.

exit 0

# 25/tcp     open        smtp

ifconfig

网络 接口配置 和调整实用程序。

bash$ ifconfig -a
lo        Link encap:Local Loopback
           inet addr:127.0.0.1  Mask:255.0.0.0
           UP LOOPBACK RUNNING  MTU:16436  Metric:1
           RX packets:10 errors:0 dropped:0 overruns:0 frame:0
           TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0 
           RX bytes:700 (700.0 b)  TX bytes:700 (700.0 b)

ifconfig 命令最常在启动时用于设置接口,或在重新启动时关闭接口。

# Code snippets from /etc/rc.d/init.d/network

# ...

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

[ -x /sbin/ifconfig ] || exit 0

# ...

for i in $interfaces ; do
  if ifconfig $i 2>/dev/null | grep -q "UP" >/dev/null 2>&1 ; then
    action "Shutting down interface $i: " ./ifdown $i boot
  fi
#  The GNU-specific "-q" option to "grep" means "quiet", i.e.,
#+ producing no output.
#  Redirecting output to /dev/null is therefore not strictly necessary.
       
# ...

echo "Currently active devices:"
echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'`
#                            ^^^^^  should be quoted to prevent globbing.
#  The following also work.
#    echo $(/sbin/ifconfig | awk '/^[a-z]/ { print $1 })'
#    echo $(/sbin/ifconfig | sed -e 's/ .*//')
#  Thanks, S.C., for additional comments.

另请参见 示例 32-6

netstat

显示当前网络统计信息和信息,例如路由表和活动连接。 此实用程序访问/proc/net第 29 章)中的信息。 请参阅 示例 29-4

netstat -r 等同于 route

bash$ netstat
Active Internet connections (w/o servers)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State      
 Active UNIX domain sockets (w/o servers)
 Proto RefCnt Flags       Type       State         I-Node Path
 unix  11     [ ]         DGRAM                    906    /dev/log
 unix  3      [ ]         STREAM     CONNECTED     4514   /tmp/.X11-unix/X0
 unix  3      [ ]         STREAM     CONNECTED     4513
 . . .

Note

netstat -lptu 显示正在侦听端口的 套接字 以及关联的进程。 这对于确定计算机是否已被黑客入侵或受损非常有用。

iwconfig

这是用于配置无线网络的命令集。 它是上面 ifconfig 的无线等效命令。

ip

用于设置、更改和分析 IP(互联网协议)网络和连接设备的多用途实用程序。 此命令是 iproute2 软件包的一部分。

bash$ ip link show
1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue 
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:d0:59:ce:af:da brd ff:ff:ff:ff:ff:ff
 3: sit0: <NOARP> mtu 1480 qdisc noop 
     link/sit 0.0.0.0 brd 0.0.0.0


bash$ ip route list
169.254.0.0/16 dev lo  scope link
	      

或者,在脚本中

#!/bin/bash
# Script by Juan Nicolas Ruiz
# Used with his kind permission.

# Setting up (and stopping) a GRE tunnel.


# --- start-tunnel.sh ---

LOCAL_IP="192.168.1.17"
REMOTE_IP="10.0.5.33"
OTHER_IFACE="192.168.0.100"
REMOTE_NET="192.168.3.0/24"

/sbin/ip tunnel add netb mode gre remote $REMOTE_IP \
  local $LOCAL_IP ttl 255
/sbin/ip addr add $OTHER_IFACE dev netb
/sbin/ip link set netb up
/sbin/ip route add $REMOTE_NET dev netb

exit 0  #############################################

# --- stop-tunnel.sh ---

REMOTE_NET="192.168.3.0/24"

/sbin/ip route del $REMOTE_NET dev netb
/sbin/ip link set netb down
/sbin/ip tunnel del netb

exit 0

route

显示有关内核路由表的信息或对其进行更改。

bash$ route
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
 pm3-67.bozosisp *               255.255.255.255 UH       40 0          0 ppp0
 127.0.0.0       *               255.0.0.0       U        40 0          0 lo
 default         pm3-67.bozosisp 0.0.0.0         UG       40 0          0 ppp0
	      

iptables

iptables 命令集是一种数据包过滤工具,主要用于设置网络防火墙等安全目的。 这是一个复杂的工具,详细解释其用法超出了本文档的范围。 Oskar Andreasson 的教程 是一个合理的起点。

另请参见 关闭 iptables示例 30-2

chkconfig

检查网络和系统配置。 此命令列出和管理在启动时在/etc/rc?.d目录中启动的网络和系统服务。

chkconfig 最初是从 IRIX 移植到 Red Hat Linux 的,可能不是某些 Linux 版本核心安装的一部分。

bash$ chkconfig --list
atd             0:off   1:off   2:off   3:on    4:on    5:on    6:off
 rwhod           0:off   1:off   2:off   3:off   4:off   5:off   6:off
 ...
	      

tcpdump

网络数据包 "嗅探器"。 这是一种通过转储与指定条件匹配的数据包标头来分析和排除网络流量故障的工具。

转储主机 bozovillecaduceus 之间的 ip 数据包流量

bash$ tcpdump ip host bozoville and caduceus
	      

当然,tcpdump 的输出可以使用前面讨论过的某些 文本处理实用程序 进行解析。

文件系统

mount

挂载文件系统,通常在外部设备上,例如软盘或 CDROM。 文件/etc/fstab提供了一个方便的可用文件系统、分区和设备列表,包括可以自动或手动挂载的选项。文件/etc/mtab显示当前已挂载的文件系统和分区(包括虚拟文件系统和分区,例如/proc).

mount -a 挂载 中列出的所有文件系统和分区/etc/fstab,除了那些带有noauto选项的。在启动时,/etc/rc.d (rc.sysinit或类似的启动脚本会调用此命令以挂载所有内容。

mount -t iso9660 /dev/cdrom /mnt/cdrom
# Mounts CD ROM. ISO 9660 is a standard CD ROM filesystem.
mount /mnt/cdrom
# Shortcut, if /mnt/cdrom listed in /etc/fstab

通用的 mount 命令甚至可以将普通文件挂载到块设备上,并且该文件将像文件系统一样运行。Mount 通过将文件与 回环设备 关联来实现这一点。 这种应用之一是在将其刻录到 CDR 上之前挂载并检查 ISO9660 文件系统镜像。[3]

示例 17-7. 检查 CD 镜像

# As root...

mkdir /mnt/cdtest  # Prepare a mount point, if not already there.

mount -r -t iso9660 -o loop cd-image.iso /mnt/cdtest   # Mount the image.
#                  "-o loop" option equivalent to "losetup /dev/loop0"
cd /mnt/cdtest     # Now, check the image.
ls -alR            # List the files in the directory tree there.
                   # And so forth.
umount

卸载当前已挂载的文件系统。在物理移除先前挂载的软盘或 CDROM 光盘之前,必须先 umount 设备,否则可能会导致文件系统损坏。

umount /mnt/cdrom
# You may now press the eject button and safely remove the disk.

Note

如果正确安装了 automount 实用程序,则可以在访问或移除软盘或 CDROM 光盘时自动挂载和卸载它们。 但是,在带有可更换软盘和光驱的 "多轴" 笔记本电脑上,这可能会导致问题。

gnome-mount

较新的 Linux 发行版已弃用 mountumount。 对于可移动存储设备的命令行挂载,后继者是 gnome-mount。 它可以接受-d选项,以通过其在/dev.

中的列表来挂载 设备文件

bash$ gnome-mount -d /dev/sda1
gnome-mount 0.4


bash$ df
. . .
 /dev/sda1                63584     12034     51550  19% /media/disk
 

例如,要挂载 USB 闪存驱动器

sync强制立即将所有更新的数据从缓冲区写入硬盘(将驱动器与缓冲区同步)。 虽然不是绝对必要,但 sync 可以向系统管理员或用户保证,刚刚更改的数据将在突然断电的情况下幸存下来。 在过去,sync; sync

(两次,只是为了绝对确保)是在系统重启之前有用的预防措施。

有时,您可能希望强制立即刷新缓冲区,例如在安全删除文件时(请参阅 示例 16-61)或当灯光开始闪烁时。

losetup

设置和配置 回环设备

SIZE=1000000  # 1 meg

head -c $SIZE < /dev/zero > file  # Set up file of designated size.
losetup /dev/loop0 file           # Set it up as loopback device.
mke2fs /dev/loop0                 # Create filesystem.
mount -o loop /dev/loop0 /mnt     # Mount it.

# Thanks, S.C.
示例 17-8. 在文件中创建文件系统

mkswap

创建交换分区或文件。 交换区随后必须通过 swapon 启用。

swapon, swapoff

启用/禁用交换分区或文件。 这些命令通常在启动和关机时生效。

mke2fs

创建 Linux ext2 文件系统。 此命令必须以 root 身份调用。

#!/bin/bash

# Adding a second hard drive to system.
# Software configuration. Assumes hardware already mounted.
# From an article by the author of the ABS Guide.
# In issue #38 of _Linux Gazette_, http://www.linuxgazette.com.

ROOT_UID=0     # This script must be run as root.
E_NOTROOT=67   # Non-root exit error.

if [ "$UID" -ne "$ROOT_UID" ]
then
  echo "Must be root to run this script."
  exit $E_NOTROOT
fi  

# Use with extreme caution!
# If something goes wrong, you may wipe out your current filesystem.


NEWDISK=/dev/hdb         # Assumes /dev/hdb vacant. Check!
MOUNTPOINT=/mnt/newdisk  # Or choose another mount point.


fdisk $NEWDISK
mke2fs -cv $NEWDISK1   # Check for bad blocks (verbose output).
#  Note:           ^     /dev/hdb1, *not* /dev/hdb!
mkdir $MOUNTPOINT
chmod 777 $MOUNTPOINT  # Makes new drive accessible to all users.


# Now, test ...
# mount -t ext2 /dev/hdb1 /mnt/newdisk
# Try creating a directory.
# If it works, umount it, and proceed.

# Final step:
# Add the following line to /etc/fstab.
# /dev/hdb1  /mnt/newdisk  ext2  defaults  1 1

exit

示例 17-9. 添加新硬盘驱动器

另请参阅 示例 17-8示例 31-3

mkdosfs

创建 DOS FAT 文件系统。

tune2fs

Warning

调整 ext2 文件系统。 可用于更改文件系统参数,例如最大挂载计数。 这必须以 root 身份调用。

这是一个极其危险的命令。 使用风险自负,因为您可能会在不经意间破坏您的文件系统。

dumpe2fsstdout转储(列表到

root# dumpe2fs /dev/hda7 | grep 'ount count'
dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
 Mount count:              6
 Maximum mount count:      20
)非常详细的文件系统信息。 这必须以 root 身份调用。

hdparm

列出或更改硬盘参数。 此命令必须以 root 身份调用,如果误用,可能会很危险。

fdisk

Warning

在存储设备(通常是硬盘驱动器)上创建或更改分区表。 此命令必须以 root 身份调用。

请极其谨慎地使用此命令。 如果出现问题,您可能会破坏现有文件系统。

fsck, e2fsck, debugfs

文件系统检查、修复和调试命令集。

fsck:用于检查 UNIX 文件系统的前端(可能会调用其他实用程序)。 实际文件系统类型通常默认为 ext2

e2fsck:ext2 文件系统检查器。

Caution

debugfs:ext2 文件系统调试器。 这个通用但危险的命令的用途之一是(尝试)恢复已删除的文件。 仅供高级用户使用!

所有这些都应以 root 身份调用,如果误用,它们可能会损坏或破坏文件系统。

badblocks

检查存储设备上的坏块(物理介质缺陷)。 此命令在新安装硬盘驱动器时或测试备份介质的完整性时会很有用。[4] 例如,badblocks /dev/fd0 测试软盘。

badblocks 命令可以破坏性地调用(覆盖所有数据)或以非破坏性只读模式调用。 如果 root 用户 拥有要测试的设备(通常是这种情况),则 root 必须调用此命令。

lsusb, usbmodules

lsusb 命令列出所有 USB(通用串行总线)总线以及连接到它们的设备。

bash$ lsusb
Bus 001 Device 001: ID 0000:0000  
 Device Descriptor:
   bLength                18
   bDescriptorType         1
   bcdUSB               1.00
   bDeviceClass            9 Hub
   bDeviceSubClass         0 
   bDeviceProtocol         0 
   bMaxPacketSize0         8
   idVendor           0x0000 
   idProduct          0x0000

   . . .
	      

usbmodules 命令输出有关已连接 USB 设备的驱动程序模块的信息。

lspci

bash$ lspci
00:00.0 Host bridge: Intel Corporation 82845 845
 (Brookdale) Chipset Host Bridge (rev 04)
 00:01.0 PCI bridge: Intel Corporation 82845 845
 (Brookdale) Chipset AGP Bridge (rev 04)
 00:1d.0 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #1) (rev 02)
 00:1d.1 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #2) (rev 02)
 00:1d.2 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #3) (rev 02)
 00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 42)

   . . .
	      

列出存在的 pci 总线。

mkbootdisk创建可用于启动系统的启动软盘,例如,如果 MBR(主引导记录)损坏。 特别值得关注的是--iso

选项,该选项使用 mkisofs 创建适合刻录可引导 CDR 的可引导 ISO9660 文件系统镜像。mkbootdisk 命令实际上是一个 Bash 脚本,由 Erik Troan 编写,位于目录中启动的网络和系统服务。

/sbin

mkisofs

创建适用于 CDR 镜像的 ISO9660 文件系统。

chroot/更改 ROOT 目录。 通常,命令从相对于

$PATH默认 根目录 中获取。 这会将 root 目录更改为另一个目录(并将工作目录也更改到那里)。 这对于安全目的很有用,例如,当系统管理员希望将某些用户(例如通过 telnet 登录的用户)限制在文件系统的安全部分时(有时称为将访客用户限制在 "chroot 监狱" 中)。 请注意,在 chroot 之后,系统二进制文件的执行路径不再有效。Achroot /opt将导致对/usr/bin的引用被转换为/opt/usr/bin。 同样地,chroot /aaa/bbb /bin/ls会将 ls 的未来实例重定向到//aaa/bbb

作为基本目录,而不是通常的情况。 用户 ~/.bashrc 中的 alias XX 'chroot /aaa/bbb ls' 有效地限制了她可以在文件系统的哪个部分运行命令 "XX"chroot 命令在从紧急启动软盘运行时(chroot

Caution

/dev/fd0),或者作为从系统崩溃中恢复时 lilo 的一个选项也很方便。 其他用途包括从不同的文件系统安装(rpm 选项)或从 CD ROM 运行只读文件系统。 仅以 root 身份调用,并谨慎使用。可能需要将某些系统文件复制到 chrooted 目录,因为正常的

$PATH

不再可靠。

定义

lockfile /home/bozo/lockfiles/$0.lock
# Creates a write-protected lockfile prefixed with the name of the script.

lockfile /home/bozo/lockfiles/${0##*/}.lock
# A safer version of the above, as pointed out by E. Choroba.

信号量 是一个标志或信号。 (用法起源于铁路运输,其中彩色旗帜、灯笼或条纹可移动臂 信号量 指示特定轨道是否正在使用,因此其他火车无法使用。) UNIX 进程可以检查适当的信号量以确定特定资源是否可用/可访问。

锁文件充当标志,表明此特定文件、设备或资源正在被进程使用(因此 "忙碌")。 锁文件的存在允许对其他进程进行受限访问(或无访问)。锁文件用于诸如保护系统邮件文件夹免受多个用户同时更改、指示调制解调器端口正在被访问以及显示 Firefox 实例正在使用其缓存之类的应用程序中。 脚本可以检查由特定进程创建的锁文件的存在,以检查该进程是否正在运行。 请注意,如果脚本尝试创建已存在的锁文件,则脚本可能会挂起。通常,应用程序在

appname=xyzip
# Application "xyzip" created lock file "/var/lock/xyzip.lock".

if [ -e "/var/lock/$appname.lock" ]
then   #+ Prevent other programs & scripts
       #  from accessing files/resources used by xyzip.
  ...

/var/lock

目录中创建和检查锁文件。[5] 脚本可以通过如下方式测试锁文件的存在。

flock $0 cat $0 > lockfile__$0
#  Set a lock on the script the above line appears in,
#+ while listing the script to stdout.

Note

flock

lockfile 命令用处小得多的是 flock。 它在文件上设置 "咨询" 锁,然后在锁定时执行命令。 这是为了防止任何其他进程在该文件上设置锁,直到指定命令完成为止。

lockfile 不同,flock 会自动创建锁文件。

mknod

创建块或字符 设备文件(在系统上安装新硬件时可能需要)。 MAKEDEV 实用程序几乎具有 mknod 的所有功能,并且更易于使用。/devMAKEDEV

用于创建设备文件的实用程序。 它必须以 root 身份运行,并且在

目录中运行。 它是 mknod 的一种高级版本。

tmpwatch

自动删除在指定时间段内未访问的文件。 通常由 cron 调用以删除过时的日志文件。

备份

dump, restore

dump 命令是一个精细的文件系统备份实用程序,通常用于较大的安装和网络中。[6] 它读取原始磁盘分区并以二进制格式写入备份文件。 要备份的文件可以保存到各种存储介质,包括磁盘和磁带驱动器。 restore 命令恢复使用 dump 进行的备份。fdformat).

对软盘执行低级格式化 (

/dev/fd0*

系统资源ulimit设置系统资源使用的 上限。 通常与-f选项一起调用,该选项设置文件大小的限制(ulimit -f 1000 将文件限制为最大 1 兆字节)。[7]-t选项限制核心转储大小(ulimit -c 0 消除核心转储)。 通常,ulimit 的值将在/etc/profile和/或

Important

~/.bash_profile

#!/bin/bash
# This script is for illustrative purposes only.
# Run it at your own peril -- it WILL freeze your system.

while true  #  Endless loop.
do
  $0 &      #  This script invokes itself . . .
            #+ forks an infinite number of times . . .
            #+ until the system freezes up because all resources exhausted.
done        #  This is the notorious "sorcerer's appentice" scenario.

exit 0      #  Will not exit here, because this script will never terminate.

中设置(请参阅 附录 H)。-t明智地使用 ulimit 可以保护系统免受可怕的 fork 炸弹 的侵害。

ulimit -Hu XX (其中 XX 是用户进程限制)

中,当脚本超出预设限制时,将中止该脚本。

quota

显示用户或组磁盘配额。

setquota-t选项限制核心转储大小(ulimit -c 0 消除核心转储)。 通常,ulimit 的值将在/etc/profile和/或

从命令行设置用户或组磁盘配额。

#!/bin/bash
# rot13a.sh: Same as "rot13.sh" script, but writes output to "secure" file.

# Usage: ./rot13a.sh filename
# or     ./rot13a.sh <filename
# or     ./rot13a.sh and supply keyboard input (stdin)

umask 177               #  File creation mask.
                        #  Files created by this script
                        #+ will have 600 permissions.

OUTFILE=decrypted.txt   #  Results output to file "decrypted.txt"
                        #+ which can only be read/written
                        #  by invoker of script (or root).

cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M' > $OUTFILE 
#    ^^ Input from stdin or a file.   ^^^^^^^^^^ Output redirected to file. 

exit 0
umask

用户文件创建权限 掩码。 限制特定用户的默认文件属性。 由该用户创建的所有文件都将采用由 umask 指定的属性。 传递给 umask 的(八进制)值定义了 禁用的 文件权限。 例如,umask 022 确保新文件最多具有 755 权限(777 NAND 022)。[8] 当然,用户稍后可以使用 chmod 更改特定文件的属性。 通常的做法是在

中设置 umask 的值。

示例 17-10. 使用 umask 隐藏输出文件,防止窥探

rdev

bash$ lsmod
Module                  Size  Used by
 autofs                  9456   2 (autoclean)
 opl3                   11376   0
 serial_cs               5456   0 (unused)
 sb                     34752   0
 uart401                 6384   0 [sb]
 sound                  58368   0 [opl3 sb uart401]
 soundlow                 464   0 [sound]
 soundcore               2800   6 [sb sound]
 ds                      6448   2 [serial_cs]
 i82365                 22928   2
 pcmcia_core            45984   0 [serial_cs ds i82365]
	      

Note

获取有关根设备、交换空间或视频模式的信息或对其进行更改。 rdev 的功能通常已被 lilo 接管,但 rdev 对于设置内存盘仍然有用。 如果误用,这是一个危险的命令。

模块

lsmod

列出已安装的内核模块。

执行 cat /proc/modules 会给出相同的信息。

insmod

强制安装内核模块(尽可能使用 modprobe 代替)。 必须以 root 身份调用。

rmmod

强制卸载内核模块。 必须以 root 身份调用。

modprobe

模块加载器,通常在启动脚本中自动调用。 必须以 root 身份调用。

bash$ modinfo hid
filename:    /lib/modules/2.4.20-6/kernel/drivers/usb/hid.o
 description: "USB HID support drivers"
 author:      "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
 license:     "GPL"
	      

depmod

创建模块依赖文件。 通常从启动脚本调用。

modinfo输出有关可加载模块的信息。杂项env使用设置或更改的某些 环境变量 运行程序或脚本(而不更改整体系统环境)。

Note

[varname=xxx]

#! /usr/bin/env perl

print "This Perl script will run,\n";
print "even when I don't know where to find Perl.\n";

# Good for portable cross-platform scripts,
# where the Perl binaries may not be in the expected place.
# Thanks, S.C.

允许更改环境变量

#!/bin/env bash
# Queries the $PATH enviromental variable for the location of bash.
# Therefore ...
# This script will run where Bash is not in its usual place, in /bin.
...

varname

以用于脚本的持续时间。 如果未指定任何选项,则此命令列出所有环境变量设置。[9]

bash$ ldd /bin/ls
libc.so.6 => /lib/libc.so.6 (0x4000c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
脚本的第一行("sha-bang" 行)可以在不知道 shell 或解释器路径时使用 env

甚至 ...

ldd-n显示可执行文件的共享库依赖项。

watch -n 5 tail /var/log/messages
# Shows tail end of system log, /var/log/messages, every five seconds.

Note

watch

以指定的时间间隔重复运行命令。

默认间隔为两秒,但可以使用

选项进行更改。

不幸的是,将 watch command 的输出 管道 传输到 grep 无效。

strip

从可执行二进制文件中删除调试符号引用。 这会减小其大小,但使其无法进行调试。

此命令通常出现在 Makefile 中,但很少出现在 shell 脚本中。

nm

#!/bin/bash
# backlight.sh
# reldate 02dec2011

#  A bug in Fedora Core 16/17 messes up the keyboard backlight controls.
#  This script is a quick-n-dirty workaround, essentially a shell wrapper
#+ for xrandr. It gives more control than on-screen sliders and widgets.

OUTPUT=$(xrandr | grep LV | awk '{print $1}')   # Get display name!
INCR=.05      # For finer-grained control, set INCR to .03 or .02.

old_brightness=$(xrandr --verbose | grep rightness | awk '{ print $2 }')


if [ -z "$1" ]
then
  bright=1    # If no command-line arg, set brightness to 1.0 (default).

  else
    if [ "$1" = "+" ]
    then
      bright=$(echo "scale=2; $old_brightness + $INCR" | bc)   # +.05

  else
    if [ "$1" = "-" ]
    then
      bright=$(echo "scale=2; $old_brightness - $INCR" | bc)   # -.05

  else
    if [ "$1" = "#" ]   # Echoes current brightness; does not change it.
    then
      bright=$old_brightness

  else
    if [[ "$1" = "h" || "$1" = "H" ]]
    then
      echo
      echo "Usage:"
      echo "$0 [No args]    Sets/resets brightness to default (1.0)."
      echo "$0 +            Increments brightness by 0.5."
      echo "$0 -            Decrements brightness by 0.5."
      echo "$0 #            Echoes current brightness without changing it."
      echo "$0 N (number)   Sets brightness to N (useful range .7 - 1.2)."
      echo "$0 h [H]        Echoes this help message."
      echo "$0 any-other    Gives xrandr usage message."

      bright=$old_brightness

  else
    bright="$1"

      fi
     fi
    fi
  fi
fi


xrandr --output "$OUTPUT" --brightness "$bright"   # See xrandr manpage.
                                                   # As root!
E_CHANGE0=$?
echo "Current brightness = $bright"

exit $E_CHANGE0


# =========== Or, alternately . . . ==================== #

#!/bin/bash
# backlight2.sh
# reldate 20jun2012

#  A bug in Fedora Core 16/17 messes up the keyboard backlight controls.
#  This is a quick-n-dirty workaround, an alternate to backlight.sh.

target_dir=\
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/backlight/acpi_video0
# Hardware directory.

actual_brightness=$(cat $target_dir/actual_brightness)
max_brightness=$(cat $target_dir/max_brightness)
Brightness=$target_dir/brightness

let "req_brightness = actual_brightness"   # Requested brightness.

if [ "$1" = "-" ]
then     # Decrement brightness 1 notch.
  let "req_brightness = $actual_brightness - 1"
else
  if [ "$1" = "+" ]
  then   # Increment brightness 1 notch.
    let "req_brightness = $actual_brightness + 1"
   fi
fi

if [ $req_brightness -gt $max_brightness ]
then
  req_brightness=$max_brightness
fi   # Do not exceed max. hardware design brightness.

echo

echo "Old brightness = $actual_brightness"
echo "Max brightness = $max_brightness"
echo "Requested brightness = $req_brightness"
echo

# =====================================
echo $req_brightness > $Brightness
# Must be root for this to take effect.
E_CHANGE1=$?   # Successful?
# =====================================

if [ "$?" -eq 0 ]
then
  echo "Changed brightness!"
else
  echo "Failed to change brightness!"
fi

act_brightness=$(cat $Brightness)
echo "Actual brightness = $act_brightness"

scale0=2
sf=100 # Scale factor.
pct=$(echo "scale=$scale0; $act_brightness / $max_brightness * $sf" | bc)
echo "Percentage brightness = $pct%"

exit $E_CHANGE1
列出未剥离的编译二进制文件中的符号。

xrandr

用于操作屏幕根窗口的命令行工具。

[1]

示例 17-11. Backlight:更改(笔记本电脑)屏幕背光的亮度

[2]

rdist

[3]

远程分发客户端:同步、克隆或备份远程服务器上的文件系统。

[4]

The注释这是 Linux 机器或具有磁盘配额的 UNIX 系统上的情况。

[5]

如果要删除的特定用户仍在登录,则 userdel 命令将失败。锁文件用于诸如保护系统邮件文件夹免受多个用户同时更改、指示调制解调器端口正在被访问以及显示 Firefox 实例正在使用其缓存之类的应用程序中。 脚本可以检查由特定进程创建的锁文件的存在,以检查该进程是否正在运行。 请注意,如果脚本尝试创建已存在的锁文件,则脚本可能会挂起。有关刻录 CDR 的更多详细信息,请参阅 Alex Withers 的文章 Creating CDs,《Linux Journal》1999 年 10 月号。

[6]

mke2fs

[7]

-culimit注释选项也会调用对坏块的检查。-b由于只有 root 具有在目录中写入的权限,因此用户脚本无法在那里设置锁文件。单用户 Linux 系统的操作员通常更喜欢更简单的备份方式,例如 tar

[8]

截至 Bash 的 版本 4 更新

[9]

选项在 POSIX 模式下采用 512 的块大小。 此外,还有两个新选项

var1=value1 var2=value2 commandXXX
# $var1 and $var2 set in the environment of 'commandXXX' only.