在 Sheryl Calish 撰写的“Linux 文件命令精通指南”这篇出色的文章中,您学习到了一些对于 Linux 新手尤为重要的常用 Linux 命令。既然您现在已经掌握了基础知识,下面我们将介绍一些更为复杂但却非常有用的命令。 在这个共分 4 个部分的文章系列中,您将学习各种常用命令的一些并不被人们所熟知的使用技巧,以及可以使这些命令更为有用的用法变化形式。在学习本文章系列过程中,您将先后了解一些难于掌握的命令。 注意,根据您所使用的 Linux 的特定版本或编译的特定内核,这些命令可能会存在差别,但即便如此,这种差别也很小。 轻松更改所有者、组和权限在 Sheryl 的文章中,您学习了如何使用 chown 和 chgrp 命令来更改文件的所有权和组。假设有如下几个文件: # ls -l total 8 -rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1 -rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file2 -rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file3 -rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file4 -rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file5 -rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file6 并且您需要更改所有文件的权限以便与 file1 的权限匹配。当然,您可以执行 chmod 644 * 来进行此更改,但如果您要编写一个脚本来执行该操作,而事先却并不知道这些权限,那该怎么办?或者,您可能要基于许多不同的文件进行多个权限更改,但却发现逐个使用这些文件的权限并进行相应的修改并不可行。 一种更好的方法是使权限类似于另一个文件的权限。以下命令使 file2 的权限与 file1 相同: chmod --reference file1 file2 现在,如果您查看以下示例: # ls -l file[12] total 8 -rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1 -rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2 file2 的权限完全按照 file1 中的权限进行了更改。您不必先获取 file1 的权限。 您还可以将同一技巧用于文件中的组成员关系。要使 file2 的组与 file1 相同,可以执行以下命令: # chgrp --reference file1 file2 # ls -l file[12] -rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1 -rw-r--r-- 1 oracle users 132 Aug 4 04:02 file2 当然,适用于更改组的方法也同样适用于所有者。下面演示了如何将同一技巧用于所有权更改。如果权限如下所示: # ls -l file[12] -rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1 -rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2 则可以按以下方式更改所有权: # chown --reference file1 file2 # ls -l file[12] -rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1 -rw-r--r-- 1 ananda users 132 Aug 4 04:02 file2 注意,组和所有者已经更改。 适用于 Oracle 用户的技巧您可以使用该技巧根据某个参考可执行文件更改目录中 Oracle 可执行文件的所有权和权限。该技巧对于移植非常有用,在移植期间您可以(并且可能应该)以不同的用户身份安装文件,并在以后将这些文件转移至常规的 Oracle 软件所有者。 有关文件的详细说明ls 命令及其许多参数提供了一些非常有用的文件信息。另一个不太为人所熟知的命令 stat 提供了一些更为有用的信息。 下面演示了如何对可执行文件“oracle”(位于 $ORACLE_HOME/bin 目录下)使用此命令。 # cd $ORACLE_HOME/bin # stat oracle File: `oracle' Size: 93300148 Blocks:182424 IO Block:4096 Regular File Device: 343h/835d Inode: 12009652 Links: 1 Access: (6751/-rwsr-s--x) Uid:( 500/ oracle) Gid:( 500/ dba) Access: 2006-08-04 04:30:52.000000000 -0400 Modify: 2005-11-02 11:49:47.000000000 -0500 Change: 2005-11-02 11:55:24.000000000 -0500 注意使用该命令获得的信息:除了通常的文件大小(也可以使用 ls -l 命令获得)以外,您还获得了该文件占用的块数。通常的 Linux 块大小为 512 字节,因此一个大小为 93,300,148 字节的文件将占用 (93300148/512=) 182226.85 个块。由于块都是完整占用,因此该文件使用了一些整数个数的块。无需猜测就可以获得确切的块数。 您还可以从以上输出中获得文件所有权的 GID 和 UID,以及权限的八进制表示形式 (6751)。如果要将文件恢复到它现在具有的相同权限,可以使用 chmod 6751 oracle,而不是显式拼写这些权限。 以上输出最有用的部分是文件访问时间戳信息。该输出显示,该文件被访问的时间是 2006-08-04 04:30:52(显示在“Access:”的旁边),即 2006 年 8 月 4 日上午 4:30:52。这是某个人开始使用数据库的时间。该文件的修改时间是 2005-11-02 11:49:47(显示在“Modify:”的旁边)。最后,“Change:”旁边的时间戳显示文件状态更改的时间。 stat 命令的修改符 -f 显示了有关文件系统(而非文件)的信息: # stat -f oracle File: "oracle" ID: 0 Namelen:255 Type:ext2/ext3 Blocks: Total: 24033242 Free: 15419301 Available: 14198462 Size: 4096 Inodes: Total: 12222464 Free: 12093976 另一个选项 -t 显示了完全相同的信息,只不过是在一行中显示的: # stat -t oracle oracle 93300148 182424 8de9 500 500 343 12009652 1 0 0 1154682061 1130950187 1130950524 4096 这对 shell 脚本非常有用,在 shell 脚本中可以使用一个简单的 cut 命令获得值以进行进一步处理。 适用于 Oracle 用户的技巧重新链接 Oracle(通常在安装补丁过程中执行)时,将在创建新的可执行文件之前将现有可执行文件的名称更改为其他名称。例如,可以使用以下命令重新链接所有实用程序 relink utilities 该命令对 sqlplus 可执行文件进行重新编译,此外还执行其他操作。它将现有的可执行文件 sqlplus 命名为 sqlplusO。如果重新编译由于某种原因失败,则 relink 进程会将 sqlplusO 重命名为 sqlplus,并撤销更改。同样,如果在应用补丁后发现功能问题,则可以通过手动重命名文件来快速撤销补丁。 下面演示了如何对这些文件使用 stat: # stat sqlplus* File: 'sqlplus' Size: 9865 Blocks:26 IO Block:4096 Regular File Device: 343h/835d Inode:9126079 Links: 1 Access: (0751/-rwxr-x--x) Uid:( 500/ oracle) Gid:( 500/ dba) Access: 2006-08-04 05:15:18.000000000 -0400 Modify: 2006-08-04 05:15:18.000000000 -0400 Change: 2006-08-04 05:15:18.000000000 -0400 File: 'sqlplusO' Size: 8851 Blocks:24 IO Block:4096 Regular File Device: 343h/835d Inode:9125991 Links: 1 Access: (0751/-rwxr-x--x) Uid:( 500/ oracle) Gid:( 500/ dba) Access: 2006-08-04 05:13:57.000000000 -0400 Modify: 2005-11-02 11:50:46.000000000 -0500 Change: 2005-11-02 11:55:24.000000000 -0500 输出显示 sqlplusO 的修改时间是 2005 年 11 月 11 日,而 sqlplus 的修改时间是 2006 年 8 月 4 日,该时间也是 sqlplusO 的状态更改时间。该输出表明,sqlplus 的原始版本从 2005 年 11 月 11 到 2006 年 8 月 4 日这段时间内一直正常运行。如果要诊断某些功能问题,则该信息将是一个非常不错的起点。除了文件更改以外,如果您知道权限的更改时间,则可以将它与发觉的任何功能问题联系起来。 另一个重要的输出是文件大小,不同的文件存在不同的大小(sqlplus 的大小为 9865 字节,而 sqlplusO 的大小为 8851),这表明版本不仅仅经过重新编译,实际上这些版本通过其他库进行了更改(也许是这样)。文件大小的不同还指示了某些问题的可能原因。 文件类型查看文件时,如何知道它的文件类型?命令 file 可以显示文件类型。例如: # file alert_DBA102.log alert_DBA102.log:ASCII text 文件 alert_DBA102.log 是一个 ASCII 文本文件。来看看更多示例: # file initTESTAUX.ora.Z initTESTAUX.ora.Z:compress'd data 16 bits 该示例指示文件是压缩文件,但如何知道文件的压缩类型?方法之一是将该文件解压缩并再次运行它;但这实际上是几乎不可能的。一种更简便的方法是使用参数 -z: # file -z initTESTAUX.ora.Z initTESTAUX.ora.Z:ASCII text (compress'd data 16 bits) 另一种方法是显示符号链接: # file spfile+ASM.ora.ORIGINAL spfile+ASM.ora.ORIGINAL:symbolic link to /u02/app/oracle/admin/DBA102/pfile/spfile+ASM.ora.ORIGINAL 尽管该方法很有用,但所指向的文件的类型是什么?可以使用选项 -l,而不必再次运行文件: # file -L spfile+ASM.ora.ORIGINAL spfile+ASM.ora.ORIGINAL:data 该示例清楚地表明该文件是数据文件。注意,与 init.ora 不同的是,spfile 文件是一个二进制文件;因此文件显示为数据文件。 适用于 Oracle 用户的技巧假设您要在用户转储目标目录中搜索某个跟踪文件,但不知道该文件是否位于其他目录并只以一个符号链接形式存在,或某个人是否压缩了该文件(甚至对其进行了重命名)。有一点您是知道的:该文件肯定是一个 ascii 文件。下面演示了如何执行操作: file -Lz * | grep ASCII | cut -d":"-f1 | xargs ls -ltr 该命令将检查 ASCII 文件(即使它们经过了压缩)并按时间顺序将其列出。 比较文件如何判断两个文件(file1 和 file2)是否相同?方法有多种,每种方法都有其自身的优点。 diff。最简单的命令是 diff,用于显示两个文件之间的差别。以下是这两个文件的内容: # cat file1 In file1 only In file1 and file2 # cat file2 In file1 and file2 In file2 only 使用 diff 命令能够了解这两个文件之间的差别,如下所示: # diff file1 file2 1d0 < In file1 only 2a2 > In file2 only # 在以上输出中,第一列中的“<”表示该行位于上面最先提到的文件(即 file1)中。第一列中的“>”表示该行位于第二个文件 (file2) 中。输出第一行中的字符 1d0 显示为了作用于文件 file1(以使其与 file2 相同)而在 sed 中必须执行的操作。 另一个选项 -y 显示了相同的输出,只不过输出是并排显示的: # diff -y file1 file2 -W 120 In file1 only < In file1 and file2 In file1 and file2 > In file2 only -W 选项是可选的;它仅指示该命令使用宽度为 120 个字符的屏幕输出,这对于包含长行的文件很有用。 如果只希望了解文件是否不同,而不必知道如何不同,则可以使用 -q 选项。 # diff -q file3 file4 # diff -q file3 file2 Files file3 and file2 differ 由于文件 file3 和 file4 相同,因此没有输出;在另一个示例中,将报告文件存在差别。 如果要编写 shell 脚本,则采用以下方式生成可以分析的输出可能比较有用。-u 选项可以执行该操作: # diff -u file1 file2 --- file1 2006-08-04 08:29:37.000000000 -0400 +++ file2 2006-08-04 08:29:42.000000000 -0400 @@ -1,2 +1,2 @@ -In file1 only In file1 and file2 +In file2 only 以上输出显示了这两个文件的内容,但并未显示重复内容,第一列中的 + 号和 - 号指示文件中的行。第一列中的任何字符均未指示这两个文件中同时存在的内容。 该命令可以识别空格。如果要忽略空格,请使用 -b 选项。使用 -B 选项忽略空白行。最后,使用 -i 忽略大小写。 diff 命令还可以应用于目录。命令 diff dir1 dir2 显示文件文件存在于任一目录中;无论文件是存在于这两个目录中的一个,还是同时存在于这两个目录中。如果它找到同名的子目录,则不会继续查看任何单个文件是否存在差别。示例如下: # diff DBA102 PROPRD Common subdirectories:DBA102/adump and PROPRD/adump Only in DBA102:afiedt.buf Only in PROPRD:archive Only in PROPRD:BACKUP Only in PROPRD:BACKUP1 Only in PROPRD:BACKUP2 Only in PROPRD:BACKUP3 Only in PROPRD:BACKUP4 Only in PROPRD:BACKUP5 Only in PROPRD:BACKUP6 Only in PROPRD:BACKUP7 Only in PROPRD:BACKUP8 Only in PROPRD:BACKUP9 Common subdirectories:DBA102/bdump and PROPRD/bdump Common subdirectories:DBA102/cdump and PROPRD/cdump Only in PROPRD:CreateDBCatalog.log Only in PROPRD:CreateDBCatalog.sql Only in PROPRD:CreateDBFiles.log Only in PROPRD:CreateDBFiles.sql Only in PROPRD:CreateDB.log Only in PROPRD:CreateDB.sql Only in DBA102:dpdump Only in PROPRD:emRepository.sql Only in PROPRD:init.ora Only in PROPRD:JServer.sql Only in PROPRD:日志 Only in DBA102:oradata Only in DBA102:pfile Only in PROPRD:postDBCreation.sql Only in PROPRD:RMANTEST.sh Only in PROPRD:RMANTEST.sql Common subdirectories:DBA102/scripts and PROPRD/scripts Only in PROPRD:sqlPlusHelp.log Common subdirectories:DBA102/udump and PROPRD/udump 注意,普通的子目录只按这种方式报告,而不进行比较。如果要进一步深究,并比较这些子目录中的文件,则应使用以下命令: diff -r dir1 dir2 该命令将采用递归方式进入每个子目录,以比较文件并报告同名文件之间的差别。 适用于 Oracle 用户的技巧diff 的一种常见用法是区分不同的 init.ora 文件。作为一种最佳实践,我在更改之前通常对文件进行复制并重命名(例如,将 initDBA102.ora 复制并重命名为 initDBA102.080306.ora 以表示 2006 年 8 月 3 日)。文件所有版本之间的一个简单的 diff 就可以快速指出哪些内容发生更改以及更改时间。 这是一个非常强大的用于管理 Oracle 根目录的命令。作为最佳实践,我在应用补丁时从不更新 Oracle 根目录。例如,假设当前的 Oracle 版本为 10.2.0.1。ORACLE_HOME 可能为 /u01/app/oracle/product/10.2/db1。当需要将它更新为 10.2.0.2 时,我不会对此 Oracle 根目录打补丁。相反,我将在 /u01/app/oracle/product/10.2/db2 上启动一个全新的安装,然后对该根目录打补丁。准备就绪后,我使用以下命令: # sqlplus / as sysdba SQL> shutdown immediate SQL> exit # export ORACLE_HOME=/u01/app/oracle/product/10.2/db2 # export PATH=$ORACLE_HOME/bin:$PATH # sqlplus / as sysdba SQL> @$ORACLE_HOME/rdbms/admin/catalog ... 等等。 该方法的目的是不破坏原始的 Oracle 根目录,因此我可以在出现问题时轻松地进行恢复。这还意味着数据库关闭并再次启动,而且瞬间即可完成。如果我将补丁直接安装到 Oracle 根目录上,则必须长时间(补丁应用的整个持续时间)关闭数据库。此外,如果补丁应用由于某种原因出现故障,则不必清理 Oracle 根目录。 既然有多个 Oracle 根目录,那如何查看哪些内容发生了更改?方法其实很简单,我可以使用以下命令: diff -r /u01/app/oracle/product/10.2/db1 /u01/app/oracle/product/10.2/db2 | grep -v Common 该命令显示了两个 Oracle 根目录之间的差别,以及同名文件之间的差别。某些重要的文件(如 tnsnames.ora、listener.ora 以及 sqlnet.ora)不会有太大的差别,但如果差别很大,那么我就需要知道差别的原因。 cmp.命令 cmp 类似于 diff: # cmp file1 file2 file1 file2 differ:byte 10, line 1 只要遇到差别就会返回输出。可以使用此输出标识文件在何处可能存在差别。与 diff 一样,cmp 有很多选项,其中最重要的选项是 -s 选项,它只返回一个代码:
示例如下: # cmp -s file3 file4 # echo $? 0 特殊变量 $? 指示返回代码来自上次执行的命令。在本示例中,该变量为 0,表示文件 file1 和 file2 相同。 # cmp -s file1 file2 # echo $? 1 表示 file1 和 file2 不同。 cmp 的这个属性对于 shell 脚本非常有用,因为在 shell 脚本中您只希望检查两个文件是否存在差别,而不必检查差别是什么。该命令的另一个重要用途是比较二进制文件,而 diff 对于比较二进制文件可能并不可靠。 适用于 Oracle 用户的技巧回顾一下上一个提示,当您重新链接 Oracle 可执行文件时,旧版本在被覆盖之前将一直保留。因此,在重新链接时,可执行文件 sqlplus 重命名为“sqlplusO”,并且新编译的 sqlplus 置于 $ORACLE_HOME/bin 中。那么,如何确保刚刚创建的 sqlplus 存在差别?只需使用以下命令: # cmp sqlplus sqlplusO sqlplus sqlplusO differ:byte 657, line 7 如果检查大小: # ls -l sqlplus* -rwxr-x--x 1 oracle dba 8851 Aug 4 05:15 sqlplus -rwxr-x--x 1 oracle dba 8851 Nov 2 2005 sqlplusO 即使这两个示例中的大小完全相同,cmp 也可以证明这两个程序存在差别。 comm.命令 comm 与其他命令相似,只是输出分三列显示,并且列之间由制表符分隔。示例如下: # comm file1 file2 In file1 and file2 In file1 only In file1 and file2 In file2 only
如果您想要查看某个文件的内容(另一个文件中不存在这些内容),而不仅仅是差别(SQL 语言中 MINUS 实用程序的排序),则该命令将很有用。-1 选项将不显示在第一个文件中找到的内容: # comm -1 file1 file2 In file1 and file2 In file2 only md5sum.该命令将生成文件的 32 位 MD5 散列值: # md5sum file1 ef929460b3731851259137194fe5ac47 file1 可以将两个具有相同校验和的文件视为相同。而该命令的用途并不仅仅限于比较文件。它还可以提供一种机制来确保文件的完整性。 假设您有两个需要保护的重要文件,file1 和 file2。可以使用 --check 选项检查并确保文件未更改。首先,为这些重要文件创建校验和文件,然后对其进行安全保存: # md5sum file1 file2 > f1f2 以后,当您要验证这些文件是否仍保持不变时,可执行如下操作: # md5sum --check f1f2 file1:OK file2:OK 这清楚地表明文件未被修改。现在,更改一个文件并检查 MD5: # cp file2 file1 # md5sum --check f1f2 file1:FAILED file2:OK md5sum:WARNING:1 of 2 computed checksums did NOT match 输出清楚地表明 file1 已被修改。 适用于 Oracle 用户的技巧md5sum 是一个非常强大的用于安全性实施的命令。您所管理的某些配置文件(如 listener.ora、tnsnames.ora 和 init.ora)对于成功的 Oracle 基础架构非常重要,任何修改都可能会导致停机。这些通常是更改控制过程的一部分。不要相信别人所说的这些文件并未更改,使用 MD5 校验和执行该命令。创建一个校验和文件,并在每次执行计划的更改时重新创建该文件。作为合规性的一部分,使用 md5sum 命令检查该文件。如果某个人无意中更新了这些重要文件中的一个,您就会立即捕获更改。 同样,您还可以为 $ORACLE_HOME/bin 中的所有可执行文件创建 MD5 校验和,并不断比较它们以捕获未授权的修改。 结论到目前为止,您只学习了对于高效执行作业比较有用的 Linux 命令的一部分。在下一部分中,我将介绍一些更复杂但却很有用的命令,如 strace、whereis、renice、skill 等。 Arup Nanda (arup@proligence.com) 担任 Oracle DBA 已 12 余载,处理过各方面的数据库管理问题,从性能优化到安全性和灾难恢复,无所不及。他与人合著了 PL/SQL for DBAs (O'Reilly Media, 2005),并曾在 2003 年荣获 Oracle Magazine 的 DBA 称号,现在为 Oracle ACE。 (责任编辑:admin) |