写shell脚本 printf,在命令行输入AAA BBB,使用printf命令输出,输出格式为

1.& Shell中的变量类型
Shell中的变量可以分为环境变量、位置变量、预定义的特殊变量以及用户自定义变量、
&!--[if !supportLists]--&2.& &!--[endif]--&环境变量
Shell中的环境变量是一类Shell预定义变量,是用于设置系统运行环境的变量,环境变量由系统统一命名。部分系统变量的值由系统设定,部分环境变量的值可以由用户给定。
环境变量的名称由大写字母组成,常用的Shell环境变量如下所示:
HOME: 用户主目录的全路径名,cd $HOME 即可切换到用户的主目录
PATH: 类似于windows下的路径,Shell会在里面依次寻找二进制的可执行文件。
&&&&&& echo $PATH可以显示当前的PATH,添加新的PATH方法 $PATH=$PATH:新PATH
TERM:& 终端类型 echo $TERM
PS1:&& 提示符,root用户默认为#,普通用户默认为$
SHELL: Shell解释器的绝对路径
LOGNAME: 登录用户的用户名
UID:& 当前用户的UID&&& echo $UID
&!--[if !supportLists]--&3.& &!--[endif]--&位置变量
位置变量是根据出现在命令行上的参数的位置确定的变量,在调用Shell程序的命令行中,参数的位置定义如下所示。
&& $命令& 参数1&& 参数2& 参数3
其中& $0& 对应& 执行的命令名
&&&&& $1& 对应& 参数1
&&&&& $2& 对应& 参数2
&&&&& $3& 对应& 参数3
(一定要搞清楚顺序!!)
&!--[if !supportLists]--&4.& &!--[endif]--&预定义的特殊变量
预定义的特殊变量有着特殊的含义,用户不可以更改,所有的预定义变量都由“$”符号和另外一个符号组成,常用的预定义特殊变量如下所示
$#: 位置参数个数(不包括Shell脚本名)
$*:& 位置参数组成的字符串
$!:&& 上一个后台命令对应的进程号
$?:&& 上一个命令的退出状态,为十进制数字,如果返回为0,则代表执行成功。
$$:&& 当前的进程号PID
&!--[if !supportLists]--&5.& &!--[endif]--&用户自定义变量 (大小写敏感)
要求: 变量名由字母或者下划线开头,后面跟任意数量的字母、数字、下划线。
&&&& _name&&& SIZE&&& my_idea
&&&& 2god&&&&& !name&& hello&world
&!--[if !supportLists]--&6.& &!--[endif]--&变量的创建
有两个内置的命令declare 和 typeset 可用于创建变量。通过命令的选项设置还可以设定变量的创建方。
除了使用内置命令来创建和设置变量外,还可以直接赋值,格式为:
变量名=变量值
&& 注意:变量名前面不应加美元“$”符号。(和PHP不同)
&&&&&&&& 等号“=”前后不可以有空格。
&&&&&&&& 和C语言不同,Shell中不需要显式的语法来声明变量。
&&&&&&&& 变量名不可以直接和其他字符相连,如果想相连,必须用括号:echo “this is $(he)llo!”
&!--[if !supportLists]--&7.& &!--[endif]--&变量的删除
系统提供unset命令可以删除变量,例如
&&unset& name
&!--[if !supportLists]--&8.& &!--[endif]--&变量的赋值
变量的赋值有五种:使用read命令,直接赋值,使用命令行参数,使用命令行的输出结果,从文件读取。
先说一下从read命令吧:(主要是在需要交互时使用)
Read命令是系统内置命令,语法格式为:
read& 变量1&& 变量2
当Shell脚本执行到read命令时,将暂停脚本的执行并等待键盘的输入,当用户输入完毕并且敲下回车之后,将完成赋值操作,脚本继续执行。
Read指令的规则:
&!--[if !supportLists]--&l& &!--[endif]--&多个数据或变量之间用空格隔开
&!--[if !supportLists]--&l& &!--[endif]--&若变量个数与数据个数相等时,对应取值
&!--[if !supportLists]--&l& &!--[endif]--&若变量个数大于数据个数时,没有输入数据的变量取空值
&!--[if !supportLists]--&l& &!--[endif]--&若变量个数小于数据个数时,将多余的数据赋给最后一个变量(也就是把空格当成字符串处理)
#!/bin/bash
echo –n “ please enter your name”& //-n 表示用户输入和提示信息在同一行
echo “your name is $name”
#!/bin/bash
echo “Please& enter& your& first name& and last name :”
read first last
echo “your first name is $first”
echo “your last name is $last”
第二种赋值方法就是直接给变量赋值(这种赋值方法主要是在不需要交互时,并且参数不需要修改时使用)
例如:name=xiaosu
&&&&& gender=man
第三种赋值方法是使用命令行参数赋值。(这种赋值方法是参数需要经常变化,并且不需要交互时使用)
这种赋值方法,也就是直接在命令后面跟参数,然后系统用$1来引用第一个参数。
第四种方法是利用命令的输出结果赋值(这种赋值方法可以直接处理上个命令产生的数据)
在Shell程序中,可以将一个命令的输出结果来当做变量,不过需要在赋值语句中使用反引号
例如currentdir=`pwd`
&&&& echo $currentdir
最后一种赋值方法是从文件中读入数据
这种方式就适合处理大批量的数据,直接把相应的数据写入文件,然后运行脚本即可。
通常是通过while循环一行行读入数据,即没循环一次,就从文件中读取一行数据,直到读取到文件的结尾。
#!/bin/bash
ls *.sh &execfile
while read LINE
chmod a+x $LINE
done&execfile
这个脚本使用了while..do..done 结构,最后一行表示从文件execfile读取数据。while read LINE表示 每次循环读入一行数据并赋值给变量LINE。
&!--[if !supportLists]--&9.& &!--[endif]--&变量的输出
最简单的方法就是使用echo
如果想输出格式化的字符串,就需要使用printf,用法和C语言类似
&&&&&&&&&&& printf 命令的格式说明符
\”&&& 输出双引号
\\&&& 输出反斜杠
\a&&& 响铃
\n&&& 换行
\r&&&& 回车
本文已收录于以下专栏:
相关文章推荐
Linux的shell编程是一种非常成熟的编程语言,它支持各种类型的变量。有三种主要的变量类型:环境变量、内部变量和用户变量。
环境变量(environment variable)是系统环境的一...
首先, Shell赋值时,等号左右两边是不能有空格的
s=`date +&%Y-%m-%d&` # 注意`不是单引号, 而是~下面的点...
aa=`expr .....`是常见的用法,由此很容易理解
aa=`df | grep /kk | awk '{print $2}'`可将df 第2列的值赋给变量aa
然后if [ $aa...
shell脚本的作用,第一个shell脚本,shell脚本的变量,shell给定的特殊变量,shell脚本的三种赋值方式
一、DHCP概述
1.采用DHCP的必要性
在TCP/IP网络上,每台工作站要能存取网络上的资源之前,都必须进行基本的网络配置,一些主要参数诸如IP地址,子网掩码,缺省网关,DNS等必不可...
在使用过程中,进行了如下语句:
for var in 0 3 6 9
 do 
for i in 200 201 202
             do
./set.sh  V$i+$var...
1、查看所有的shell变量
2、查看所有的只读shell变量
3、变量设置值
格式:var_name=var_value
注意:=连...
http://wiki.nginx.org/Modules#Standard_HTTP_modules 这里面带有所有基本的模块,及需要额外增加的模块
1.安装带有ssl模块的 nginx
1.  Shell中的变量类型
Shell中的变量可以分为环境变量、位置变量、预定义的特殊变量以及用户自定义变量、
2.  环境变量
Shell中的环境变量是一类Shell预定义变量,是用于设置...
本人不才,配置了两天,终于搞出来了,结合网上诸多博文,特此总结一下!
配置环境:
      Ubuntu 11.04
     PCRE 8.31
   &#1...
他的最新文章
讲师:汪剑
讲师:刘道宽
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)当前位置: >>
linux命令及shell
下载第一部分 shell第1章 文件安全与权限为了防止未授权用户访问你的文件,可以在文件和目录上设置权限位。还可以设定文件 在创建时所具有的缺省权限:这些只是整个系统安全问题中的一小部分。在这里我们并不想 对系统安全问题的方方面面进行全面的探讨,只是介绍一下有关文件和目录的安全问题。 本章包含以下内容: ? 文件和目录的权限。 ? setuid。 ? chown和chgrp。 ? umask。 ? 符号链接。 创建文件的用户和他 (她)所属于的组拥有该文件。文件的属主可以设定谁具有读、写、执 行该文件的权限。当然,根用户或系统管理员可以改变任何普通用户的设置。一个文件一经 创建,就具有三种访问方式: 1) 读,可以显示该文件的内容。 2) 写,可以编辑或删除它。 3) 执行,如果该文件是一个 shell脚本或程序。 按照所针对的用户,文件的权限可分为三类: 1) 文件属主,创建该文件的用户。 2) 同组用户,拥有该文件的用户组中的任何用户。 3) 其他用户,即不属于拥有该文件的用户组的某一用户。1.1 文件当你创建一个文件的时候,系统保存了有关该文件的全部信息,包括: ? 文件的位置。 ? 文件类型。 ? 文件长度。 ? 哪位用户拥有该文件,哪些用户可以访问该文件。 ? i节点。 ? 文件的修改时间。 ? 文件的权限位。 让我们使用 ls -l 命令,来看一个典型的文件: 2第一部分 shell下载下面让我们来分析一下该命令所得结果的前面两行,看看都包含了哪些信息: total 4232:这一行告诉我们该目录中所有文件所占的空间。 - r w x r- x r- x:这是该文件的权限位。如果除去最前面的横杠,这里一共是 9个字符,他们 分别对应 9个权限位。通过这些权限位,可以设定用户对文件的访问权限。这 9个字符可以分 为三组: rwx:文件属主权限 r-x:同组用户权限 r-x:其他用户权限 问权限被禁止。 1 该文件硬链接的数目。 root 文件的属主。 root 文件的属主 root所在的缺省组(也叫做root)。 3578 用字节来表示的文件长度,记住,不是 K字节! Oct 14 04:44 文件的更新时间。 dmesg 文件名。 这是前面三位 这是中间三位 这是最后三位后面我们还将对这些权限位作更详细的介绍。出现在 r、w、x位置上的横杠表示相应的访1.2 文件类型还记得前面一节所提到的文件权限位前面的那个字符吗?我们现在就解释一下这个横杠 所代表的意思,文件类型有七种,它可以从 ls -l命令所列出的结果的第一位看出,这七种类型 是: d 目录。 l 符号链接(指向另一个文件 )。 s 套接字文件。 b 块设备文件。 c 字符设备文件。 p 命名管道文件。 - 普通文件,或者更准确地说,不属于以上几种类型的文件。1.3 权限让我们用touch命令创建一个文件:$ touch myfile现在对该目录使用 ls -l 命令: 下载第1章 文件安全与权限3我们已经创建了一个空文件,正如我们所希望的那样,第一个横杠告诉我们该文件是一 个普通文件。你将会发现所创建的文件绝大多数都是普通文件或符号链接文件 (后面将会出现 更多的符号链接文件 )。 文件属主权限 rw组用户权限 r-其他用户权限 r―接下来的三个权限位是文件属主所具有的权限;再接下来的三位是与你同组用户所具有 的权限,这里是 admin组;最后三位是其他用户所具有的权限。在该命令的结果中,我所属于 的缺省组也显示了出来。下面是对该文件权限的精确描述:表1-1 ls -l命令输出的含义(第一个字符 )(接下来的三个字符 )rw(再接下来的三个字符 )r-(最后三个字符 )r-普通文件 文件属主的权限 同组用户的权限 其他用户的权限因此,这三组字符 (除了第一个字符 )分别定义了: 1) 文件属主所拥有的权限。 2) 文件属主缺省组 (一个用户可以属于很多的组 )所拥有的权限。 3) 系统中其他用户的权限。 在每一组字符中含有三个权限位: r 读权限 w 写/更改权限 x 执行该脚本或程序的权限 这里我们采用另外一种方式来表示刚才所列出 myfile的文件权限: 文件类型为普通文件 rw文件属主可以读、写 r-同组用户可以读 r-其他用户可以读你可能已经注意到了,myfile在创建的时候并未给属主赋予执行权限,在用户创建文件时, 系统不会自动地设置执行权限位。这是出于加强系统安全的考虑。必须手工修改这一权限位: 后面讲到 umask命令时,你就会明白为什么没有获得执行权限。然而,你可以针对目录设置执 行权限位,但这与文件执行权限位的意义有所不同,这一点我们将在后面讨论。 上面这段关于权限位的内容可能不太好理解,让我们来看几个例子 (见表1-2)。 更令人迷惑的是,对于文件属主来说,在只有读权限位被置位的情况下,仍然可以通过 文件重定向的方法向该文件写入。过一会儿我们就会看到,能否删除一个文件还依赖于该文 件所在目录权限位的设置。表1-2 文件权限及含义权 限 所代表的含义 文文件属主可读,但不能写或执行 文文件属主和同组用户 (一般来说,是文件属主所在的缺省组 )可读 文任何用户都可读,但不能写或执行 文文件属主可读、写、执行,同组用户和其他用户只可读 文文件属主可读、写、执行,同组用户可读、执行r-- --- --r-- r-- --r-- r-- r-rwx r-- r-rwx r-x --- 4第一部分 shell下载(续)所代表的含义 文文件属主可读、写、执行,同组用户和其他用户可读、执行 文文件属主和同组用户可读、写 文文件属主和同组用户可读、写,其他用户可读 文文件属主和同组用户及其他用户读可以读、写,慎用这种权限 设置,因为任何用户都可以写入该文件权限rwx r-x r-x rw- rw- --rw- rw- r-rw- rw- ---1.4 改变权限位对于属于你的文件,可以按照自己的需要改变其权限位的设置。在改变文件权限位设置 之前,要仔细地想一想有哪些用户需要访问你的文件 (包括你的目录 )。可以使用 c h m o d命令来 改变文件权限位的设置。这一命令有比较短的绝对模式和长一些的符号模式。我们先来看一 看符号模式。 1.4.1 符号模式 chmod命令的一般格式为:chmod [who] operator [permission] filenamewho的含义是: u 文件属主权限。 g 同组用户权限。 o 其他用户权限。 a 所有用户(文件属主、同组用户及其他用户 )。 operator的含义: + 增加权限。 - 取消权限。 = 设定权限。 permission的含义: r 读权限。 w 写权限。 x 执行权限。 s 文件属主和组set-ID。 t 粘性位*。 l 给文件加锁,使其他用户无法访问。 u,g,o 针对文件属主、同组用户及其他用户的操作。 *在列文件或目录时,有时会遇到“ t”位。 “t”代表了粘性位。如果在一个目录上出现 “t”位,这就意味着该目录中的文件只有其属主才可以删除,即使某个同组用户具有和属主 同等的权限。不过有的系统在这一规则上并不十分严格。 如果在文件列表时看到“ t” ,那么这就意味着该脚本或程序在执行时会被放在交换区 (虚 存)。不过由于当今的内存价格如此之低,大可不必理会文件的“ t”的使用。 下载1.4.2 chmod命令举例第1章 文件安全与权限5现在让我们来看一些使用 c h m o d命令的例子。假定 m y f i l e文件最初具有这样的权限: r w x rwx rwx :命 令 chmod a-x myfile chmod og-w myfile chmod g+w myfile chmod u+x myfile chmod go+x myfile 结 果 rw- rw- rwrw- r-- r-rw- rw- r-rwx rw- r-rwx rwx r-x 含 义 收回所有用户的执行权限 收回同组用户和其他用户的写权限 赋予同组用户写权限 赋予文件属主执行权限 赋予同组用户和其他用户执行权限当创建myfile文件时,它具有这样的权限: 如果这是我写的一个脚本,我希望能够具有执行权限,并取消其他用户 的写权限,可以用:$ chmod u+x o-w myfile(所有其他用户 )这样,该文件的权限变为: 现在已经使文件属主对 m y f i l e文件具有读、写执行的权限,而 a d m i n组的用户对该文件具 有读权限。 如果希望某个脚本文件对你自己来说可执行,而且你对该文件的缺省权限很放心,那么 只要使它对你来说具有执行权限即可。$ chmod u+x dt1.4.3 绝对模式 chmod命令绝对模式的一般形式为:chmod [mode] file其中mode是一个八进制数。 在绝对模式中,权限部分有着不同的含义。每一个权限位用一个八进制数来代表,如表 1-3所示。表1-3 八进制目录 /文件权限表示八 进 制 数 00
含 义 八 进 制 数 02 0001 含 义文件属主可读 文件属主可写 文件属主可执行 同组用户可读 同组用户可写同组用户可执行 其他用户可读 其他用户可写 其他用户可执行在设定权限的时候,只需按照表 1 - 3查出与文件属主、同组用户和其他用户所具有的权限 相对应的数字,并把它们加起来,就是相应的权限表示。 从表1-3中可以看出,文件属主、同组用户和其他用户分别所能够具有的最大权限值就是7。 6第一部分 shell下载再来看看前面举的例子: 相应的权限表示应为 644,它的意思就是: (文件属主可读、写 ) 0040(同组用户可读) 0004(其他用户可读) = = 有一个计算八进制权限表示的更好办法,如表 1-4所示:表1-4 计算权限值文件属主 r w x 4+2+1 同组用户 r w x 4+2+1 其他用户 r w x 4+2+1使用表1 - 4,可以更容易地计算出相应的权限值,只要分别针对文件属主、同组用户和其 他用户把相应权限下面的数字加在一起就可以了。 myfile文件具有这样的权限: r w 4+2 r - 4 r - 4把相应权限位所对应的值加在一起,就是 644。 1.4.4 chmod命令的其他例子 以下是一些 chmod命令绝对模式的例子:命 令 结 果 含 义 赋予所有用户读和写的权限 赋予所有文件属主读和写的权限,所有其他用户读权限 赋予文件属主读、写和执行的权限,所有其他用户读的权限 赋予文件属主和同组用户读和写的权限,其他用户读权限 赋予文件属主读、写和执行的权限 赋予所有用户读权限chmod 666 chmod 644 chmod 744 chmod 664 chmod 700 chmod 444rw- rw- rwrw- r-- r-rwx r-- r-rw- rw- r-rwx --- --r-- r-- r--下面举一个例子,假定有一个名为 yoa的文件,具有如下权限: 我现在希望使自己对该文件可读、写和执行, admin组用户对该文件只读,可以键入:如果希望自己对该文件可读、写和执行,对其他所有用户只读,我可以用:如果希望一次设置目录下所有文件的权限,可以用:chmod 644*这将使文件属主和同组用户都具有读和写的权限,其他用户只具有读权限。 下载还可以通过使用 -R选项连同子目录下的文件一起设置:chmod -R 664 /usr/local/home/dave/*第1章 文件安全与权限7这样就可以一次将 /usr/local/home/dave目录下的所有文件连同各个子目录下的文件的权限 全部设置为文件属主和同组用户可读和写,其他用户只读。使用 - R选项一定要谨慎,只有在 需要改变目录树下全部文件权限时才可以使用。 1.4.5 可以选择使用符号模式或绝对模式 上面的例子中既有绝对模式的,也有符号模式的,我们可以从中看出,如果使用该命令 的符号模式,可以设置或取消个别权限位,而在绝对模式中则不然。我个人倾向于使用符号 模式,因为它比绝对模式方便快捷。1.5 目录还记得在前面介绍 chmod命令时讲过,目录的权限位和文件有所不同。现在我们来看看其 中的区别。目录的读权限位意味着可以列出其中的内容。写权限位意味着可以在该目录中创 建文件,如果不希望其他用户在你的目录中创建文件,可以取消相应的写权限位。执行权限 位则意味着搜索和访问该目录(见表 1-5、表1-6) 。表1-5 目录权限r 可以列出该目录中的文件 w 可以在该目录中创建或删除文件 x 可以搜索或进入该目录表1-6 目录权限举例权 限 文件属主 读、写、执行 读、写、执行 读、写、执行 同组用户 读、写、执行 读、执行 读、执行 其他用户 读、执行 读 读、执行drwx rwx r-x(775) drwx r-x r--(754) drwx r-x r-x(755)如果把同组用户或其他用户针对某一目录的权限设置为 - - x,那么他们将无法列出该目录 中的文件。如果该目录中有一个执行位置位的脚本或程序,只要用户知道它的路径和文件名, 仍然可以执行它。用户不能够进入该目录并不妨碍他的执行。 目录的权限将会覆盖该目录中文件的权限。例如,如果目录 docs具有如下的权限: 而其中的文件pay的权限为: 那么admin组的用户将无法编辑该文件,因为它所属的目录不具有这样的权限。 该文件对任何用户都可读,但由于它所在的目录并未给 a d m i n组的用户赋予执行权限,所 以该组的用户都将无法访问该目录,他们将会得到“访问受限”的错误消息。1.6 suid/guid我们在前面曾经提到过 s u i d和g u i d。这种权限位近年来成为一个棘手的问题。很多系统供 8第一部分 shell下载应商不允许实现这一位,或者即使它被置位,也完全忽略它的存在,因为它会带来安全性风 险。那么人们为何如此大惊小怪呢? suid意味着如果某个用户对属于自己的 shell脚本设置了这种权限,那么其他用户在执行这 一脚本时也会具有其属主的相应权限。于是,如果根用户的某一个脚本设置了这样的权限, 那么其他普通用户在执行它的期间也同样具有根用户的权限。同样的原则也适用于 g u i d,执 行相应脚本的用户将具有该文件所属用户组中用户的权限。 1.6.1 为什么要使用suid/guid 为什么要使用这种类型的脚本?这里有一个很好的例子。我管理着几个大型的数据库系 统,而对它们进行备份需要有系统管理权限。我写了几个脚本,并设置了它们的 g u i d,这样 我指定的一些用户只要执行这些脚本就能够完成相应的工作,而无须以数据库管理员的身份 登录,以免不小心破坏了数据库服务器。通过执行这些脚本,他们可以完成数据库备份及其 他管理任务,但是在这些脚本运行结束之后,他们就又回复到他们作为普通用户的权限。 有相当一些 UNIX命令也设置了 suid和guid。如果想找出这些命令,可以进入 /bin或/sbin目 录,执行下面的命令:$ ls -l | grep '^...s'上面的命令是用来查找 suid文件的;$ ls -l | grep '^...s..s'上面的命令是用来查找 suid和guid的。 现在我们明白了什么是 suid,可是如何设置它呢?下面就来介绍这个问题。如果希望设置 suid,那么就将相应的权限位之前的那一位设置为 4;如果希望设置 guid,那么就将相应的权限 位之前的那一位设置为2;如果希望两者都置位,那么将相应的权限位之前的那一位设置为4+2。 一旦设置了这一位,一个 s将出现在 x的位置上。记住:在设置 s u i d或g u i d的同时,相应的 执行权限位必须要被设置。例如,如果希望设置 guid,那么必须要让该用户组具有执行权限。 如果想要对文件 l o g i n设置s u i d,它当前所具有的权限为 rwx rw- r-- (741) ,需要在使用 c h m o d命令时在该权限数字的前面加上一个 4,即chmod 4741,这将使该文件的权限变为 r w s rw- r --。$ chmod 4741 logit1.6.2 设置suid/guid的例子 下面给出几个例子:表1-7 设置suid/guid命 令 结 果 含 义chmod 4755 chmod 6711 chmod 4764rws r-x r-x rws --s --s rws rw- r--文文件被设置了 s u i d,文件属主具有读、写和执行的权限,所有其 他用户具有读和执行的权限 文文件被设置了 s u i d和g u i d,文件属主具有读、写和执行的权限, 所有其他用户具有执行的权限 文文件被设置了 s u i d,文件属主具有读、写和执行的权限,同组用 户具有读和执行的权限,其他用户具有读权限 下载可以这样设置其 suid:chmod u+s &filename&第1章 文件安全与权限9还可以使用符号方式来设置 suid/guid。如果某个文件具有这样的权限: rwx r-x r-x,那么于是该文件的权限将变为: rws r-x r-x 在查找设置了suid的文件时,没准会看到具有这样权限的文件: rwS r-x r-x,其中S为大写。 它表示相应的执行权限位并未被设置,这是一种没有什么用处的 suid设置,可以忽略它的存在。 注意,chmod命令不进行必要的完整性检查,可以给某一个没用的文件赋予任何权限,但 chmod 命令并不会对所设置的权限组合做什么检查。因此,不要看到一个文件具有执行权限, 就认为它一定是一个程序或脚本。1.7 chown和chgrp当你创建一个文件时,你就是该文件的属主。一旦你拥有某个文件,就可以改变它的所 有权,把它的所有权交给另外一个 / e t c / p a s s w d文件中存在的合法用户。可以使用用户名或用 户I D号来完成这一操作。在改变一个文件的所有权时,相应的 s u i d也将被清除,这是出于安 全性的考虑。只有文件的属主和系统管理员可以改变文件的所有权。一旦将文件的所有权交 给另外一个用户,就无法再重新收回它的所有权。如果真的需要这样做,那么就只有求助于 系统管理员了。 chown命令的一般形式为:chmod -R -h owner file- R选项意味着对所有子目录下的文件也都进行同样的操作。 - h选项意味着在改变符号链 接文件的属主时不影响该链接所指向的目标文件。 1.7.1 chown举例 这里给出几个例子:文件project的所有权现在由用户 louise交给了用户 pauline。 1.7.2 chgrp举例 chgrp命令和chown命令的格式差不多,下面给出一个例子。用户pauline现在把该文件所属的组由 admin变为sybadmin(系统中的另外一个用户组) 。 1.7.3 找出你所属于的用户组 如果你希望知道自己属于哪些用户组,可以用如下的命令: 10第一部分 shell下载或者可以使用id命令:1.7.4 找出其他用户所属于的组 为了找出其他用户所属于的组,可以用如下的命令:上面的命令告诉我们用户 matty属于sybadmin、appsgen和post用户组。1.8 umask当最初登录到系统中时, u m a s k命令确定了你创建文件的缺省模式。这一命令实际上和 c h m o d命令正好相反。你的系统管理员必须要为你设置一个合理的 u m a s k值,以确保你创建的 文件具有所希望的缺省权限,防止其他非同组用户对你的文件具有写权限。 在已经登录之后,可以按照个人的偏好使用 umask命令来改变文件创建的缺省权限。相应 的改变直到退出该 shell或使用另外的umask命令之前一直有效。 一般来说, u m a s k命令是在 / e t c / p r o f i l e文件中设置的,每个用户在登录时都会引用这个文 件,所以如果希望改变所有用户的 umask,可以在该文件中加入相应的条目。如果希望永久性 地设置自己的umask值,那么就把它放在自己 $HOME目录下的.profile或.bash_profile文件中。 1.8.1 如何计算umask值 u m a s k命令允许你设定文件创建时的缺省模式,对应每一类用户 (文件属主、同组用户、 其他用户 )存在一个相应的 u m a s k值中的数字。对于文件来说,这一数字的最大值分别是 6。系 统不允许你在创建一个文本文件时就赋予它执行权限,必须在创建后用 c h m o d命令增加这一 权限。目录则允许设置执行权限,这样针对目录来说, umask中各个数字最大可以到 7。 该命令的一般形式为:umask nnn其中nnn为umask置000-777。 让我们来看一些例子。 计算出你的 umask值: 可以有几种计算 u m a s k值的方法,通过设置 u m a s k值,可以为新创建的文件和目录设置缺 省权限。表 1-8列出了与权限位相对应的 umask值。 在计算 u m a s k值时,可以针对各类用户分别在这张表中按照所需要的文件 /目录创建缺省 权限查找对应的 umask值。 例如,umask值002 所对应的文件和目录创建缺省权限分别为 664和775。 还有另外一种计算 u m a s k值的方法。我们只要记住 u m a s k是从权限中“拿走”相应的位即 可。 下载表1-8 umask值与权限umask 0 1 2 3 4 5 6 7 文 6 6 4 4 2 2 0 0 件第1章 文件安全与权限11目 7 6 5 4 3 2 1 0录例如,对于 umask值002,相应的文件和目录缺省创建权限是什么呢? 第一步,我们首先写下具有全部权限的模式,即 777(所有用户都具有读、写和执行权限 )。 第二步,在下面一行按照 umask值写下相应的位,在本例中是 002。 第三步,在接下来的一行中记下上面两行中没有匹配的位。这就是目录的缺省创建权限。 稍加练习就能够记住这种方法。 第四步,对于文件来说,在创建时不能具有文件权限,只要拿掉相应的执行权限比特即 可。 这就是上面的例子,其中 umask值为002: 1) 文件的最大权限 2) umask值为002 3) 目录权限 4) 文件权限 1) 文件的最大权限 2) umask值为022 3) 目录权限 4) 文件权限 1.8.2 常用的umask值 表1-9列出了一些 umask值及它们所对应的目录和文件权限。表1-9 常用的umask值及对应的文件和目录权限umask值 022 027 002 006 007 目 755 750 775 771 770 录 文 644 640 664 660 660 件rwx rwx rwx (777) - - - - - - -wrwx rwx r-x (775) rw- rw- r-- (664) rwx rwx rwx (777) - - - -w- -wrwx r-x r-x (755) rw- r-- r-- (644) 这就是目录创建缺省权限 这就是文件创建缺省权限 这就是目录创建缺省权限 这就是文件创建缺省权限下面是另外一个例子,假设这次 umask值为022:如果想知道当前的 umask 值,可以使用umask命令: 12第一部分 shell下载如果想要改变umask值,只要使用umask命令设置一个新的值即可:$ umask 002确认一下系统是否已经接受了新的 umask值:在使用 u m a s k命令之前一定要弄清楚到底希望具有什么样的文件 /目录创建缺省权限。否 则可能会得到一些非常奇怪的结果;例如,如果将 u m a s k值设置为 6 0 0,那么所创建的文件 /目 录的缺省权限就是 066!1.9 符号链接存在两种不同类型的链接,软链接和硬链接,这里我们只讨论软链接。软链接实际上就 是一个指向文件的指针。你将会发现这种软链接使用起来非常方便。 1.9.1 使用软链接来保存文件的多个映像 下面我们就解释一下符号链接是怎么回事。比方说在 / u s r / l o c a l / a d m i n / s a l e s目录下有一个 含有销售信息的文件,销售部门的每一个人都想看这份文件。你可以在每一位用户的 $ H O M E 目录下建立一个指向该文件的链接,而不是在每个目录下拷贝一份。这样当需要更改这一文 件时,只需改变一个源文件即可。每个销售 $ H O M E目录中的链接可以起任何名字,不必和源 文件一致。 如果有很多子目录,而进入这些目录很费时间,在这种情况下链接也非常有用。可以针 对$ H O M E目录下的一个很深的子目录创建一个链接。还有,比如在安装一个应用程序时,它 的日志被保存到 /usr/opt/app/log目录下,如果想把它保存在另外一个你认为更方便目录下,可 以建立一个指向该目录的链接。 该命令的一般形式为:ln [-s] source_path target_path其中的路径可以是目录也可以是文件。让我们来看几个例子。 1.9.2 符号链接举例 假如系统中有 4 0个销售和管理用户,销售用户使用一个销售应用程序,而管理用户使用 一个管理应用程序。我作为系统管理员该怎么做呢?首先删除它们各自 $ H O M E目录下的所 有. p r o f i l e文件。然后在 / u s r / l o c a l / m e n u s /目录下创建两个 p r o f i l e文件,一个是 s a l e s . p r o f i l e,一 个是admin.profile,它们分别为销售和管理人员提供了所需的环境,并引导他们进入相应的应 用程序。现在我在所有销售人员的 $HOME目录下分别创建一个指向 sales.profile的链接,在所 有管理人员的 $ H O M E目录下分别创建一个指向 a d m i n . p r o f i l e文件的链接。注意,不必在上面 命令格式中的 t a rg e t _ p a t h端创建相应文件,如果不存在这样一个文件, l n命令会自动创建该文 下载件。下面就是我对销售人员 matty所做的操作。第1章 文件安全与权限13(你所看到的可能会与此稍有差别 )。 这就是我所要做的全部工作;对于管理人员也是如此。而且如果需要作任何修改的话, 只要改变销售和管理人员的 profile文件即可,而不必对 40个用户逐一进行修改。 下面是另外一个例子。我所管理的系统中有一个网络监视器,它将日志写在 /usr/opt/ m o n i t o r / r e g s t a r目录下,但其他所有的日志都保存在 / v a r / a d m / l o g s目录下,这样只需在该目录 下建立一个指向原有文件的链接就可以在一个地方看所有的日志了,而不必花费很多时间分 别进入各个相应的目录。下面就是所用的链接命令:$ ln -s /usr/opt/monitor/regstar/reg.log /var/adm/logs/monitor.log如果链接太多的话,可以删掉一些,不过切记不要删除源文件。 不管是否在同一个文件系统中,都可以创建链接。在创建链接的时候,不要忘记在原有 目录设置执行权限。链接一旦创建,链接目录将具有权限 7 7 7或rwx rwx rwx ,但是实际的原 有文件的权限并未改变。 在新安装的系统上,通常要进行这样的操作,在 /var目录中创建一个指向 /tmp目录的链接, 因为有些应用程序认为存在 / v a r / t m p目录(然而它实际上并不存在 ),有些应用程序在该目录中 保存一些临时文件。为了使所有的临时文件都放在一个地方,可以使用 l n命令在/ v a r目录下建 立一个指向 /tmp目录的链接。现在如果我在/var目录中列文件,就能够看到刚才建立的链接:1.10 小结本章介绍了一些有关文件安全的基本概念。如果这些命令能够使用得当而且使用得比较 谨慎,应该不会有什么问题。手指轻轻一敲就有可能输入 chmod -R这样的命令,它将改变整 个文件系统的权限,如果没有做备份的话,没有几年的时间恐怕是无法恢复了,所以在输入 这些命令时,千万不要在手指上贴膏药! 是否使用设置了 suid的脚本完全取决于你自己。如果使用的话,一定要确保能够监控它的 使用,而且不要以根用户身份设置 suid。 下载第2章 使用find和xargs有时可能需要在系统中查找具有某一特征的文件 (例如文件权限、文件属主、文件长度、 文件类型等等 )。这样做可能有很多原因。可能出于安全性的考虑,或是一般性的系统管理任 务,或许只是为了找出一个不知保存在什么地方的文件。 F i n d是一个非常有效的工具,它可 以遍历当前目录甚至于整个文件系统来查找某些文件或目录。 在本章中,我们介绍以下内容: ? find命令选项。 ? 使用find命令不同选项的例子。 ? 配合find使用x a rg s命令的例子。 由于find具有如此强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间 来了解一下。即使系统中含有网络文件系统 ( N F S ),f i n d命令在该文件系统中同样有效,只要 你具有相应的权限。 在运行一个非常消耗资源的 find命令时,很多人都倾向于把它放在后台执行,因为遍历一 个大的文件系统可能会花费很长的时间 (这里是指30G字节以上的文件系统 )。 Find命令的一般形式为:find pathname -options [-print -exec -ok]让我们来看看该命令的参数: pathname find命令所查找的目录路径。例如用 .来表示当前目录,用 /来表示系统根目录。 -print find命令将匹配的文件输出到标准输出。 -exec find命令对匹配的文件执行该参数所给出的 s h e l l命令。相应命令的形式为 ' c o m m and' {} \;,注意{}和\;之间的空格。 -ok 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的 shell命令, 在执行每一个命令之前,都会给出提示,让用户来确定是否执行。2.1 find命令选项f i n d命令有很多选项或表达式,每一个选项前面跟随一个横杠 -。让我们先来看一下该命 令的主要选项,然后再给出一些例子。 -name 按照文件名查找文件。 -perm 按照文件权限来查找文件。 -prune 使用这一选项可以使 find命令不在当前指定的目录中查找,如果同时使用了 -depth 选项,那么 -prune选项将被find命令忽略。 -user 按照文件属主来查找文件。 -group 按照文件所属的组来查找文件。 -mtime -n +n 按照文件的更改时间来查找文件, -n表示文件更改时间距现在 n天以内,+n 表示文件更改时间距现在 n天以前。Find命令还有-atime和-ctime选项,但它们都和 -mtime选项 下载相似,所以我们在这里只介绍 -mtime选项。第2章 使用find和xargs15-nogroup 查找无有效所属组的文件,即该文件所属的组在 /etc/groups中不存在。 -nouser 查找无有效属主的文件,即该文件的属主在 /etc/passwd中不存在。 -newer file1 ! file2 查找更改时间比文件 file1新但比文件 file2旧的文件。 -type 查找某一类型的文件,诸如: b - 块设备文件。 d - 目录。 c - 字符设备文件。 p - 管道文件。 l - 符号链接文件。 f - 普通文件。 -size n[c] 查找文件长度为 n块的文件,带有 c时表示文件长度以字节计。 -depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。 -fstype 查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件 /etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。 -mount 在查找文件时不跨越文件系统 mount点。 -follow 如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。 -cpio 对匹配的文件使用 cpio命令,将这些文件备份到磁带设备中。 2.1.1 使用name选项 文件名选项是 f i n d命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用。 可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来。 不管当前路径是什么,如果想要在自己的根目录 $ H O M E中查找文件名符合 * . t x t的文件, 使用~作为'pathname参数,波浪号~代表了你的 $HOME目录。$ find ~ -name &*.txt& -print想要在当前目录及子目录中查找所有的‘ *.txt’文件,可以用:$ find . -name &*.txt& -print想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:$ find . -name &[A-Z]*& -print想要在/etc目录中查找文件名以 host开头的文件,可以用:$ find /etc -name &host*& -print想要查找$HOME目录中的文件,可以用:$ f i n d ~ - n a m e & * & - p r i或f i n d . - p r i n t nt要想让系统高负荷运行,就从根目录开始查找所有的文件。如果希望在系统管理员那里 保留一个好印象的话,最好在这么做之前考虑清楚!$ find / -name &*& -print如果想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是 * . t x t的文 件,下面的命令就能够返回名为 ax37.txt的文件: 16第一部分 shell下载$ find . -name &[a-z][a-z][0--9][0--9].txt& -print2.1.2 使用perm选项 如果希望按照文件权限模式来查找文件的话,可以采用 - p e r m选项。你可能需要找到所有 用户都具有执行权限的文件,或是希望查看某个用户目录下的文件权限类型。在使用这一选 项的时候,最好使用八进制的权限表示法。 为了在当前目录下查找文件权限位为 7 5 5的文件,即文件属主可以读、写、执行,其他用 户可以读、执行的文件,可以用:$ find . -perm 755 -print如果希望在当前目录下查找所有用户都可读、写、执行的文件(要小心这种情况) ,我们 可以使用 f i n d命令的 - p e r m选项。在八进制数字前面要加一个横杠 -。在下面的命令中 - p e r m代 表按照文件权限查找,而‘ 007’和你在chmod命令的绝对模式中所采用的表示法完全相同。$ find . -perm -007 -print2.1.3 忽略某个目录 如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件, 那么可以使用 - p r u n e选项来指出需要忽略的目录。在使用 - p r u n e选项时要当心,因为如果你同 时使用了-depth选项,那么 -prune选项就会被 find命令忽略。 如果希望在 /apps目录下查找文件,但不希望在 /apps/bin目录下查找,可以用:$ find /apps -name &/apps/bin& -prune -o -print2.1.4 使用user和nouser选项 如果希望按照文件属主查找文件,可以给出相应的用户名。例如,在 $ H O M E目录中查找 文件属主为 dave的文件,可以用:$ find ~ -user dave -print在/etc目录下查找文件属主为 uucp的文件:$ find /etc -user uucp -print为了查找属主帐户已经被删除的文件,可以使用 - n o u s e r选项。这样就能够找到那些属主 在/etc/passwd文件中没有有效帐户的文件。在使用 -nouser选项时,不必给出用户名; find命令 能够为你完成相应的工作。例如,希望在 /home目录下查找所有的这类文件,可以用:$ find /home -nouser -print2.1.5 使用group和nogroup选项 就像u s e r和n o u s e r选项一样,针对文件所属于的用户组, f i n d命令也具有同样的选项,为 了在/apps目录下查找属于 accts用户组的文件,可以用:$ find /apps -group accts -print要查找没有有效所属用户组的所有文件,可以使用 n o g r o u p选项。下面的 f i n d命令从文件 系统的根目录处查找这样的文件$ fine/-nogroup-print 下载2.1.6 按照更改时间查找文件第2章 使用find和xargs17如果希望按照更改时间来查找文件,可以使用 mtime选项。如果系统突然没有可用空间了, 很有可能某一个文件的长度在此期间增长迅速,这时就可以用 m t i m e选项来查找这样的文件。 用减号-来限定更改时间在距今 n日以内的文件,而用加号 +来限定更改时间在距今 n日以前的 文件。 希望在系统根目录下查找更改时间在 5日以内的文件,可以用:$ find / -mtime -5 -print为了在/var/adm目录下查找更改时间在 3日以前的文件,可以用:$ find /var/adm -mtime +3 -print2.1.7 查找比某个文件新或旧的文件 如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用 - n e w e r选 项。它的一般形式为:newest_file_name ! oldest_file_name其中,!是逻辑非符号。 这里有两个文件,它们的更改时间大约相差两天。下面给出的 find命令能够查找更改时间比文件 age.awk新但比文件 belts.awk旧的文件:如果想使用 find命令的这一选项来查找更改时间在两个小时以内的文件,除非有一个现成 的文件其更改时间恰好在两个小时以前,否则就没有可用来比较更改时间的文件。为了解决 这一问题,可以首先创建一个文件并将其日期和时间戳设置为所需要的时间。这可以用 t o u c h 命令来实现。 假设现在的时间是 2 3 : 4 0,希望查找更改时间在两个小时以内的文件,可以首先创建这样 一个文件:一个符合要求的文件已经被创建;这里我们假设今天是五月四日,而该文件的更改时间 是21:40,比现在刚好早两个小时。 现在我们就可以使用 f i n d命令的- n e w e r选项在当前目录下查找所有更改时间在两个小时以 内的文件:$ find . -newer dstamp -print2.1.8 使用type选项 UNIX或LINUX系统中有若干种不同的文件类型,这部分内容我们在前面的章节已经做了 18第一部分 shell下载介绍,这里就不再赘述。如果要在 /etc目录下查找所有的目录,可以用:$ find /etc -type d -print为了在当前目录下查找除目录以外的所有类型的文件,可以用:$ find . ! -type d -print为了在/etc目录下查找所有的符号链接文件,可以用:$ find /etc -type l -print2.1.9 使用size选项 可以按照文件长度来查找文件,这里所指的文件长度既可以用块( b l o c k)来计量,也可 以用字节来计量。以字节计量文件长度的表达形式为 N c;以块计量文件长度只用数字表示即 可。 就我个人而言,我总是使用以字节计的方式,在按照文件长度查找文件时,大多数人都 喜欢使用这种以字节表示的文件长度,而不用块的数目来表示,除非是在查看文件系统的大 小,因为这时使用块来计量更容易转换。 为了在当前目录下查找文件长度大于 1M字节的文件,可以用:$ find . -size +1000000c -print为了在/home/apache目录下查找文件长度恰好为 100字节的文件,可以用:$ find /home/apache -size 100c -print为了在当前目录下查找长度超过 10块的文件(一块等于 512字节) ,可以用:$ find . -size +10 -print2.1.10 使用depth选项 在使用 f i n d命令时,可能希望先匹配所有的文件,再在子目录中查找。使用 d e p t h选项就 可以使find命令这样做。这样做的一个原因就是,当在使用 find命令向磁带上备份文件系统时, 希望首先备份所有的文件,其次再备份子目录中的文件。 在下面的例子中, f i n d命令从文件系统的根目录开始,查找一个名为 C O N . F I L E的文件。 它将首先匹配所有的文件然后再进入子目录中查找。$ find / -name &CON.FILE& -depth -print2.1.11 使用mount选项 在当前的文件系统中查找文件(不进入其他文件系统) ,可以使用 f i n d命令的 m o u n t选项。 在下面的例子中,我们从当前目录开始查找位于本文件系统中文件名以 XC结尾的文件:$ find . -name &*.XC& -mount -print2.1.12 使用cpio选项 c p i o命令可以用来向磁带设备备份文件或从中恢复文件。可以使用 f i n d命令在整个文件系 统中(更多的情况下是在部分文件系统中)查找文件,然后用 cpio命令将其备份到磁带上。 如果希望使用 c p i o命令备份 / e t c、/ h o m e和/ a p p s目录中的文件,可以使用下面所给出的命 令,不过要记住你是在文件系统的根目录下: 下载第2章 使用find和xargs19(在上面的例子中,第一行末尾的 \告诉shell命令还未结束,忽略 \后面的回车。 ) 在上面的例子中,应当注意到路径中缺少 /。这叫作相对路径。之所以使用相对路径,是 因为在从磁带中恢复这些文件的时候,可以选择恢复文件的路径。例如,可以将这些文件先 恢复到另外一个目录中,对它们进行某些操作后,再恢复到原始目录中。如果在备份时使用 了绝对路径,例如 / e t c,那么在恢复时,就只能恢复到 / e t c目录中去,别无其他选择。在上面 的例子中,我告诉 f i n d命令首先进入 / e t c目录,然后是 / h o m e和/ a p p s目录,先匹配这些目录下 的文件,然后再匹配其子目录中的文件,所有这些结果将通过管道传递给 cpio命令进行备份。 顺便说一下,在上面的例子中 cpio命令使用了 C65536选项,我本可以使用 B选项,不过这 样每块的大小只有 5 1 2 字节,而使用了 C 6 5 5 3 6 选项后,块的大小变成了 () 。 2.1.13 使用exec或ok来执行shell命令 当匹配到一些文件以后,可能希望对其进行某些操作,这时就可以使用 - e x e c选项。一旦 f i n d命令匹配到了相应的文件,就可以用 - e x e c选项中的命令对其进行操作(在有些操作系统 中只允许 - e x e c选项执行诸如 l s或ls -l这样的命令) 。大多数用户使用这一选项是为了查找旧文 件并删除它们。这里我强烈地建议你在真正执行 r m命令删除文件之前,最好先用 l s命令看一 下,确认它们是所要删除的文件。 e x e c选项后面跟随着所要执行的命令,然后是一对儿 { },一个空格和一个 \,最后是一个 分号。 为了使用 e x e c选项,必须要同时使用 p r i n t选项。如果验证一下 f i n d命令,会发现该命令只 输出从当前路径起的相对路径及文件名。 为了用ls -l 命令列出所匹配到的文件,可以把 ls -l 命令放在find命令的-exec选项中,例如: 6 4 K 字节上面的例子中, find命令匹配到了当前目录下的所有普通文件,并在 -exec选项中使用ls -l 命令将它们列出。 为了在/logs目录中查找更改时间在 5日以前的文件并删除它们,可以用:$ find logs -type f -mtime +5 -exec rm {} \;记住,在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心! 当使用诸如 mv或rm命令时,可以使用 -exec选项的安全模式。它将在对每个匹配到的文件 进行操作之前提示你。在下面的例子中, f i n d命令在当前目录中查找所有文件名以 . L O G结尾、 更改时间在 5日以上的文件,并删除它们,只不过在删除之前先给出提示。按y键删除文件,按 n键不删除。 任何形式的命令都可以在 -exec选项中使用。在下面的例子中我们使用 grep命令。find命令 20第一部分 shell下载首先匹配所有文件名为“ p a s s w d *”的文件,例如 p a s s w d、p a s s w d . o l d、p a s s w d . b a k,然后执 行grep命令看看在这些文件中是否存在一个 rounder用户。2.1.14 find命令的例子 我们已经介绍了 find命令的基本选项,下面给出 find命令的一些其他的例子。 为了匹配$HOME目录下的所有文件,下面两种方法都可以使用:$ find $HOME -print $ find ~ -print为了在当前目录中查找 suid置位,文件属主具有读、写、执行权限,并且文件所属组的用 户和其他用户具有读和执行的权限的文件,可以用:$ find . -type f -perm 4755 -print为了查找系统中所有文件长度为 0的普通文件,并列出它们的完整路径,可以用:$ find / -type f -size 0 -exec ls -l {} \;为了查找/var/logs目录中更改时间在 7日以前的普通文件,并删除它们,可以用:$ find /var/logs -type f -mtime +7 -exec rm {} \;为了查找系统中所有属于 audit组的文件,可以用:$find /-name -group audit -print我们的一个审计系统每天创建一个审计日志文件。日志文件名的最后含有数字,这样我 们一眼就可以看出哪个文件是最新的,哪个是最旧的。 A d m i n . l o g 文件编上了序号: a d m i n . l o g . 0 0 1、a d m i n . l o g . 0 0 2等等。下面的 f i n d命令将删除 / l o g s目录中访问时间在 7日以前、 含有数字后缀的 a d m i n . l o g文件。该命令只检查三位数字,所以相应日志文件的后缀不要超过 999。'- a t i m $ find /logs -name 'admin.log[0-9][0-9][0-9] e +7 -exec rm {} \;为了查找当前文件系统中的所有目录并排序,可以用:$ find . -type d -print -local -mount |sort为了查找系统中所有的 rmt磁带设备,可以用:$ find /dev/rmt -print2.2 xargs在使用f i n d命令的- e x e c选项处理匹配到的文件时, f i n d命令将所有匹配到的文件一起传递 给e x e c执行。不幸的是,有些系统对能够传递给 e x e c的命令长度有限制,这样在 f i n d命令运行 几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出” 。这就是 x a rg s命令的用处所在,特别是与 f i n d命令一起使用。 F i n d命令把匹配到的文件传递给 x a rg s命 令,而x a rg s命令每次只获取一部分文件而不是全部,不像 - e x e c选项那样。这样它可以先处理 最先获取的一部分文件,然后是下一批,并如此继续下去。在有些系统中,使用 - e x e c选项会 为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次 执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用 下载第2章 使用find和xargs21x a rg s命令则只有一个进程。另外,在使用 x a rg s命令时,究竟是一次获取所有的参数,还是分 批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参 数来确定。 让我们来看看xargs命令是如何同find命令一起使用的,并给出一些例子。 下面的例子查找系统中的每一个普通文件,然后使用 x a rg s命令来测试它们分别属于哪类 文件:下面的例子在整个系统中查找内存信息转储文件 /tmp/core.log 文件中:( c o r e d u m p ) ,然后把结果保存到$ find . -name &core& -print | xargs echo && &/tmp/core.log下面的例子在 / a p p s / a u d i t目录下查找所有用户具有读、写和执行权限的文件,并收回相应 的写权限:$ find /apps/audit -perm -7 -print | xargs chmod o-w在下面的例子中,我们用 grep命令在所有的普通文件中搜索 device这个词:$ find / -type f -print | xargs grep &device&在下面的例子中,我们用 grep命令在当前目录下的所有普通文件中搜索 DBO这个词:$ f i n d . - n a m e *- t y p e f - p r i n t | x a r g s g r e p & D B O & \注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。2.3 小结f i n d命令是一个非常优秀的工具,它可以按照用户指定的准则来匹配文件。使用 e x e c和 x a rg s可以使用户对所匹配到的文件执行几乎所有的命令。 下载第3章 后台执行命令当你在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还 有更重要的事情要做,比如阅读电子邮件。对于密集访问磁盘的进程,你可能希望它能够在 每天的非负荷高峰时间段运行。为了使这些进程能够在后台运行,也就是说不在终端屏幕上 运行,有几种选择方法可供使用。 在本章中我们将讨论: ? 设置crontab文件,并用它来提交作业。 ? 使用at命令来提交作业。 ? 在后台提交作业。 ? 使用nohup命令提交作业。 名词解释: cron 系统调度进程。可以使用它在每天的非高峰负荷时间段运行作业,或在一周或一月 中的不同时段运行。 At at 命令。使用它在一个特定的时间运行一些特殊的作业,或在晚一些的非负荷高峰时 间段或高峰负荷时间段运行。 & 使用它在后台运行一个占用时间不长的进程。 Nohup 使用它在后台运行一个命令,即使在用户退出时也不受影响。3.1 cron和crontabc r o n是系统主要的调度进程,可以在无需人工干预的情况下运行作业。有一个叫做 c r o n t a b的命令允许用户提交、编辑或删除相应的作业。每一个用户都可以有一个 c r o n t a b文件 来保存调度信息。可以使用它运行任意一个 s h e l l脚本或某个命令,每小时运行一次,或一周 三次,这完全取决于你。每一个用户都可以有自己的 c r o n t a b文件,但在一个较大的系统中, 系统管理员一般会禁止这些文件,而只在整个系统保留一个这样的文件。系统管理员是通过 cron.deny和cron.allow这两个文件来禁止或允许用户拥有自己的 crontab文件。 3.1.1 crontab的域 为了能够在特定的时间运行作业,需要了解 c r o n t a b文件每个条目中各个域的意义和格式。 下面就是这些域: 第1列 第2列 第3列 第4列 第5列 第6列 分钟1~59 小时1~23(0表示子夜) 日1~31 月1~12 星期0~6(0表示星期天) 要运行的命令 下载下面是crontab的格式: 分&&时&&日&&月&&星期&&要运行的命令 其中&&表示空格。第3章 后台执行命令23C r o n t a b文件的一个条目是从左边读起的,第一列是分,最后一列是要运行的命令,它位 于星期的后面。 在这些域中,可以用横杠 -来表示一个时间范围,例如你希望星期一至星期五运行某个作 业,那么可以在星期域使用 1 - 5来表示。还可以在这些域中使用逗号“,” ,例如你希望星期一 和星期四运行某个作业,只需要使用 1 , 4来表示。可以用星号 *来表示连续的时间段。如果你 对某个表示时间的域没有特别的限定,也应该在该域填入 *。该文件的每一个条目必须含有 5 个时间域,而且每个域之间要用空格分隔。该文件中所有的注释行要在行首用 #来表示。 3.1.2 crontab条目举例 这里有crontab文件条目的一些例子:30 21* * * /apps/bin/cleanup.sh上面的例子表示每晚的 21:30运行/apps/bin目录下的cleanup.sh。45 4 1,10,22 * * /apps/bin/backup.sh上面的例子表示每月 1、10、22日的4:45运行/apps/bin目录下的backup.sh。10 1 * * 6,0 /bin/find -name &core& -exec rm {} \;上面的例子表示每周六、周日的 1:10运行一个find命令。0,30 18-23 * * * /apps/bin/dbcheck.sh上面的例子表示在每天 18:00至23:00之间每隔30分钟运行/apps/bin目录下的dbcheck.sh。0 23 * * 6 /apps/bin/qtrend.sh上面的例子表示每星期六的 11:00pm运行/apps/bin目录下的qtrend.sh。 你可能已经注意到上面的例子中,每个命令都给出了绝对路径。当使用 c r o n t a b运行s h e l l 脚本时,要由用户来给出脚本的绝对路径,设置相应的环境变量。记住,既然是用户向 c r o n 提交了这些作业,就要向 cron提供所需的全部环境。不要假定 cron知道所需要的特殊环境,它 其实并不知道。所以你要保证在 s h e l l脚本中提供所有必要的路径和环境变量,除了一些自动 设置的全局变量。 如果cron不能运行相应的脚本,用户将会收到一个邮件说明其中的原因。 3.1.3 crontab命令选项 crontab命令的一般形式为:Crontab [-u user] -e -l -r其中: -u 用户名。 -e 编辑crontab文件。 -l 列出crontab文件中的内容。 -r 删除crontab文件。 如果使用自己的名字登录,就不用使用 - u选项,因为在执行 c r o n t a b命令时,该命令能够 24第一部分 shell下载知道当前的用户。 3.1.4 创建一个新的crontab文件 在考虑向 c r o n进程提交一个 c r o n t a b文件之前,首先要做的一件事情就是设置环境变量 E D I TO R。c r o n进程根据它来确定使用哪个编辑器编辑 c r o n t a b文件。 9 9 %的U N I X和L I N U X用 户都使用 v i,如果你也是这样,那么你就编辑 $ H O M E目录下的 . p r o f i l e文件,在其中加入这样 一行:EDITOR= export EDITOR然后保存并退出。 不妨创建一个名为 & u s e r & c r o n的文件,其中 & u s e r &是用户名,例如, d a v e c r o n。在该文件 中加入如下的内容。保存并退出。确信前面 5个域用空格分隔。 在上面的例子中,系统将每隔 1 5分钟向控制台输出一次当前时间。如果系统崩溃或挂起, 从最后所显示的时间就可以一眼看出系统是什么时间停止工作的。在有些系统中,用 tty1来表 示控制台,可以根据实际情况对上面的例子进行相应的修改。 为了提交你刚刚创建的 crontab文件,可以把这个新创建的文件作为 cron命令的参数:$ crontab davecron现在该文件已经提交给 cron进程,它将每隔 15分钟运行一次。 同时,新创建文件的一个副本已经被放在 /var/spool/cron目录中,文件名就是用户名(即, dave) 。 3.1.5 列出crontab文件 为了列出crontab文件,可以用:你将会看到和上面类似的内容。可以使用这种方法在 $ H O M E目录中对 c r o n t a b文件做一备 份:$ crontab -l & $HOME/mycron这样,一旦不小心误删了 crontab文件,可以用上一节所讲述的方法迅速恢复。 3.1.6 编辑crontab文件 如果希望添加、删除或编辑 crontab文件中的条目,而 EDITOR环境变量又设置为 vi,那么 就可以用vi来编辑crontab文件,相应的命令为:$ crontab -e可以像使用 v i编辑其他任何文件那样修改 c r o n t a b文件并退出。如果修改了某些条目或添 下载域出现了超出允许范围的值,它会提示你。第3章 后台执行命令25加了新的条目,那么在保存该文件时, c r o n会对其进行必要的完整性检查。如果其中的某个 我们在编辑 crontab文件时,没准会加入新的条目。例如,加入下面的一条:现在保存并退出。最好在 c r o n t a b文件的每一个条目之上加入一条注释,这样就可以知道 它的功能、运行时间,更为重要的是,知道这是哪位用户的作业。 现在让我们使用前面讲过的 crontab -l命令列出它的全部信息:3.1.7 删除crontab文件 为了删除crontab文件,可以用:$ crontab -r3.1.8 恢复丢失的crontab文件 如果不小心误删了 c r o n t a b文件,假设你在自己的 $ H O M E目录下还有一个备份,那么可以 将其拷贝到 /var/spool/cron/&username&,其中&username&是用户名。如果由于权限问题无法完 成拷贝,可以用:$ crontab &filename&其中,&filename&是你在$HOME目录中副本的文件名。 我建议你在自己的 $ H O M E目录中保存一个该文件的副本。我就有过类似的经历,有数次 误删了crontab文件(因为 r键紧挨在e键的右边 …) 。这就是为什么有些系统文档建议不要直接 编辑crontab文件,而是编辑该文件的一个副本,然后重新提交新的文件。 有些c r o n t a b的变体有些怪异,所以在使用 c r o n t a b命令时要格外小心。如果遗漏了任何选 项,crontab可能会打开一个空文件,或者看起来像是个空文件。这时敲 delete键退出,不要按 &Ctrl-D&,否则你将丢失 crontab文件。3.2 at命令a t命令允许用户向 c r o n守护进程提交作业,使其在稍后的时间运行。这里稍后的时间可能 是指10min以后,也可能是指几天以后。如果你希望在一个月或更长的时间以后运行,最好还 是使用crontab文件。 一旦一个作业被提交, a t命令将会保留所有当前的环境变量,包括路径,不象 c r o n t a b, 只提供缺省的环境。该作业的所有输出都将以电子邮件的形式发送给用户,除非你对其输出 进行了重定向,绝大多数情况下是重定向到某个文件中。 和c r o n t a b一样,根用户可以通过 / e t c目录下的 a t . a l l o w和a t . d e n y文件来控制哪些用户可以 26格。第一部分 shell下载使用at命令,哪些用户不行。不过一般来说,对 at命令的使用不如对 crontab的使用限制那么严 at命令的基本形式为:at [-f script] [-m -l -r] [time] [date]其中, -f script 是所要提交的脚本或命令。 -l 列出当前所有等待运行的作业。 atq命令具有相同的作用。 -r 清除作业。为了清除某个作业,还要提供相应的作业标识( I D);有些 U N I X变体只 接受atrm作为清除命令。 -m 作业完成后给用户发邮件。 time date 的词。 现在就让我们来看看如何提交作业。 3.2.1 使用at命令提交命令或脚本 使用at命令提交作业有几种不同的形式,可以通过命令行方式,也可以使用 at命令提示符。 一般来说在提交若干行的系统命令时,我使用 at命令提示符方式,而在提交 shell脚本时,使用 命令行方式。 如果你想提交若干行的命令,可以在 at命令后面跟上日期 /时间并回车。然后就进入了 at命 令提示符,这时只需逐条输入相应的命令,然后按‘ &CTRL-D&’退出。下面给出一个例子: at命令的时间格式非常灵活;可以是 H、H H . H H M M、H H : M M或H : M,其中H和M 日期格式可以是月份数或日期数,而且 at命令还能够识别诸如 today、tomorrow这样 分别是小时和分钟。还可以使用 a.m.或p.m.。其中, & E O T &就是& C T R L - D &。在2 1 : 1 0系统将执行一个简单的 f i n d命令。你应当已经注 意到,我所提交的作业被分配了一个唯一标识 job 1。该命令在完成以后会将全部结果以邮件 的形式发送给我。 下面就是我从这个邮件中截取的一部分:下面这些日期/时间格式都是at命令可以接受的: 下载第3章 后台执行命令27如果希望向at命令提交一个 shell脚本,使用其命令行方式即可。在提交脚本时使用 -f选项。在上面的例子中,一个叫做 db_table.sh的脚本将在明天下午 3:00运行。 还可以使用 echo命令向at命令提交作业:$ echo find /etc -name &passwd& -print | at now +1 minute3.2.2 列出所提交的作业 一个作业被提交后,可以使用 at -l 命令来列出所有的作业:其中,第一行是作业标识,后面是作业运行的日期 /时间。最后一列 a代表a t。还可以使用 a t q命令来完成同样的功能,它是 a t命令的一个链接。当提交一个作业后,它就被拷贝到 /var/spool/at目录中,准备在要求的时间运行。3.2.3 清除一个作业 清除作业的命令格式为:atrm [job no] t -r [job no] 或a要清除某个作业,首先要执行 at -l命令,以获取相应的作业标识,然后对该作业标识使用 at -r 命令,清除该作业。有些系统使用at-r [job no]命令清除作业。3.3 &命令当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。 28命令 &第一部分 shell下载可以使用&命令把作业放到后台执行。 该命令的一般形式为: 为什么要在后台执行命令?因为当在后台执行命令时,可以继续使用你的终端做其他事 情。适合在后台运行的命令有 find、费时的打印作业、费时的排序及一些 shell脚本。在后台运 行作业时要当心:需要用户交互的命令不要放在后台执行,因为这样你的机器就会在那里傻 等。 不过,作业在后台运行一样会将结果输出到屏幕上,干扰你的工作。如果放在后台运行 的作业会产生大量的输出,最好使用下面的方法把它的输出重定向到某个文件中:command &out.file 2&&1 &在上面的例子中,所有的标准输出和错误输出都将被重定向到一个叫做 out.file 的文件中。 当你成功地提交进程以后,就会显示出一个进程号,可以用它来监控该进程,或杀死它。 3.3.1 向后台提交命令 现在我们运行一个 f i n d命令,查找名为“ s r m . c o n f”的文件,并把所有标准输出和错误输 出重定向到一个叫作 find.dt的文件中:在上面的例子中,在我们成功提交该命令之后,系统给出了它的进程号 27015。 当该作业完成时,按任意键(一般是回车键)就会出现一个提示: 这里还有另外一个例子,有一个叫做 p s 1的脚本,它能够截断和清除所有的日志文件,我 把它放到后台去执行:3.3.2 用ps命令查看进程 当一个命令在后台执行的时候,可以用提交命令时所得到的进程号来监控它的运行。在 前面的例子中,我们可以按照提交 ps1时得到的进程号,用 ps命令和grep命令列出这个进程:如果系统不支持 ps x命令,可以用:记住,在用 ps命令列出进程时,它无法确定该进程是运行在前台还是后台。 3.3.3 杀死后台进程 如果想杀死后台进程可以使用 k i l l命令。当一个进程被放到后台运行时, s h e l l会给出一个 下载kill -signal [process_number]第3章 后台执行命令29进程号,我们可以根据这个进程号,用 kill命令杀死该进程。该命令的基本形式为: 现在暂且不要考虑其中的各种不同信号;我们会在后面的章节对这一问题进行介绍。 在杀进程的时候,执行下面的命令 (你的进程号可能会不同 )并按回车键。系统将会给出相 应的信息告诉用户进程已经被杀死。如果系统没有给出任何信息,告诉你进程已经被杀死,那么不妨等一会儿,也许系统正 在杀该进程,如果还没有回应,就再执行另外一个 kill命令,这次带上一个信号选项:如果用上述方法提交了一个后台进程,那么在退出时该进程将会被终止。为了使后台进 程能够在退出后继续运行,可以使用 nohup命令,下面我们就介绍这一命令。3.4 nohup命令如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup命令。该命令可以在你退出帐户之后继续运行相应的进程。 Nohup就是不挂起的意思 (no hang up)。 该命令的一般形式为:nohup command &3.4.1 使用nohup命令提交作业 如果使用 n o h u p命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名 为nohup.out的文件中,除非另外指定了输出文件:nohup command & myout.file 2&&1在上面的例子中,输出被重定向到 myout.file文件中。 让我们来看一个例子,验证一下在退出帐户后相应的作业是否能够继续运行。我们先提 交一个名为 ps1的日志清除进程:现在退出该 shell,再重新登录,然后执行下面的命令:我们看到,该脚本还在运行。如果系统不支持 ps x 命令,使用 ps -ef|grep ps1命令。 3.4.2 一次提交几个作业 如果希望一次提交几个命令,最好能够把它们写入到一个 s h e l l脚本文件中,并用 n o h u p命 令来执行它。例如,下面的所有命令都用管道符号连接在一起;我们可以把这些命令存入一 30第一部分 shell下载个文件,并使该文件可执行。现在让它可执行:$ chmod 744 quarterend我们还将该脚本的所有输出都重定向到一个名为 qtr.out的文件中。3.5 小结本章中所讨论的工具主要是有关后台运行作业的。有时我们必须要对大文件进行大量更 改,或执行一些复杂的查找,这些工作最好能够在系统负荷较低时执行。 创建一个定时清理日志文件或完成其他特殊工作的脚本,这样只要提交一次,就可以每 天晚上运行,而且无需你干预,只要看看相应的脚本日志就可以了。 C r o n和其他工具可以使 系统管理任务变得更轻松。 下载第4章文件名置换当你在使用命令行时,有很多时间都用来查找你所需要的文件。 S h e l l提供了一套完整的 字符串模式匹配规则,或者称之为元字符,这样你就可以按照所要求的模式来匹配文件。还 可以使用字符类型来匹配文件名。在命令行方式下,使用元字符更为快捷,所以在本章我们 只介绍这部分内容。 在本章我们将讨论: ? 匹配文件名中的任何字符串。 ? 匹配文件名中的单个字符。 ? 匹配文件名中的字母或数字字符。 下面就是这些特殊字符: * 匹配文件名中的任何字符串,包括空字符串。 ? 匹配文件名中的任何单个字符。 [...] 匹配[ ]中所包含的任何字符。 [!...] 匹配[ ]中非感叹号!之后的字符。 当s h e l l遇到上述字符时,就会把它们当作特殊字符,而不是文件名中的普通字符,这样 用户就可以用它们来匹配相应的文件名。4.1 使用*使用星号*可以匹配文件名中的任何字符串。 在下面的例子中,我们给出文件名模式 app*, 它的意思是文件名以 app开头,后面可以跟随任何字符串,包括空字符串:*也可以用在文件名模式的开头,在下面的例子中, *.doc匹配所有以 .doc结尾的 文件名:*还可以用在文件名的当中,在下面的例子中, c l * . s e d用于匹配所有以 c l开头、后面跟任 何字符串、最后以 .sed结尾的文件名:在使用 c d命令切换路径时,使用星号还可以省去输入整个路径名的麻烦,下面给出一个 这样的例子: 32第一部分 shell下载4.2 使用?使用可以匹配文件名中的任何单个字符。在下面的例子中,我们列出文件名以任意两个 字符开头,接着是 R,后面跟任何字符的文件:在下面的例子中,我们列出文件名以 c o n f开头、中间是任意两个字符、最后以 . l o g结尾的 文件:在下面的例子中, f ? ? * s匹配所有以 f开头、中间是任意两个字符、后面跟随任意字符串、 并以s结尾的文件名:4.3 使用[...]和[!...]使用[...]可以用来匹配方括号 [ ]中的任何字符。在这一方法中,还可以使用一个横杠 -来连 接两个字母或数字,以此来表示一个范围。在下面的例子中,列出了以 i或o开头的文件名:为了匹配所有以 l o g .开头、后面跟随一个数字、然后可以是任意字符串的文件名,可以用 log.[0-9]*,其中[0-9]表示任意单个数字,星号 *代表了其他字符:下面的例子和刚才的有所不同,使用 [ ! 0 - 9 ] *来表示非数字开头的字符串,其中 !是非的意 思:下面的例子中,列出了所有以LPS开头、中间可以是任何两个字符,最后以1结尾的文件名: 下载第4章 文件名置换33下面的例子中,列出了所有以 LPS开头、中间可以是任何两个字符,后面跟随一个非数字 字符、然后是任意字符串的文件名:为了列出所有以大写字母开头的文件名,可以用:$ ls [A-Z]*为了列出所有以小写字母开头的文件名,可以用:$ ls [a-z]*为了列出所有以数字开头的文件名,可以用:$ ls [0-9]*为了列出所有以 . 开头的文件名(隐含文件,例如 .profile、.rhosts、.history等等) ,可以 用:$ ls .*4.4 小结使用元字符可以大大减少你在查找文件名上的工作量。这是一种非常有效的模式匹配方 法,在后面的章节中,我们还将在讨论正则表达式的时候对文本处理中所涉及到的元字符进 行更为详尽的讨论。 下载第5章 shell输入与输出在shell脚本中,可以用几种不同的方式读入数据:可以使用标准输入 ― 缺省为键盘,或 者指定一个文件作为输入。对于输出也是一样:如果不指定某个文件作为输出,标准输出总 是和终端屏幕相关联。如果所使用命令出现了什么错误,它也会缺省输出到屏幕上,如果不 想把这些信息输出到屏幕上,也可以把这些信息指定到一个文件中。 大多数使用标准输入的命令都指定一个文件作为标准输入。如果能够从一个文件中读取 数据,何必要费时费力地从键盘输入呢? 本章我们将讨论以下内容: ? 使用标准输入、标准输出及标准错误。 ? 重定向标准输入和标准输出。 本章全面讨论了 shell对数据和信息的标准输入、标准输出,对重定向也做了一定的介绍。5.1 echo使用echo命令可以显示文本行或变量,或者把字符串输入到文件。它的一般形式为:echo stringecho命令有很多功能,其中最常用的是下面几个: \c 不换行。 \f 进纸。 \t 跳格。 \n 换行。 如果希望提示符出现在输出的字符串之后,可以用:上面的命令将会有如下的显示: 其中“ □”是光标。 如果想在输出字符之后,让光标移到下一行,可以用:$ echo &The red pen ran out of ink&还可以用 e c h o命令输出转义符以及变量。在下面的例子中,你可以让终端铃响一声,显 示出$ H O M E目录,并且可以让系统执行 t t y命令(注意,该命令用键盘左上角的符号,法语中 的抑音符引起来,不是单引号, )。如果是LINUX系统,那么...... 必须使用- n选项来禁止echo命令输出后换行: 下载$ echo -n &What is your name :&第5章 shell输入与输出35(续)必须使用-e选项才能使转义符生效:如果希望在 echo命令输出之后附加换行,可以使用 \n选项:运行时会出现如下输出:还可以在echo语句中使用跳格符,记住别忘了加反斜杠 \:如果是LINUX系统,那么... 别忘了使用- e选项才能使转义符生效:如果想把一个字符串输出到文件中,使用重定向符号 &。在下面的例子中一个字符串被重 定向到一个名为 myfile的文件中:$ echo &The log files have all been done&& myfile或者可以追加到一个文件的末尾,这意味着不覆盖原有的内容:$ echo &$LOGNAME carried them out at `date`&&&myfile现在让我们看一下 myfile文件中的内容:初涉s h e l l的用户常常会遇到的一个问题就是如何把双引号包含到 e c h o命令的字符串中。 引号是一个特殊字符,所以必须要使用反斜杠 \来使s h e l l忽略它的特殊含义。假设你希望使用 echo命令输出这样的字符串: dev/rmt0” “/ ,那么我们只要在引号前面加上反斜杠 \即可:$ echo &\&/dev/rmt0&\& &/dev/rmt0&5.2 read可以使用read语句从键盘或文件的某一行文本中读入信息,并将其赋给一个变量。如果只 36车。第一部分 shell下载指定了一个变量,那么 r e a d将会把所有的输入赋给该变量,直至遇到第一个文件结束符或回 它的一般形式为:read varible1 varible2 ...在下面的例子中,只指定了一个变量,它将被赋予直至回车之前的所有内容:在下面的例子中,我们给出了两个变量,它们分别被赋予名字和姓氏。 s h e l l将用空格作 为变量之间的分隔符:如果输入文本域过长, Shell 将所有的超长部分赋予最后一个变量。下面的例子,假定要 读取变量名字和姓,但这次输入三个名字;结果如下;在上面的例子中,如果我们输入字符串 John Lemon Doe,那么第一个单词将被赋给第一 个变量,而由于变量数少于单词数,字符串后面的部分将被全部赋给第二个变量。 在编写shell脚本的时候,如果担心用户会对此感到迷惑,可以采用每一个 read语句只给一 个变量赋值的办法:用户在运行上面这个脚本的时候,就能够知道哪些信息赋给了哪个变量。如果是LINUX系统,那么...... 别忘了使用“-n”选项。 下载第5章 shell输入与输出37(续)5.3 catc a t是一个简单而通用的命令,可以用它来显示文件内容,创建文件,还可以用它来显示 控制字符。在使用 c a t命令时要注意,它不会在文件分页符处停下来;它会一下显示完整个文 件。如果希望每次显示一页,可以使用 m o r e命令或把 c a t命令的输出通过管道传递到另外一个 具有分页功能的命令中,请看下面的例子:$ cat myfile | more或$ cat myfile | pgcat命令的一般形式为:cat [options] filename1 ... filename2 ...cat命令最有用的选项就是: -v 显示控制字符 如果希望显示名为 myfile的文件,可以用:$ cat myfile如果希望显示myfile1、myfile2、myfile3这三个文件,可以用:$ cat myfile1 myfile2 myfile3如果希望创建一个名为 bigfile的文件,该文件包含上述三个文件的内容,可以把上面命令 的输出重定向到新文件中:$ cat myfile1 myfile2 myfile3 & bigfile如果希望创建一个新文件,并向其中输入一些内容,只需使用 c a t命令把标准输出重定向 到该文件中,这时 c a t命令的输入是标准输入 ― 键盘,你输入一些文字,输入完毕后按 &CTRL-D&结束输入。这真是一个非常简单的文字编辑器!还可以使用 c a t命令来显示控制字符。这里有一个对从 D O S机器上f t p过来的文件进行检察 的例子,在这个例子中,所有的控制字符 &CTRL-M&都在行末显示了出来。有一点要提醒的是,如果在敲入了 c a t以后就直接按回车,该命令会等你输入字符。如果 你本来就是要输入一些字符,那么它除了会在你输入时在屏幕上显示以外,还会再回显这些 385.4 管道第一部分 shell下载内容;最后按&CTRL-D&结束输入即可。可以通过管道把一个命令的输出传递给另一个命令作为输入。管道用竖杠 |表示。它的一 般形式为: 命令1 |命令2 其中|是管道符号。 在下面的例子中,在当前目录中执行文件列表操作,如果没有管道的话,所有文件就会 显示出来。当 s h e l l看到管道符号以后,就会把所有列出的文件交给管道右边的命令,因此管 道的含义正如它的名字所暗示的那样:把信息从一端传送到另外一端。在这个例子中,接下 来grep命令在文件列表中搜索 quarter1.doc:让我们再来用一幅图形象地讲解刚才的例子(见图 5-1) :这就是管道 Is 命令的输出图5-1 管道sed、awk和grep都很适合用管道,特别是在简单的一行命令中。在下面的例子中, who命 令的输出通过管道传递给 awk命令,以便只显示用户名和所在的终端。如果你希望列出系统中所有的文件系统,可以使用管道把 d f命令的输出传递给 a w k命令, a w k显示出其中的第一列。你还可以再次使用管道把 a w k的结果传递给 g r e p命令,去掉最上面 的题头filesystem。当然,你没准还会希望只显示出其中的分区名,不显示 / d e v /部分,这没问题;我们只要 在后面简单地加上另一个管道符号和相应的 sed命令即可。 下载第5章 shell输入与输出39在这个例子中,我们先对一个文件进行排序,然后通过管道输送到打印机。$ sort myfile | lp5.5 teet e e命令作用可以用字母 T来形象地表示。它把输出的一个副本输送到标准输出,另一个 副本拷贝到相应的文件中。如果希望在看到输出的同时,也将其存入一个文件,那么这个命 令再合适不过了。 它的一般形式为:tee -a files其中,-a表示追加到文件末尾。 当执行某些命令或脚本时,如果希望把输出保存下来, tee命令非常方便。 下面我们来看一个例子,我们使用 w h o命令,结果输出到屏幕上,同时保存在 w h o . o u t文 件中:可以用图5-2来表示刚才的例子。screen who命令的输出who.out$ who图5-2 tee在下面的例子中,我们把一些文件备份到磁带上,同时将所备份的文件记录在 t a p e . l o g文 件中。由于需要不断地对文件进行备份,为了保留上一次的日志,我们在 t e e命令中使用了 - a 选项。在上面的例子中,第一行末尾的反斜杠 \告诉s h e l l该命令尚未结束,应从下面一行继续读 入该命令。 可以在执行脚本之前,使用一个 e c h o命令告诉用户谁在执行这个脚本,输出结果保存在 40什么地方。第一部分 shell下载如果不想把输出重定向到文件中,可以不这样做,而是把它定向到某个终端上。在下面 的例子中,一个警告被发送到系统控制台上,表明一个磁盘清理进程即将运行。$ echo &stand-by disk cleanup starting in 1 minute&| tee /dev/console可以让不同的命令使用同一个日志文件,不过不要忘记使用 -a选项。5.6 标准输入、输出和错误当我们在 s h e l l中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描 述符来引用这些文件。由于文件描述符不容易记忆, shell同时也给出了相应的文件名。 下面就是这些文件描述符及它们通常所对应的文件名:文 件 文件描述符 0 1 2输入文件 ― 标准输入 输出文件 ― 标准输出 错误输出文件 ― 标准错误系统中实际上有 12个文件描述符,但是正如我们在上表中所看到的, 0、1、2是标准输入、 输出和错误。可以任意使用文件描述符 3到9。 5.6.1 标准输入 标准输入是文件描述符0。它是命令的输入,缺省是键盘,也可以是文件或其他命令的输出。 5.6.2 标准输出 标准输出是文件描述符 1。它是命令的输出,缺省是屏幕,也可以是文件。 5.6.3 标准错误 标准错误是文件描述符 2。这是命令错误的输出,缺省是屏幕,同样也可以是文件。你可 能会问,为什么会有一个专门针对错误的特殊文件?这是由于很多人喜欢把错误单独保存到 一个文件中,特别是在处理大的数据文件时,可能会产生很多错误。 如果没有特别指定文件说明符,命令将使用缺省的文件说明符(你的屏幕,更确切地说 是你的终端) 。5.7 文件重定向在执行命令时,可以指定命令的标准输入、输出和错误,要实现这一点就需要使用文件 下载第5章 shell输入与输出41重定向。表 5-1列出了最常用的重定向组合,并给出了相应的文件描述符。 在对标准错误进行重定向时,必须要使用文件描述符,但是对于标准输入和输出来说, 这不是必需的。为了完整起见,我们在表 5-1中列出了两种方法。表5-1 常用文件重定向命令command & filename command && filename command 1 & fielname command & filename 2&&1 command 2 & filename command 2 && filename command && filename 2&&1 command & filename &filename2 command & filename command && delimiter command &&m command &&m command &&把把标准输出重定向到一个新文件中 把把标准输出重定向到一个文件中 (追加) 把把标准输出重定向到一个文件中 把把标准输出和标准错误一起重定向到一个文件中 把把标准错误重定向到一个文件中 把把标准输出重定向到一个文件中 (追加) 把把标准输出和标准错误一起重定向到一个文件中 (追加) 把c o m m a n d命令以 f i l e n a m e文件作为标准输入,以 f i l e n a m e 2文件 作为标准输出 把command命令以filename文件作为标准输入 把从标准输入中读入,直至遇到 delimiter分界符 把把文件描述符 m作为标准输入 把把标准输出重定向到文件描述符 m中 把关闭标准输入5.7.1 重定向标准输出 让我们来看一个标准输出的例子。在下面的命令中,把 / e t c / p a s s w d文件中的用户 I D域按 照用户命排列。该命令的输出重定向到 sort.out文件中。要提醒注意的是,在使用 sort命令的时 候(或其他含有相似输入文件参数的命令 ),重定向符号一定要离开 s o r t命令两个空格,否则该 命令会把它当作输入文件。$ cat passwd | awk -F: '{print $1}' | sort 1&sort.out从表5-1中可以看出,我们也可以使用如下的表达方式,结果和上面一样:$ cat passwd | awk -F: '{print $1}' | sort &sort.out可以把很多命令的输出追加到同一文件中。在上面的例子中,所有的目录名和以 account开头的文件名都被写入到 file.out文件中。 如果希望把标准输出重定向到文件中,可以用 & f i l e n a m e。在下面的例子中, l s命令的所 有输出都被重定向到 ls.out文件中:$ ls &ls.out如果希望追加到已有的文件中 (在该文件不存在的情况下创建该文件 ),那么可以使用 &&filename:如果想创建一个长度为 0的空文件,可以用 '&filename':$ &myfile 42第一部分 shell下载5.7.2 重定向标准输入 可以指定命令的标准输入。在 awk一章就会遇到这样的情况。下面给出一个这样的例子:$ sort & name.txt在上面的命令中, s o r t命令的输入是采用重定向的方式给出的,不过也可以直接把相应的 文件作为该命令的参数:$ sort name.txt在上面的例子中,还可以更进一步地通过重定向为 s o r t命令指定一个输出文件 n a m e . o u t。 这样屏幕上将不会出现任何信息 (除了错误信息以外 ):$ sort &name.txt &name.out在发送邮件时,可以用重定向的方法发送一个文件中的内容。在下面的例子中,用户 louise将收到一个邮件,其中含有文件 contents.txt中的内容:$ mail louise & contents.txt重定向操作符command && delimiter是一种非常有用的命令,通常都被称为“此处”文挡。 我们将在本书后面的章节深入讨论这一问题。现在只介绍它的功能。 shell将分界符de

我要回帖

更多关于 shell printf 对齐 的文章

 

随机推荐