标准的 UNIX 归档实用程序。 [1] 最初是一个 Tape ARchiving (磁带归档) 程序,它已发展成为一个通用的软件包,可以处理各种类型的归档,并支持所有类型的目标设备,从磁带驱动器到常规文件,甚至是stdout (标准输出)(参见 示例 3-4)。 GNU tar 已被修补以接受各种压缩过滤器,例如:tar czvf archive_name.tar.gz *,它以递归方式归档并 gzips 当前工作目录($PWD)中目录树中的所有文件,除了点文件。 [2]
一些有用的 tar 选项
-c创建 (新存档)
-x提取 (从现有存档中提取文件)
--delete删除 (从现有存档中删除文件)
![]() | 此选项不适用于磁带设备。 |
-r追加 (文件到现有存档)
-A追加 (tar 文件到现有存档)
-t列出 (现有存档的内容)
-u更新存档
-d比较存档与指定文件系统
--after-date仅处理日期戳晚于指定日期的文件
-z gzip 存档
(压缩或解压缩,取决于是否与-c或-x) 选项组合使用
-j bzip2 存档
![]() | 从损坏的 gzipped tar 存档中恢复数据可能很困难。 归档重要文件时,请制作多个备份。 |
Shell 归档实用程序。 shell 存档中的文本和/或二进制文件在不压缩的情况下连接,生成的存档本质上是一个 shell 脚本,包含 #!/bin/sh 标头,包含所有必要的解档命令,以及文件本身。 目标文件中的不可打印的二进制字符将转换为输出 shar 文件中的可打印 ASCII 字符。 Shar 存档仍然出现在 Usenet 新闻组中,但在其他方面,shar 已被 tar/gzip 取代。 unshar 命令解压缩 shar 存档。
mailshar 命令是一个 Bash 脚本,它使用 shar 将多个文件连接成一个文件以便通过电子邮件发送。 此脚本支持压缩和 uuencoding。
用于创建和操作存档的实用程序,主要用于二进制目标文件库。
Red Hat Package Manager(Red Hat 软件包管理器),或 rpm 实用程序为源或二进制存档提供了一个包装器。 它包括用于安装和检查软件包完整性的命令,以及其他功能。
一个简单的 rpm -i package_name.rpm 通常足以安装一个软件包,尽管还有许多其他选项可用。
![]() | rpm -qf识别文件来自哪个软件包。
|
![]() | rpm -qa给出一个给定系统上所有已安装的 rpm 软件包的完整列表。 一个rpm -qa package_name仅列出与package_name.
|
这个专门的存档复制命令 (copy input and output - 复制输入和输出) 已经很少见了,已经被 tar/gzip 所取代。 它仍然有它的用途,例如移动目录树。 通过指定适当的块大小(用于复制),它可以比 tar 快得多。
示例 16-30. 使用 cpio 移动目录树
#!/bin/bash # Copying a directory tree using cpio. # Advantages of using 'cpio': # Speed of copying. It's faster than 'tar' with pipes. # Well suited for copying special files (named pipes, etc.) #+ that 'cp' may choke on. ARGS=2 E_BADARGS=65 if [ $# -ne "$ARGS" ] then echo "Usage: `basename $0` source destination" exit $E_BADARGS fi source="$1" destination="$2" ################################################################### find "$source" -depth | cpio -admvp "$destination" # ^^^^^ ^^^^^ # Read the 'find' and 'cpio' info pages to decipher these options. # The above works only relative to $PWD (current directory) . . . #+ full pathnames are specified. ################################################################### # Exercise: # -------- # Add code to check the exit status ($?) of the 'find | cpio' pipe #+ and output appropriate error messages if anything went wrong. exit $? |
此命令从 rpm 存档中提取 cpio 存档。
示例 16-31. 解包 rpm 存档
#!/bin/bash # de-rpm.sh: Unpack an 'rpm' archive : ${1?"Usage: `basename $0` target-file"} # Must specify 'rpm' archive name as an argument. TEMPFILE=$$.cpio # Tempfile with "unique" name. # $$ is process ID of script. rpm2cpio < $1 > $TEMPFILE # Converts rpm archive into #+ cpio archive. cpio --make-directories -F $TEMPFILE -i # Unpacks cpio archive. rm -f $TEMPFILE # Deletes cpio archive. exit 0 # Exercise: # Add check for whether 1) "target-file" exists and #+ 2) it is an rpm archive. # Hint: Parse output of 'file' command. |
pax portable archive exchange (可移植存档交换) 工具包有助于定期文件备份,旨在实现各种 UNIX 版本之间的交叉兼容。 它旨在取代 tar 和 cpio。
pax -wf daily_backup.pax ~/linux-server/files # Creates a tar archive of all files in the target directory. # Note that the options to pax must be in the correct order -- #+ pax -fw has an entirely different effect. pax -f daily_backup.pax # Lists the files in the archive. pax -rf daily_backup.pax ~/bsd-server/files # Restores the backed-up files from the Linux machine #+ onto a BSD one. |
请注意,pax 处理许多标准的归档和压缩命令。
标准的 GNU/UNIX 压缩实用程序,取代了劣质的专有 compress。 相应的解压缩命令是 gunzip,它等同于 gzip -d。
![]() | 该-c选项将 gzip 的输出发送到stdout (标准输出)。 当 管道传输到其他命令时,这很有用。 |
zcat 过滤器将 gzipped 文件解压缩到stdout (标准输出),作为管道或重定向的可能输入。 实际上,这是一个适用于压缩文件的 cat 命令(包括使用较旧的 compress 实用程序处理的文件)。 zcat 命令等同于 gzip -dc。
![]() | 在某些商业 UNIX 系统上,zcat 是 uncompress -c 的同义词,并且不适用于 gzipped 文件。 |
另请参见 示例 7-7。
一种替代的压缩实用程序,通常比 gzip 更有效(但更慢),尤其是在大型文件上。 相应的解压缩命令是 bunzip2。
与 zcat 命令类似,bzcat 将 bzipped2-ed 文件解压缩到stdout (标准输出).
![]() | 较新版本的 tar 已通过 bzip2 支持进行了修补。 |
这是一个在商业 UNIX 发行版中找到的较旧的专有压缩实用程序。 更高效的 gzip 在很大程度上已经取代了它。 Linux 发行版通常包含一个用于兼容性的 compress 工作副本,尽管 gunzip 可以解压缩使用 compress 处理的文件。
![]() | znew 命令将 compressed 文件转换为 gzipped 文件。 |
另一种压缩 (squeeze - 挤压) 实用程序,一个仅适用于已排序的 ASCII 单词列表的过滤器。 它使用过滤器的标准调用语法,sq < input-file > output-file。 快速,但效率远不如 gzip。 相应的解压缩过滤器是 unsq,像 sq 一样调用。
![]() | sq 的输出可以管道传输到 gzip 以进行进一步压缩。 |
跨平台文件归档和压缩实用程序,与 DOS pkzip.exe 兼容。 "Zipped" (Zip 压缩的) 存档似乎比 "tarballs" (tar 包) 更常见的 Internet 文件交换媒介。
这些 Linux 实用程序允许解压缩使用 DOS arc.exe, arj.exe, 和 rar.exe 程序压缩的存档。
高效的 Lempel-Ziv-Markov 压缩。 lzma 的语法类似于 gzip 的语法。 7-zip 网站 提供了更多信息。
一种新型的高效压缩工具,向后兼容 lzma,并且具有类似于 gzip 的调用语法。 有关更多信息,请参见 Wikipedia 条目。
用于识别文件类型的实用程序。 命令file file-name将返回file-name的文件规范,例如ascii text (ascii 文本)或data (数据)。 它引用 magic numbers (魔数),可以在以下位置找到:/usr/share/magic, /etc/magic, 或/usr/lib/magic, 取决于 Linux/UNIX 发行版。
该-f选项使 file 在 batch (批处理) 模式下运行,从指定的文件中读取要分析的文件名列表。-z选项在压缩目标文件上使用时,会强制尝试分析未压缩的文件类型。
bash$ file test.tar.gz test.tar.gz: gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix bash file -z test.tar.gz test.tar.gz: GNU tar archive (gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix) |
# Find sh and Bash scripts in a given directory: DIRECTORY=/usr/local/bin KEYWORD=Bourne # Bourne and Bourne-Again shell scripts file $DIRECTORY/* | fgrep $KEYWORD # Output: # /usr/local/bin/burn-cd: Bourne-Again shell script text executable # /usr/local/bin/burnit: Bourne-Again shell script text executable # /usr/local/bin/cassette.sh: Bourne shell script text executable # /usr/local/bin/copy-cd: Bourne-Again shell script text executable # . . . |
示例 16-32. 从 C 程序文件中删除注释
#!/bin/bash # strip-comment.sh: Strips out the comments (/* COMMENT */) in a C program. E_NOARGS=0 E_ARGERROR=66 E_WRONG_FILE_TYPE=67 if [ $# -eq "$E_NOARGS" ] then echo "Usage: `basename $0` C-program-file" >&2 # Error message to stderr. exit $E_ARGERROR fi # Test for correct file type. type=`file $1 | awk '{ print $2, $3, $4, $5 }'` # "file $1" echoes file type . . . # Then awk removes the first field, the filename . . . # Then the result is fed into the variable "type." correct_type="ASCII C program text" if [ "$type" != "$correct_type" ] then echo echo "This script works on C program files only." echo exit $E_WRONG_FILE_TYPE fi # Rather cryptic sed script: #-------- sed ' /^\/\*/d /.*\*\//d ' $1 #-------- # Easy to understand if you take several hours to learn sed fundamentals. # Need to add one more line to the sed script to deal with #+ case where line of code has a comment following it on same line. # This is left as a non-trivial exercise. # Also, the above code deletes non-comment lines with a "*/" . . . #+ not a desirable result. exit 0 # ---------------------------------------------------------------- # Code below this line will not execute because of 'exit 0' above. # Stephane Chazelas suggests the following alternative: usage() { echo "Usage: `basename $0` C-program-file" >&2 exit 1 } WEIRD=`echo -n -e '\377'` # or WEIRD=$'\377' [[ $# -eq 1 ]] || usage case `file "$1"` in *"C program text"*) sed -e "s%/\*%${WEIRD}%g;s%\*/%${WEIRD}%g" "$1" \ | tr '\377\n' '\n\377' \ | sed -ne 'p;n' \ | tr -d '\n' | tr '\377' '\n';; *) usage;; esac # This is still fooled by things like: # printf("/*"); # or # /* /* buggy embedded comment */ # # To handle all special cases (comments in strings, comments in string #+ where there is a \", \\" ...), #+ the only way is to write a C parser (using lex or yacc perhaps?). exit 0 |
which command 给出了 "command (命令)" 的完整路径。 这对于查找特定命令或实用程序是否已安装在系统上很有用。
$bash which rm
/usr/bin/rm |
有关此命令的有趣用法,请参见 示例 36-16。
与上面的 which 类似,whereis command 给出了 "command (命令)" 的完整路径,以及它的 manpage (手册页)。
$bash whereis rm
rm: /bin/rm /usr/share/man/man1/rm.1.bz2 |
whatis command 在whatis数据库中查找 "command (命令)"。 这对于识别系统命令和重要的配置文件很有用。 可以将其视为简化的 man 命令。
$bash whatis whatis
whatis (1) - search the whatis database for complete words |
示例 16-33. 探索/usr/X11R6/bin
#!/bin/bash # What are all those mysterious binaries in /usr/X11R6/bin? DIRECTORY="/usr/X11R6/bin" # Try also "/bin", "/usr/bin", "/usr/local/bin", etc. for file in $DIRECTORY/* do whatis `basename $file` # Echoes info about the binary. done exit 0 # Note: For this to work, you must create a "whatis" database #+ with /usr/sbin/makewhatis. # You may wish to redirect output of this script, like so: # ./what.sh >>whatis.db # or view it a page at a time on stdout, # ./what.sh | less |
另请参见 示例 11-3。
显示详细的目录列表。 效果类似于 ls -lb。
这是 GNU fileutils 之一。
bash$ vdir total 10 -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo.bak -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.xrolo bash ls -l total 10 -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo.bak -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.xrolo |
locate 命令使用专门为此目的存储的数据库来搜索文件。 slocate 命令是 locate 的安全版本 (可能已别名为 slocate)。
$bash locate hickson
/usr/lib/xephem/catalogs/hickson.edb |
这些命令检索或设置文件访问控制列表 -- 所有者、组和文件权限。
bash$ getfacl * # file: test1.txt # owner: bozo # group: bozgrp user::rw- group::rw- other::r-- # file: test2.txt # owner: bozo # group: bozgrp user::rw- group::rw- other::r-- bash$ setfacl -m u:bozo:rw yearly_budget.csv bash$ getfacl yearly_budget.csv # file: yearly_budget.csv # owner: accountant # group: budgetgrp user::rw- user:bozo:rw- user:accountant:rw- group::rw- mask::rw- other::r-- |
显示符号链接指向的文件。
bash$ readlink /usr/bin/awk ../../bin/gawk |
使用 strings 命令查找二进制文件或数据文件中的可打印字符串。它将列出目标文件中找到的可打印字符序列。 这对于快速“肮脏”地检查核心转储或查看未知图形图像文件可能很方便(strings image-file | more可能会显示类似 JFIF 的内容,这将标识该文件为 jpeg 图形)。 在脚本中,您可能会使用 grep 或 sed 解析 strings 的输出。 请参阅 示例 11-8 和 示例 11-10。
示例 16-34. 一个“改进的” strings 命令
#!/bin/bash # wstrings.sh: "word-strings" (enhanced "strings" command) # # This script filters the output of "strings" by checking it #+ against a standard word list file. # This effectively eliminates gibberish and noise, #+ and outputs only recognized words. # =========================================================== # Standard Check for Script Argument(s) ARGS=1 E_BADARGS=85 E_NOFILE=86 if [ $# -ne $ARGS ] then echo "Usage: `basename $0` filename" exit $E_BADARGS fi if [ ! -f "$1" ] # Check if file exists. then echo "File \"$1\" does not exist." exit $E_NOFILE fi # =========================================================== MINSTRLEN=3 # Minimum string length. WORDFILE=/usr/share/dict/linux.words # Dictionary file. # May specify a different word list file #+ of one-word-per-line format. # For example, the "yawl" word-list package, # http://bash.deta.in/yawl-0.3.2.tar.gz wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` # Translate output of 'strings' command with multiple passes of 'tr'. # "tr A-Z a-z" converts to lowercase. # "tr '[:space:]'" converts whitespace characters to Z's. # "tr -cs '[:alpha:]' Z" converts non-alphabetic characters to Z's, #+ and squeezes multiple consecutive Z's. # "tr -s '\173-\377' Z" converts all characters past 'z' to Z's #+ and squeezes multiple consecutive Z's, #+ which gets rid of all the weird characters that the previous #+ translation failed to deal with. # Finally, "tr Z ' '" converts all those Z's to whitespace, #+ which will be seen as word separators in the loop below. # *********************************************************************** # Note the technique of feeding/piping the output of 'tr' back to itself, #+ but with different arguments and/or options on each successive pass. # *********************************************************************** for word in $wlist # Important: # $wlist must not be quoted here. # "$wlist" does not work. # Why not? do strlen=${#word} # String length. if [ "$strlen" -lt "$MINSTRLEN" ] # Skip over short strings. then continue fi grep -Fw $word "$WORDFILE" # Match whole words only. # ^^^ # "Fixed strings" and #+ "whole words" options. done exit $? |
diff:灵活的文件比较实用程序。 它逐行顺序比较目标文件。 在某些应用程序中,例如比较单词词典,通过 sort 和 uniq 过滤文件,然后将它们传递给 diff 可能很有帮助。diff file-1 file-2输出文件中不同的行,使用插入符号显示每一行属于哪个文件。
该--side-by-sidediff 的选项并排输出每个比较的文件,逐行显示在单独的列中,并标记不匹配的行。 该-c和-u选项同样使命令的输出更容易解释。
有各种花哨的 diff 前端可用,例如 sdiff、wdiff、xdiff 和 mgdiff。
diff 的一个常见用途是生成与 patch 一起使用的差异文件。 该-e选项输出适用于 ed 或 ex 脚本的文件。
patch:灵活的版本控制实用程序。 给定由 diff 生成的差异文件,patch 可以将软件包的先前版本升级到较新版本。 分发相对较小的“差异”文件比分发新修订的软件包的整个正文要方便得多。 内核“补丁”已成为分发 Linux 内核频繁发布的首选方法。
patch -p1 <patch-file # Takes all the changes listed in 'patch-file' # and applies them to the files referenced therein. # This upgrades to a newer version of the package. |
修补内核
cd /usr/src gzip -cd patchXX.gz | patch -p0 # Upgrading kernel source using 'patch'. # From the Linux kernel docs "README", # by anonymous author (Alan Cox?). |
![]() | diff 命令还可以递归地比较目录(对于存在的文件名)。
|
diff 的扩展版本,一次比较三个文件。 此命令在成功执行后返回退出值 0,但不幸的是,这不提供有关比较结果的任何信息。
bash$ diff3 file-1 file-2 file-3 ==== 1:1c This is line 1 of "file-1". 2:1c This is line 1 of "file-2". 3:1c This is line 1 of "file-3" |
merge(三向文件合并)命令是 diff3 的一个有趣的补充。 其语法是merge Mergefile file1 file2。 结果是输出到Mergefile从file1到file2所做的更改。 将此命令视为 patch 的精简版本。
比较和/或编辑两个文件,以便将它们合并到输出文件中。 由于它的交互性,此命令在脚本中很少使用。
cmp 命令是上面 diff 的简化版本。 虽然 diff 报告两个文件之间的差异,但 cmp 仅显示它们在何处不同。
![]() | 与 diff 一样,如果比较的文件相同,cmp 返回退出状态 0,如果文件不同,则返回 1。 这允许在 shell 脚本中的测试结构中使用。 |
示例 16-35. 在脚本中使用 cmp 比较两个文件。
#!/bin/bash # file-comparison.sh ARGS=2 # Two args to script expected. E_BADARGS=85 E_UNREADABLE=86 if [ $# -ne "$ARGS" ] then echo "Usage: `basename $0` file1 file2" exit $E_BADARGS fi if [[ ! -r "$1" || ! -r "$2" ]] then echo "Both files to be compared must exist and be readable." exit $E_UNREADABLE fi cmp $1 $2 &> /dev/null # Redirection to /dev/null buries the output of the "cmp" command. # cmp -s $1 $2 has same result ("-s" silent flag to "cmp") # Thank you Anders Gustavsson for pointing this out. # # Also works with 'diff', i.e., #+ diff $1 $2 &> /dev/null if [ $? -eq 0 ] # Test exit status of "cmp" command. then echo "File \"$1\" is identical to file \"$2\"." else echo "File \"$1\" differs from file \"$2\"." fi exit 0 |
![]() | 在 gzipped 文件上使用 zcmp。 |
通用文件比较实用程序。 文件必须先排序才能有用。
comm-options first-file second-file
comm file-1 file-2输出三列
第 1 列 = 独属于file-1
第 2 列 = 独属于file-2
第 3 列 = 两者共有的行。
这些选项允许禁止输出一列或多列。
-1禁止输出列1
-2禁止输出列2
-3禁止输出列3
-12禁止输出两列1和2,等等。
此命令对于比较“词典”或单词列表很有用 -- 每行一个单词的排序文本文件。
从文件名中删除路径信息,仅打印文件名。 构建basename $0让脚本知道它的名称,也就是它被调用的名称。 如果脚本在缺少参数的情况下被调用,这可以用于“用法”消息
echo "Usage: `basename $0` arg1 arg2 ... argn" |
从文件名中删除 basename,仅打印路径信息。
![]() | basename 和 dirname 可以对任何任意字符串进行操作。 该参数不需要引用现有文件,甚至不需要是一个文件名(请参阅 示例 A-7)。 |
示例 16-36. basename 和 dirname
#!/bin/bash address=/home/bozo/daily-journal.txt echo "Basename of /home/bozo/daily-journal.txt = `basename $address`" echo "Dirname of /home/bozo/daily-journal.txt = `dirname $address`" echo echo "My own home is `basename ~/`." # `basename ~` also works. echo "The home of my home is `dirname ~/`." # `dirname ~` also works. exit 0 |
这些是将文件分割成更小块的实用工具。 它们通常用于分割大文件,以便在软盘上备份它们,或者准备通过电子邮件发送或上传它们。
csplit 命令根据上下文分割文件,分割发生在匹配模式的地方。
示例 16-37. 一个按节复制自身的脚本
#!/bin/bash # splitcopy.sh # A script that splits itself into chunks, #+ then reassembles the chunks into an exact copy #+ of the original script. CHUNKSIZE=4 # Size of first chunk of split files. OUTPREFIX=xx # csplit prefixes, by default, #+ files with "xx" ... csplit "$0" "$CHUNKSIZE" # Some comment lines for padding . . . # Line 15 # Line 16 # Line 17 # Line 18 # Line 19 # Line 20 cat "$OUTPREFIX"* > "$0.copy" # Concatenate the chunks. rm "$OUTPREFIX"* # Get rid of the chunks. exit $? |
这些是用于生成校验和的实用工具。校验和是一个数字 [3] 从文件内容数学计算得出,用于检查其完整性。 脚本可能会引用校验和列表以用于安全目的,例如确保关键系统文件的内容未被更改或损坏。 对于安全应用程序,请使用 md5sum(message digest 5 checksum)命令,或者更好的是,更新的 sha1sum(安全哈希算法)。 [4]
bash$ cksum /boot/vmlinuz 1670054224 804083 /boot/vmlinuz bash$ echo -n "Top Secret" | cksum 3391003827 10 bash$ md5sum /boot/vmlinuz 0f43eccea8f09e0a0b2b5cf1dcf333ba /boot/vmlinuz bash$ echo -n "Top Secret" | md5sum 8babc97a6f62a4649716f4df8d61728f - |
![]() | cksum 命令显示其目标(无论是文件还是stdout (标准输出). md5sum 和 sha1sum 命令在从stdout (标准输出). |
示例 16-38. 检查文件完整性
#!/bin/bash # file-integrity.sh: Checking whether files in a given directory # have been tampered with. E_DIR_NOMATCH=80 E_BAD_DBFILE=81 dbfile=File_record.md5 # Filename for storing records (database file). set_up_database () { echo ""$directory"" > "$dbfile" # Write directory name to first line of file. md5sum "$directory"/* >> "$dbfile" # Append md5 checksums and filenames. } check_database () { local n=0 local filename local checksum # ------------------------------------------- # # This file check should be unnecessary, #+ but better safe than sorry. if [ ! -r "$dbfile" ] then echo "Unable to read checksum database file!" exit $E_BAD_DBFILE fi # ------------------------------------------- # while read record[n] do directory_checked="${record[0]}" if [ "$directory_checked" != "$directory" ] then echo "Directories do not match up!" # Tried to use file for a different directory. exit $E_DIR_NOMATCH fi if [ "$n" -gt 0 ] # Not directory name. then filename[n]=$( echo ${record[$n]} | awk '{ print $2 }' ) # md5sum writes records backwards, #+ checksum first, then filename. checksum[n]=$( md5sum "${filename[n]}" ) if [ "${record[n]}" = "${checksum[n]}" ] then echo "${filename[n]} unchanged." elif [ "`basename ${filename[n]}`" != "$dbfile" ] # Skip over checksum database file, #+ as it will change with each invocation of script. # --- # This unfortunately means that when running #+ this script on $PWD, tampering with the #+ checksum database file will not be detected. # Exercise: Fix this. then echo "${filename[n]} : CHECKSUM ERROR!" # File has been changed since last checked. fi fi let "n+=1" done <"$dbfile" # Read from checksum database file. } # =================================================== # # main () if [ -z "$1" ] then directory="$PWD" # If not specified, else #+ use current working directory. directory="$1" fi clear # Clear screen. echo " Running file integrity check on $directory" echo # ------------------------------------------------------------------ # if [ ! -r "$dbfile" ] # Need to create database file? then echo "Setting up database file, \""$directory"/"$dbfile"\"."; echo set_up_database fi # ------------------------------------------------------------------ # check_database # Do the actual work. echo # You may wish to redirect the stdout of this script to a file, #+ especially if the directory checked has many files in it. exit 0 # For a much more thorough file integrity check, #+ consider the "Tripwire" package, #+ http://sourceforge.net/projects/tripwire/. |
另请参阅 示例 A-19、示例 36-16 和 示例 10-2,了解 md5sum 命令的创造性用途。
![]() | 已经有报告说 128 位的 md5sum 可以被破解,因此更安全的 160 位的 sha1sum 是对校验和工具包的一个受欢迎的新增功能。
|
安全顾问已经证明,即使 sha1sum 也可以被破坏。 幸运的是,更新的 Linux 发行版包括更长的位长 sha224sum、sha256sum、sha384sum 和 sha512sum 命令。
此实用程序将二进制文件(图像、声音文件、压缩文件等)编码为 ASCII 字符,使其适合在电子邮件的正文中或在新闻组帖子中传输。 这在 MIME(多媒体)编码不可用时尤其有用。
这会反转编码,将 uuencoded 文件解码回原始二进制文件。
示例 16-39. Uudecoding 编码文件
#!/bin/bash # Uudecodes all uuencoded files in current working directory. lines=35 # Allow 35 lines for the header (very generous). for File in * # Test all the files in $PWD. do search1=`head -n $lines $File | grep begin | wc -w` search2=`tail -n $lines $File | grep end | wc -w` # Uuencoded files have a "begin" near the beginning, #+ and an "end" near the end. if [ "$search1" -gt 0 ] then if [ "$search2" -gt 0 ] then echo "uudecoding - $File -" uudecode $File fi fi done # Note that running this script upon itself fools it #+ into thinking it is a uuencoded file, #+ because it contains both "begin" and "end". # Exercise: # -------- # Modify this script to check each file for a newsgroup header, #+ and skip to next if not found. exit 0 |
![]() | fold -s 命令可能有用(可能在管道中)来处理从 Usenet 新闻组下载的长的 uudecoded 文本消息。 |
mimencode 和 mmencode 命令处理多媒体编码的电子邮件附件。 虽然 邮件用户代理(例如 pine 或 kmail)通常会自动处理此问题,但这些特定的实用程序允许通过 shell 脚本从命令行或以 批处理模式手动操作此类附件。
曾经,这是标准的 UNIX 文件加密实用程序。 [5] 出于政治动机的政府法规禁止出口加密软件,导致 crypt 从 UNIX 世界的大部分地区消失,并且它仍然在大多数 Linux 发行版中缺失。 幸运的是,程序员已经提出了一些不错的替代方案,其中包括作者自己的 cruft(请参阅 示例 A-4)。
这是 安全套接字层加密的开源实现。
# To encrypt a file: openssl aes-128-ecb -salt -in file.txt -out file.encrypted \ -pass pass:my_password # ^^^^^^^^^^^ User-selected password. # aes-128-ecb is the encryption method chosen. # To decrypt an openssl-encrypted file: openssl aes-128-ecb -d -salt -in file.encrypted -out file.txt \ -pass pass:my_password # ^^^^^^^^^^^ User-selected password. |
将 openssl 通过 管道传输到 tar 或从 tar 传输可以加密整个目录树。
# To encrypt a directory: sourcedir="/home/bozo/testfiles" encrfile="encr-dir.tar.gz" password=my_secret_password tar czvf - "$sourcedir" | openssl des3 -salt -out "$encrfile" -pass pass:"$password" # ^^^^ Uses des3 encryption. # Writes encrypted file "encr-dir.tar.gz" in current working directory. # To decrypt the resulting tarball: openssl des3 -d -salt -in "$encrfile" -pass pass:"$password" | tar -xzv # Decrypts and unpacks into current working directory. |
当然,openssl 还有许多其他用途,例如获取网站的签名 证书。 请参阅 info 页面。
通过在删除文件之前用随机位模式多次覆盖它来安全地擦除文件。 此命令具有与 示例 16-61 相同的效果,但以更彻底和优雅的方式进行。
这是 GNU fileutils 之一。
![]() | 即使在应用 shred 之后,先进的法医技术仍然可能能够恢复文件的内容。 |
创建一个 临时文件 [6],其文件名 "唯一"。 从命令行调用而不带其他参数时,它会在/tmp目录下创建一个零长度的文件。
bash$ mktemp /tmp/tmp.zzsvql3154 |
PREFIX=filename tempfile=`mktemp $PREFIX.XXXXXX` # ^^^^^^ Need at least 6 placeholders #+ in the filename template. # If no filename template supplied, #+ "tmp.XXXXXXXXXX" is the default. echo "tempfile name = $tempfile" # tempfile name = filename.QA2ZpY # or something similar... # Creates a file of that name in the current working directory #+ with 600 file permissions. # A "umask 177" is therefore unnecessary, #+ but it's good programming practice nevertheless. |
用于构建和编译二进制包的实用程序。它也可以用于由源文件中的增量更改触发的任何操作集。
make 命令检查一个Makefile,这是一个文件依赖项和要执行的操作的列表。
make 实用程序实际上是一种强大的脚本语言,在许多方面与 Bash 类似,但具有识别 依赖项 的能力。 有关此有用工具集的深入报道,请参阅 GNU软件文档站点。
专用文件复制命令,类似于 cp,但能够设置复制文件的权限和属性。 此命令似乎是为安装软件包量身定制的,因此它经常出现在Makefile中(在make install部分)。 它同样可以在安装脚本中证明是有用的。
此实用程序由 Benjamin Lin 及其合作者编写,将 DOS 格式的文本文件(行以 CR-LF 结尾)转换为 UNIX 格式(行仅以 LF 结尾),并反之亦然。
ptx [targetfile] 命令输出 targetfile 的置换索引(交叉引用列表)。 如果需要,这可以在管道中进一步过滤和格式化。
分页器,一次显示一个屏幕的文本文件或流给stdout (标准输出)。 这些可用于过滤stdout (标准输出)... 或脚本的输出。
more 的一个有趣的应用程序是 "试驾" 命令序列,以避免潜在的不愉快后果。
ls /home/bozo | awk '{print "rm -rf " $1}' | more # ^^^^ # Testing the effect of the following (disastrous) command-line: # ls /home/bozo | awk '{print "rm -rf " $1}' | sh # Hand off to the shell to execute . . . ^^ |
less 分页器具有一个有趣的属性,可以格式化显示 man 手册 源代码。 请参阅 示例 A-39。
[1] | 此处讨论的 archive(归档) 简单地说,是将一组相关文件存储在单个位置。 |
[2] | Atar czvf ArchiveName.tar.gz * 将会 在当前工作目录下方的子目录中包含点文件。 这是未记录的 GNU tar “特性”。 |
[3] | 校验和可以表示为 十六进制 数,或表示为其他基数。 |
[4] | 为了获得更好 的安全性,请使用 sha256sum、sha512 和 sha1pass 命令。 |
[5] | 这是一种对称块密码,用于在单个系统或局域网上加密文件,而不是 公钥 密码类,其中 pgp 是一个众所周知的例子。 |
[6] | 使用-d选项调用时,创建临时的 directory(目录)。 |