Unix / Linux – 快速指南
Unix / Linux – 快速指南
Unix – 入门
什么是Unix?
Unix 操作系统是一组充当计算机和用户之间链接的程序。
分配系统资源并协调计算机内部所有细节的计算机程序称为操作系统或内核。
用户通过称为shell的程序与内核通信。shell 是一个命令行解释器;它翻译用户输入的命令并将它们转换成内核可以理解的语言。
-
Unix 最初于 1969 年由贝尔实验室的一群 AT&T 员工 Ken Thompson、Dennis Ritchie、Douglas McIlroy 和 Joe Ossanna 开发。
-
市场上有各种 Unix 变体。Solaris Unix、AIX、HP Unix 和 BSD 是一些示例。Linux 也是一种可免费使用的 Unix。
-
几个人可以同时使用一台 Unix 计算机;因此 Unix 被称为多用户系统。
-
一个用户也可以同时运行多个程序;因此 Unix 是一个多任务环境。
Unix 架构
这是 Unix 系统的基本框图 –
统一所有 Unix 版本的主要概念是以下四个基础知识 –
-
内核– 内核是操作系统的核心。它与硬件和大多数任务(如内存管理、任务调度和文件管理)交互。
-
Shell – Shell 是处理您的请求的实用程序。当您在终端上输入命令时,shell 会解释该命令并调用您想要的程序。shell 对所有命令使用标准语法。C Shell、Bourne Shell 和 Korn Shell 是最著名的 shell,它们可用于大多数 Unix 变体。
-
命令和实用程序– 您可以在日常活动中使用各种命令和实用程序。cp、mv、cat和grep等是命令和实用程序的几个例子。有超过 250 个标准命令以及通过 3 个提供的许多其他命令rd派对软件。所有命令都带有各种选项。
-
文件和目录– Unix 的所有数据都组织成文件。然后将所有文件组织到目录中。这些目录被进一步组织成一个树状结构,称为文件系统。
系统启动
如果您有一台安装了 Unix 操作系统的计算机,那么您只需打开系统即可使其生效。
一旦您打开系统,它就会开始启动,最后它会提示您登录系统,这是登录系统并将其用于您的日常活动的活动。
登录 Unix
当您第一次连接到 Unix 系统时,您通常会看到如下提示 –
login:
登录
-
准备好您的用户 ID(用户标识)和密码。如果您还没有这些,请联系您的系统管理员。
-
在登录提示处输入您的用户 ID,然后按ENTER。您的用户 ID区分大小写,因此请确保您完全按照系统管理员的指示输入。
-
在密码提示处输入您的密码,然后按ENTER。您的密码也区分大小写。
-
如果您提供正确的用户名和密码,那么您将被允许进入系统。阅读屏幕上出现的信息和消息,如下所示。
login : amrood amrood's password: Last login: Sun Jun 14 09:32:32 2009 from 62.61.164.73 $
您将看到一个命令提示符(有时称为$提示符),您可以在其中键入所有命令。例如,要检查日历,您需要按如下方式键入cal命令 –
$ cal June 2009 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $
更改密码
所有 Unix 系统都需要密码来帮助确保您的文件和数据属于您自己,并且系统本身不受黑客和破解者的侵害。以下是更改密码的步骤 –
步骤 1 – 首先,在命令提示符下输入密码,如下所示。
第 2 步– 输入您当前使用的旧密码。
步骤 3 – 输入您的新密码。始终保持您的密码足够复杂,以便没有人能猜到它。但请确保,你记住了。
步骤 4 – 您必须再次输入密码来验证密码。
$ passwd Changing password for amrood (current) Unix password:****** New UNIX password:******* Retype new UNIX password:******* passwd: all authentication tokens updated successfully $
注意– 我们在此处添加星号 (*) 只是为了显示您需要在系统中输入当前密码和新密码的位置。当您键入时,它不会向您显示任何字符。
列出目录和文件
Unix 中的所有数据都被组织成文件。所有文件都组织到目录中。这些目录被组织成一个树状结构,称为文件系统。
您可以使用ls命令列出目录中可用的所有文件或目录。以下是使用带有-l选项的ls命令的示例。
$ ls -l total 19621 drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml -rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia -rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar drwxr-xr-x 8 root root 4096 Nov 25 2007 usr -rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php -rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar -rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid -rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf $
这里以d…..开头的条目代表目录。例如,uml、univ 和 urlspedia 是目录,其余条目是文件。
你是谁?
当您登录系统时,您可能愿意知道:我是谁?
找出“你是谁”的最简单方法是输入whoami命令 –
$ whoami amrood $
在你的系统上试试。此命令列出与当前登录关联的帐户名称。你也可以试试我是谁来获取关于你自己的信息。
谁登录了?
有时您可能有兴趣知道谁同时登录到计算机。
根据您希望了解其他用户的程度,可以使用三个命令来获取此信息:users、who和w。
$ users amrood bablu qadir $ who amrood ttyp0 Oct 8 14:10 (limbo) bablu ttyp2 Oct 4 09:08 (calliope) qadir ttyp4 Oct 8 12:09 (dent) $
在您的系统上尝试w命令来检查输出。这列出了与登录系统的用户相关的信息。
注销
完成会话后,您需要退出系统。这是为了确保没有其他人访问您的文件。
登出
-
只需在命令提示符下输入logout命令,系统就会清理所有内容并断开连接。
系统关闭
通过命令行正确关闭 Unix 系统的最一致的方法是使用以下命令之一 –
Sr.No. | 命令和描述 |
---|---|
1 |
halt 立即关闭系统 |
2 |
init 0 使用预定义的脚本关闭系统以在关闭之前同步和清理系统 |
3 |
init 6 通过完全关闭然后重新启动系统来重新启动系统 |
4 |
poweroff 通过关闭电源关闭系统 |
5 |
reboot 重新启动系统 |
6 |
shutdown 关闭系统 |
您通常需要成为超级用户或 root(Unix 系统上最高特权的帐户)才能关闭系统。然而,在一些独立的或个人拥有的 Unix 机器上,管理用户和有时普通用户可以这样做。
Unix – 文件管理
在本章中,我们将详细讨论 Unix 中的文件管理。Unix 中的所有数据都被组织成文件。所有文件都组织到目录中。这些目录被组织成一个树状结构,称为文件系统。
当您使用 Unix 时,以一种或另一种方式,您将大部分时间都花在处理文件上。本教程将帮助您了解如何创建和删除文件、复制和重命名文件、创建指向它们的链接等。
在 Unix 中,有三种基本类型的文件 –
-
普通文件– 普通文件是系统上包含数据、文本或程序指令的文件。在本教程中,您将了解如何处理普通文件。
-
目录– 目录存储特殊和普通文件。对于熟悉 Windows 或 Mac OS 的用户,Unix 目录相当于文件夹。
-
特殊文件– 一些特殊文件提供对硬件的访问,例如硬盘驱动器、CD-ROM 驱动器、调制解调器和以太网适配器。其他特殊文件类似于别名或快捷方式,使您可以使用不同的名称访问单个文件。
列出文件
要列出存储在当前目录中的文件和目录,请使用以下命令 –
$ls
这是上述命令的示例输出 –
$ls bin hosts lib res.03 ch07 hw1 pub test_results ch07.bak hw2 res.01 users docs hw3 res.02 work
命令ls支持-l选项,它可以帮助您获取有关列出文件的更多信息 –
$ls -l total 1962188 drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml -rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia -rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar drwxr-xr-x 8 root root 4096 Nov 25 2007 usr drwxr-xr-x 2 200 300 4096 Nov 25 2007 webthumb-1.01 -rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php -rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar -rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid -rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf drwxr-xr-x 11 amrood amrood 4096 May 29 2007 zlib-1.2.3 $
以下是所有列出的列的信息 –
-
第一列– 表示文件类型和文件的权限。以下是所有类型文件的说明。
-
第二列– 表示文件或目录占用的内存块数。
-
第三列– 代表文件的所有者。这是创建此文件的 Unix 用户。
-
第四列– 代表所有者的组。每个 Unix 用户都有一个关联的组。
-
第五列– 以字节为单位表示文件大小。
-
第六列– 表示最后一次创建或修改此文件的日期和时间。
-
第七列– 表示文件或目录名称。
在ls -l列表示例中,每个文件行都以d、–或l开头。这些字符表示列出的文件的类型。
Sr.No. | 前缀和描述 |
---|---|
1 |
– 常规文件,例如 ASCII 文本文件、二进制可执行文件或硬链接。 |
2 |
b 阻止特殊文件。块输入/输出设备文件,例如物理硬盘驱动器。 |
3 |
c 字符特殊文件。原始输入/输出设备文件,例如物理硬盘驱动器。 |
4 |
d 包含其他文件和目录列表的目录文件。 |
5 |
l 符号链接文件。任何常规文件上的链接。 |
6 |
p 名为管。一种进程间通信机制。 |
7 |
s 用于进程间通信的套接字。 |
元字符
元字符在 Unix 中有特殊的意义。例如,*和? 是元字符。我们使用*匹配 0 个或多个字符,问号 ( ? ) 匹配单个字符。
例如 –
$ls ch*.doc
显示所有文件,其名称以ch开头并以.doc结尾–
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc c
在这里,*用作与任何字符匹配的元字符。如果要显示仅以.doc结尾的所有文件,则可以使用以下命令 –
$ls *.doc
隐藏文件
不可见文件是第一个字符是点或句点字符 (.) 的文件。Unix 程序(包括 shell)使用这些文件中的大部分来存储配置信息。
隐藏文件的一些常见示例包括文件 –
-
.profile – Bourne shell (sh) 初始化脚本
-
.kshrc – Korn shell (ksh) 初始化脚本
-
.cshrc – C shell (csh) 初始化脚本
-
.rhosts – 远程 shell 配置文件
要列出不可见的文件,请为ls指定-a选项–
$ ls -a . .profile docs lib test_results .. .rhosts hosts pub users .emacs bin hw1 res.01 work .exrc ch07 hw2 res.02 .kshrc ch07.bak hw3 res.03 $
-
单点 (.) – 这表示当前目录。
-
双点 (..) – 这表示父目录。
创建文件
您可以使用vi编辑器在任何 Unix 系统上创建普通文件。您只需要提供以下命令 –
$ vi filename
上面的命令将打开一个具有给定文件名的文件。现在,按i键进入编辑模式。进入编辑模式后,您可以开始在文件中写入内容,如下面的程序所示 –
This is unix file....I created it for the first time..... I'm going to save this content in this file.
完成程序后,请按照以下步骤操作 –
-
按esc键退出编辑模式。
-
同时按下两个键Shift &plus ZZ完全退出文件。
您现在将在当前目录中使用filename创建一个文件。
$ vi filename $
编辑文件
您可以使用vi编辑器编辑现有文件。我们将简要讨论如何打开现有文件 –
$ vi filename
打开文件后,您可以通过按i键进入编辑模式,然后您可以继续编辑文件。如果您想在文件中到处移动,那么首先您需要按Esc键退出编辑模式。在此之后,您可以使用以下键在文件内移动 –
-
l键移动到右侧。
-
h键移动到左侧。
-
k键在文件中向上移动。
-
j键在文件中向下移动。
因此,使用上述键,您可以将光标定位在您想要编辑的任何位置。定位后,您可以使用i键进入编辑模式。完成文件中的编辑后,按Esc,最后将两个键Shift 和 ZZ一起从文件中完全出来。
显示文件内容
您可以使用cat命令查看文件的内容。以下是查看上述创建文件内容的简单示例 –
$ cat filename This is unix file....I created it for the first time..... I'm going to save this content in this file. $
您可以使用-b选项和cat命令来显示行号,如下所示 –
$ cat -b filename 1 This is unix file....I created it for the first time..... 2 I'm going to save this content in this file. $
计算文件中的字数
您可以使用wc命令获取文件中包含的行、单词和字符总数的计数。以下是查看有关上面创建的文件的信息的简单示例 –
$ wc filename 2 19 103 filename $
这是所有四列的详细信息 –
-
第一列– 表示文件中的总行数。
-
第二列– 表示文件中的总字数。
-
第三列– 表示文件中的总字节数。这是文件的实际大小。
-
第四列– 表示文件名。
您可以一次提供多个文件并获取有关这些文件的信息。以下是简单的语法 –
$ wc filename1 filename2 filename3
复制文件
要制作文件的副本,请使用cp命令。命令的基本语法是 –
$ cp source_file destination_file
以下是创建现有文件filename副本的示例。
$ cp filename copyfile $
您现在将在当前目录中找到另一个文件copyfile。此文件将与原始文件filename完全相同。
重命名文件
要更改文件名,请使用mv命令。以下是基本语法 –
$ mv old_file new_file
以下程序将现有文件filename重命名为newfile。
$ mv filename newfile $
该MV命令将完全移动现有的文件到新的文件。在这种情况下,您只会在当前目录中找到newfile。
删除文件
要删除现有文件,请使用rm命令。以下是基本语法 –
$ rm filename
注意– 文件可能包含有用的信息。始终建议在使用此删除命令时要小心。最好将-i选项与rm命令一起使用。
以下是显示如何完全删除现有文件filename的示例。
$ rm filename $
您可以使用下面给出的命令一次删除多个文件 –
$ rm filename1 filename2 filename3 $
标准 Unix 流
在正常情况下,每个 Unix 程序在启动时都会为其打开三个流(文件) –
-
stdin – 这被称为标准输入,关联的文件描述符为 0。这也表示为 STDIN。Unix 程序将从 STDIN 读取默认输入。
-
stdout – 这被称为标准输出,关联的文件描述符为 1。这也表示为 STDOUT。Unix 程序将在 STDOUT 写入默认输出
-
stderr – 这被称为标准错误,相关的文件描述符为 2。这也表示为 STDERR。Unix 程序会将所有错误消息写入 STDERR。
Unix – 目录管理
在本章中,我们将详细讨论 Unix 中的目录管理。
目录是一个文件,它的唯一工作是存储文件名和相关信息。所有文件,无论是普通文件、特殊文件还是目录文件,都包含在目录中。
Unix 使用层次结构来组织文件和目录。这种结构通常称为目录树。树有一个根节点,斜线字符 ( / ),所有其他目录都包含在它下面。
主目录
您首次登录时所在的目录称为主目录。
您将在主目录和为组织文件而创建的子目录中完成大部分工作。
您可以随时使用以下命令进入您的主目录 –
$cd ~ $
这里~表示主目录。假设您必须进入任何其他用户的主目录,请使用以下命令 –
$cd ~username $
要进入最后一个目录,您可以使用以下命令 –
$cd - $
绝对/相对路径名
目录按层次结构排列,根 (/) 位于顶部。层次结构中任何文件的位置由其路径名描述。
路径名的元素由 / 分隔。路径名是绝对的,如果它是相对于 root 来描述的,因此绝对路径名总是以 / 开头。
以下是绝对文件名的一些示例。
/etc/passwd /users/sjones/chem/notes /dev/rdsk/Os3
路径名也可以相对于您当前的工作目录。相对路径名从不以 / 开头。相对于用户 amrood 的主目录,一些路径名可能如下所示 –
chem/notes personal/res
要随时确定您在文件系统层次结构中的位置,请输入命令pwd以打印当前工作目录 –
$pwd /user0/home/amrood $
列出目录
要列出目录中的文件,您可以使用以下语法 –
$ls dirname
以下是列出/usr/local目录中包含的所有文件的示例–
$ls /usr/local X11 bin gimp jikes sbin ace doc include lib share atalk etc info man ami
创建目录
我们现在将了解如何创建目录。目录由以下命令创建 –
$mkdir dirname
这里,目录是您要创建的目录的绝对或相对路径名。例如,命令 –
$mkdir mydir $
在当前目录中创建目录mydir。这是另一个例子 –
$mkdir /tmp/test-dir $
此命令在/tmp目录中创建目录test-dir。如果mkdir命令成功创建了请求的目录,则不会产生任何输出。
如果您在命令行上提供多个目录,mkdir会创建每个目录。例如, –
$mkdir docs pub $
在当前目录下创建目录 docs 和 pub。
创建父目录
我们现在将了解如何创建父目录。有时,当您要创建目录时,其父目录可能不存在。在这种情况下,mkdir 会发出如下错误消息 –
$mkdir /tmp/amrood/test mkdir: Failed to make directory "/tmp/amrood/test"; No such file or directory $
在这种情况下,您可以为mkdir命令指定-p选项。它为您创建所有必要的目录。例如 –
$mkdir -p /tmp/amrood/test $
上面的命令创建了所有必需的父目录。
删除目录
可以使用rmdir命令删除目录,如下所示 –
$rmdir dirname $
注意– 要删除目录,请确保它为空,这意味着该目录中不应有任何文件或子目录。
您可以一次删除多个目录,如下所示 –
$rmdir dirname1 dirname2 dirname3 $
上述命令删除目录 dirname1、dirname2 和 dirname3(如果它们为空)。如果rmdir命令成功,则不会产生任何输出。
更改目录
您可以使用cd命令执行更多操作,而不仅仅是更改到主目录。通过指定有效的绝对或相对路径,您可以使用它来更改任何目录。语法如下 –
$cd dirname $
此处,dirname是您要更改到的目录的名称。例如,命令 –
$cd /usr/local/bin $
更改到目录/usr/local/bin。从此目录中,您可以使用以下相对路径cd到目录/usr/home/amrood –
$cd ../../home/amrood $
重命名目录
的MV(移动)指令,也可用于重命名的目录。语法如下 –
$mv olddir newdir $
您可以将目录mydir重命名为yourdir,如下所示 –
$mv mydir yourdir $
目录。(点)和..(点点)
该文件名。(点)代表当前工作目录;和文件名..(点点)表示当前工作目录的上级目录中一个水平上,通常被称为父目录。
如果我们输入命令以显示当前工作目录/文件的列表并使用-a 选项列出所有文件并使用-l 选项提供长列表,我们将收到以下结果。
$ls -la drwxrwxr-x 4 teacher class 2048 Jul 16 17.56 . drwxr-xr-x 60 root 1536 Jul 13 14:18 .. ---------- 1 teacher class 4210 May 1 08:27 .profile -rwxr-xr-x 1 teacher class 1948 May 12 13:42 memo $
Unix – 文件权限/访问模式
在本章中,我们将详细讨论 Unix 中的文件权限和访问模式。文件所有权是 Unix 的一个重要组成部分,它提供了一种安全的文件存储方法。Unix 中的每个文件都具有以下属性 –
-
所有者权限– 所有者的权限决定了文件所有者可以对文件执行的操作。
-
组权限– 组的权限决定了用户(文件所属组的成员)可以对文件执行的操作。
-
其他(世界)权限– 其他人的权限指示所有其他用户可以对文件执行的操作。
权限指标
使用ls -l命令时,它会显示与文件权限相关的各种信息,如下所示 –
$ls -l /home/amrood -rwxr-xr-- 1 amrood users 1024 Nov 2 00:10 myfile drwxr-xr--- 1 amrood users 1024 Nov 2 00:10 mydir
这里,第一列代表不同的访问模式,即与文件或目录相关联的权限。
权限分为三组,组中的每个位置表示一个特定的权限,按此顺序:读取(r),写入(w),执行(x) –
-
前三个字符 (2-4) 表示文件所有者的权限。例如-rwxr-xr–表示拥有者拥有读(r)、写(w)和执行(x)权限。
-
第二组三个字符 (5-7) 包含文件所属组的权限。例如,-rwxr-xr–表示该组有读(r)和执行(x)权限,但没有写权限。
-
最后一组三个字符 (8-10) 代表其他所有人的权限。例如,-rwxr-xr–表示有只读(r)权限。
文件访问模式
文件的权限是 Unix 系统安全的第一道防线。Unix 权限的基本构建块是读取、写入和执行权限,如下所述 –
读
授予读取,即查看文件内容的能力。
写
授予修改或删除文件内容的能力。
执行
具有执行权限的用户可以将文件作为程序运行。
目录访问模式
目录访问模式以与任何其他文件相同的方式列出和组织。有一些差异需要提及 –
读
访问目录意味着用户可以阅读内容。用户可以查看目录中的文件名。
写
访问意味着用户可以在目录中添加或删除文件。
执行
执行一个目录并没有真正的意义,所以把它看作是一个遍历权限。
用户必须具有对bin目录的执行访问权才能执行ls或cd命令。
更改权限
要更改文件或目录权限,请使用chmod(更改模式)命令。chmod 有两种使用方式——符号模式和绝对模式。
在符号模式下使用 chmod
初学者修改文件或目录权限的最简单方法是使用符号模式。通过符号权限,您可以使用下表中的运算符添加、删除或指定所需的权限集。
Sr.No. | Chmod 运算符和说明 |
---|---|
1 |
+ 将指定的权限添加到文件或目录。 |
2 |
– 从文件或目录中删除指定的权限。 |
3 |
= 设置指定的权限。 |
这是一个使用testfile的示例。在测试文件上运行ls -1显示文件的权限如下 –
$ls -l testfile -rwxrwxr-- 1 amrood users 1024 Nov 2 00:10 testfile
然后上表中的每个示例chmod命令都在测试文件上运行,然后是ls –l,因此您可以看到权限更改 –
$chmod o+wx testfile $ls -l testfile -rwxrwxrwx 1 amrood users 1024 Nov 2 00:10 testfile $chmod u-x testfile $ls -l testfile -rw-rwxrwx 1 amrood users 1024 Nov 2 00:10 testfile $chmod g = rx testfile $ls -l testfile -rw-r-xrwx 1 amrood users 1024 Nov 2 00:10 testfile
以下是如何在一行中组合这些命令 –
$chmod o+wx,u-x,g = rx testfile $ls -l testfile -rw-r-xrwx 1 amrood users 1024 Nov 2 00:10 testfile
以绝对权限使用 chmod
使用 chmod 命令修改权限的第二种方法是使用一个数字来指定文件的每组权限。
每个权限都分配了一个值,如下表所示,每组权限的总数为该组提供了一个编号。
Number | 八进制权限表示 | 参考 |
---|---|---|
0 | 没有权限 | — |
1 | 执行权限 | – X |
2 | 写权限 | -w- |
3 | 执行和写权限:1(执行)+2(写)=3 | -wx |
4 | 读取权限 | r– |
5 | 读和执行权限:4(读)+1(执行)=5 | 接收 |
6 | 读写权限:4(读)+2(写)=6 | rw- |
7 | 所有权限:4(读)+2(写)+1(执行)=7 | rwx |
这是使用 testfile 的示例。在测试文件上运行ls -1显示文件的权限如下 –
$ls -l testfile -rwxrwxr-- 1 amrood users 1024 Nov 2 00:10 testfile
然后上表中的每个示例chmod命令都在测试文件上运行,然后是ls –l,因此您可以看到权限更改 –
$ chmod 755 testfile $ls -l testfile -rwxr-xr-x 1 amrood users 1024 Nov 2 00:10 testfile $chmod 743 testfile $ls -l testfile -rwxr---wx 1 amrood users 1024 Nov 2 00:10 testfile $chmod 043 testfile $ls -l testfile ----r---wx 1 amrood users 1024 Nov 2 00:10 testfile
更改所有者和组
在 Unix 上创建帐户时,它会为每个用户分配一个所有者 ID和一个组 ID。上面提到的所有权限也是根据所有者和组分配的。
有两个命令可用于更改所有者和文件组 –
-
chown – chown命令代表“更改所有者”,用于更改文件的所有者。
-
chgrp – chgrp命令代表“更改组”,用于更改文件的组。
改变所有权
该CHOWN命令更改文件的所有权。基本语法如下 –
$ chown user filelist
用户的值可以是系统上的用户名,也可以是系统上用户的用户 ID (uid)。
以下示例将帮助您理解这个概念 –
$ chown amrood testfile $
将给定文件的所有者更改为用户amrood。
注意– 超级用户 root 可以不受限制地更改任何文件的所有权,但普通用户只能更改他们拥有的文件的所有权。
更改组所有权
该chgrp命令命令更改文件的组所有权。基本语法如下 –
$ chgrp group filelist
group 的值可以是系统上组的名称或系统上组的组 ID (GID)。
以下示例可帮助您理解这个概念 –
$ chgrp special testfile $
将给定文件的组更改为特殊组。
SUID 和 SGID 文件权限
通常当一个命令被执行时,它必须以特殊权限执行才能完成它的任务。
例如,当您使用passwd命令更改密码时,您的新密码将存储在文件/etc/shadow 中。
作为普通用户,出于安全原因,您没有对该文件的读或写访问权限,但是当您更改密码时,您需要对该文件具有写权限。这意味着passwd程序必须为您提供额外的权限,以便您可以写入文件/etc/shadow。
通过称为设置用户 ID (SUID)和设置组 ID (SGID)位的机制向程序授予其他权限。
当您执行启用了 SUID 位的程序时,您将继承该程序所有者的权限。未设置 SUID 位的程序在启动该程序的用户的权限下运行。
SGID 也是这种情况。通常,程序以您的组权限执行,但您的组将仅针对该程序更改为该程序的组所有者。
如果权限可用,则SUID 和 SGID 位将显示为字母“s”。SUID “s”位将位于所有者执行权限通常所在的权限位中。
例如,命令 –
$ ls -l /usr/bin/passwd -r-sr-xr-x 1 root bin 19031 Feb 7 13:47 /usr/bin/passwd* $
显示 SUID 位已设置并且命令归根所有。执行位置中的大写字母S而不是小写s表示未设置执行位。
如果在目录上启用了粘滞位,则仅当您是以下用户之一时才能删除文件 –
- 粘性目录的所有者
- 被删除文件的所有者
- 超级用户,root
要为任何目录设置 SUID 和 SGID 位,请尝试以下命令 –
$ chmod ug+s dirname $ ls -l drwsr-sr-x 2 root root 4096 Jun 19 06:45 dirname $
Unix – 环境
在本章中,我们将详细讨论 Unix 环境。一个重要的 Unix 概念是environment,它由环境变量定义。有些是由系统设置的,有些是由您设置的,还有一些是由 shell 或加载其他程序的任何程序设置的。
变量是我们为其赋值的字符串。分配的值可以是数字、文本、文件名、设备或任何其他类型的数据。
例如,首先我们设置一个变量 TEST,然后我们使用echo命令访问它的值–
$TEST="Unix Programming" $echo $TEST
它产生以下结果。
Unix Programming
请注意,环境变量的设置不使用$符号,但在访问它们时我们使用 $ 符号作为前缀。这些变量保留它们的值,直到我们退出 shell。
当您登录系统时,shell 会经历一个称为初始化的阶段来设置环境。这通常是一个两步过程,涉及 shell 读取以下文件 –
- /etc/配置文件
- 轮廓
过程如下 –
-
shell 检查文件/etc/profile是否存在。
-
如果存在,shell 会读取它。否则,将跳过此文件。不显示错误消息。
-
shell 检查文件.profile是否存在于您的主目录中。您的主目录是您登录后开始的目录。
-
如果存在,shell 会读取它;否则,shell 会跳过它。不显示错误消息。
一旦读取了这两个文件,shell 就会显示一个提示 –
$
这是您可以输入命令以执行它们的提示。
注意– 此处详述的 shell 初始化过程适用于所有Bourne类型的 shell,但bash和ksh使用了一些其他文件。
.profile 文件
文件/etc/profile由您的 Unix 机器的系统管理员维护,包含系统上所有用户所需的 shell 初始化信息。
文件.profile由您控制。您可以向该文件添加任意数量的 shell 自定义信息。您需要配置的最少信息集包括 –
- 您使用的终端类型。
- 用于定位命令的目录列表。
- 影响终端外观的变量列表。
您可以检查您的主目录中可用的.profile。使用 vi 编辑器打开它并检查为您的环境设置的所有变量。
设置终端类型
通常,您使用的终端类型由login或getty程序自动配置。有时,自动配置过程会错误地猜测您的终端。
如果您的终端设置不正确,命令的输出可能看起来很奇怪,或者您可能无法与 shell 正确交互。
为了确保不是这种情况,大多数用户通过以下方式将他们的终端设置为最小公分母 –
$TERM=vt100 $
设置路径
当您在命令提示符下键入任何命令时,shell 必须先定位该命令,然后才能执行该命令。
PATH 变量指定 shell 应在其中查找命令的位置。通常 Path 变量设置如下 –
$PATH=/bin:/usr/bin $
此处,由冒号(:)分隔的每个单独条目都是目录。如果您请求 shell 执行命令并且在 PATH 变量中给出的任何目录中都找不到它,则会出现类似于以下内容的消息 –
$hello hello: not found $
下一节将讨论 PS1 和 PS2 等变量。
PS1 和 PS2 变量
shell 显示为命令提示符的字符存储在变量 PS1 中。您可以将此变量更改为任何您想要的值。一旦你改变它,它就会被 shell 从那时起使用。
例如,如果您发出命令 –
$PS1='=>' => => =>
您的提示将变为 =>。要设置PS1的值以显示工作目录,请发出命令 –
=>PS1="[\u@\h \w]$" [root@ip-72-167-112-17 /var/www/tutorialspoint/unix]$ [root@ip-72-167-112-17 /var/www/tutorialspoint/unix]$
此命令的结果是提示符显示用户的用户名、机器的名称(主机名)和工作目录。
有很多转义序列可以用作 PS1 的值参数;尽量把自己限制在最关键的地方,这样提示就不会用信息淹没你。
Sr.No. | 转义序列和描述 |
---|---|
1 |
\t 当前时间,表示为 HH:MM:SS |
2 |
\d 当前日期,表示为工作日月份日期 |
3 |
\n 新队 |
4 |
\s 当前外壳环境 |
5 |
\W 工作目录 |
6 |
\w 工作目录的完整路径 |
7 |
\u 当前用户的用户名 |
8 |
\h 当前机器的主机名 |
9 |
\# 当前命令的命令号。输入新命令时增加 |
10 |
\$ 如果有效 UID 为 0(即如果您以 root 身份登录),则以 # 字符结束提示;否则,使用 $ 符号 |
您可以在每次登录时自己进行更改,也可以通过将其添加到.profile文件来在 PS1 中自动进行更改。
当您发出不完整的命令时,shell 将显示辅助提示并等待您完成命令并再次按 Enter。
默认的辅助提示是>(大于号),但可以通过重新定义PS2 shell 变量来更改–
以下是使用默认辅助提示的示例 –
$ echo "this is a > test" this is a test $
下面给出的示例使用自定义提示重新定义 PS2 –
$ PS2="secondary prompt->" $ echo "this is a secondary prompt->test" this is a test $
环境变量
以下是重要环境变量的部分列表。这些变量的设置和访问如下所述 –
Sr.No. | 变量和描述 |
---|---|
1 |
DISPLAY 包含X11程序默认使用的显示器标识符。 |
2 |
HOME 表示当前用户的家目录:cd内置命令的默认参数。 |
3 |
IFS 表示解析器在扩展后用于分词的内部字段分隔符。 |
4 |
LANG LANG 扩展到默认系统区域设置;LC_ALL 可用于覆盖它。例如,如果其值为pt_BR,则语言设置为(巴西)葡萄牙语,区域设置为巴西。 |
5 |
LD_LIBRARY_PATH 带有动态链接器的 Unix 系统包含一个以冒号分隔的目录列表,动态链接器在 exec 之后构建进程映像时应搜索共享对象,然后再搜索任何其他目录。 |
6 |
PATH 指示命令的搜索路径。它是一个以冒号分隔的目录列表,shell 在其中查找命令。 |
7 |
PWD 指示 cd 命令设置的当前工作目录。 |
8 |
RANDOM 每次引用时生成 0 到 32,767 之间的随机整数。 |
9 |
SHLVL 每次启动 bash 实例时递增 1。此变量可用于确定内置 exit 命令是否结束当前会话。 |
10 |
TERM 指显示类型。 |
11 |
TZ 指时区。它可以采用 GMT、AST 等值。 |
12 |
UID 扩展为当前用户的数字用户 ID,在 shell 启动时初始化。 |
以下是显示几个环境变量的示例示例 –
$ echo $HOME /root ]$ echo $DISPLAY $ echo $TERM xterm $ echo $PATH /usr/local/bin:/bin:/usr/bin:/home/amrood/bin:/usr/local/bin $
Unix 基本实用程序 – 打印、电子邮件
在本章中,我们将详细讨论打印和电子邮件作为 Unix 的基本实用程序。到目前为止,我们已经尝试了解 Unix 操作系统及其基本命令的性质。在本章中,我们将学习一些可以在我们日常生活中使用的重要 Unix 实用程序。
打印文件
在 Unix 系统上打印文件之前,您可能需要重新格式化它以调整边距、突出显示某些单词等。大多数文件也可以在不重新格式化的情况下打印,但原始打印输出可能不那么吸引人。
许多版本的 Unix 包括两个强大的文本格式化程序,nroff和troff。
pr 命令
的PR命令执行终端屏幕上或用于打印机的文件少量格式。例如,如果文件中有很长的名称列表,您可以在屏幕上将其格式化为两列或更多列。
以下是pr命令的语法–
pr option(s) filename(s)
所述PR改变只在屏幕上或在所述印刷拷贝该文件的格式; 它不会修改原始文件。下表列出了一些公关选项 –
Sr.No. | 选项和说明 |
---|---|
1 |
-k 产生k列输出 |
2 |
-d 输出双倍空格(并非在所有pr版本上) |
3 |
-h “header” 将下一项作为报告标题 |
4 |
-t 消除了页眉和顶部/底部边距的打印 |
5 |
-l PAGE_LENGTH 将页面长度设置为 PAGE_LENGTH (66) 行。默认文本行数为 56 |
6 |
-o MARGIN 用 MARGIN(零)空格偏移每一行 |
7 |
-w PAGE_WIDTH 将页面宽度设置为 PAGE_WIDTH (72) 个字符,仅用于多文本列输出 |
在使用pr之前,这里是一个名为 food 的示例文件的内容。
$cat food Sweet Tooth Bangkok Wok Mandalay Afghani Cuisine Isle of Java Big Apple Deli Sushi and Sashimi Tio Pepe's Peppers ........ $
让我们使用pr命令制作带有标题餐厅的两列报告–
$pr -2 -h "Restaurants" food Nov 7 9:58 1997 Restaurants Page 1 Sweet Tooth Isle of Java Bangkok Wok Big Apple Deli Mandalay Sushi and Sashimi Afghani Cuisine Tio Pepe's Peppers ........ $
lp 和 lpr 命令
命令lp或lpr将文件打印到纸上而不是屏幕显示。准备好使用pr命令格式化后,您可以使用这些命令中的任何一个在连接到计算机的打印机上打印文件。
您的系统管理员可能已经在您的站点设置了默认打印机。要在默认打印机上打印名为food的文件,请使用lp或lpr命令,如下例所示 –
$lp food request id is laserp-525 (1 file) $
该LP命令显示的ID,你可以用它来取消打印作业或检查其状态。
-
如果您正在使用lp命令,您可以使用 -n Num选项打印 Num 份数。与命令lpr 一起,您可以使用 – Num。
-
如果有多个打印机连接到共享网络,那么您可以使用 -d打印机选项和 lp 命令来选择打印机,出于同样的目的,您可以使用 -P打印机选项和 lpr 命令。这里的打印机是打印机名称。
lpstat 和 lpq 命令
该的lpstat命令显示什么在打印机队列:请求ID,所有者,文件大小,当工作岗位打印发送,请求的状态。
如果您想查看除您自己的以外的所有输出请求,请使用lpstat -o。请求按打印顺序显示 –
$lpstat -o laserp-573 john 128865 Nov 7 11:27 on laserp laserp-574 grace 82744 Nov 7 11:28 laserp-575 john 23347 Nov 7 11:35 $
该LPQ给出比略有不同信息的lpstat -o –
$lpq laserp is ready and printing Rank Owner Job Files Total Size active john 573 report.ps 128865 bytes 1st grace 574 ch03.ps ch04.ps 82744 bytes 2nd john 575 standard input 23347 bytes $
第一行显示打印机状态。如果打印机被禁用或纸张用完,您可能会在第一行看到不同的消息。
取消和 lprm 命令
所述取消命令终止从打印请求lp命令。该LPRM命令终止所有LPR请求。您可以指定请求的 ID(由 lp 或 lpq 显示)或打印机的名称。
$cancel laserp-575 request "laserp-575" cancelled $
要取消当前正在打印的任何请求,无论其 ID 如何,只需输入取消和打印机名称 –
$cancel laserp request "laserp-573" cancelled $
如果它属于您,lprm命令将取消活动作业。否则,您可以将工作编号作为参数,或使用破折号 (-)删除所有工作 –
$lprm 575 dfA575diamond dequeued cfA575diamond dequeued $
该LPRM命令告诉您从打印机队列中删除的实际文件名。
发送电子邮件
您可以使用 Unix mail 命令来发送和接收邮件。这是发送电子邮件的语法 –
$mail [-s subject] [-c cc-addr] [-b bcc-addr] to-addr
以下是与邮件命令相关的重要选项 -s
Sr.No. | 选项和说明 |
---|---|
1 |
-s 在命令行上指定主题。 |
2 |
-c 将副本发送到用户列表。List 应该是一个逗号分隔的名称列表。 |
3 |
-b 发送密件副本到列表。List 应该是一个逗号分隔的名称列表。 |
以下是向 [email protected] 发送测试消息的示例。
$mail -s "Test Message" [email protected]
然后您需要输入您的消息,然后在一行的开头输入“control-D”。要停止,只需按如下方式输入点(.) –
Hi, This is a test . Cc:
您可以使用重定向 < 操作符发送一个完整的文件,如下所示 –
$mail -s "Report 05/06/07" [email protected] < demo.txt
要在您的 Unix 系统上检查收到的电子邮件,您只需按如下方式输入电子邮件 –
$mail no email
Unix – 管道和过滤器
在本章中,我们将详细讨论 Unix 中的管道和过滤器。您可以将两个命令连接在一起,以便一个程序的输出成为下一个程序的输入。以这种方式连接的两个或多个命令形成一个管道。
要制作管道,请在命令行上的两个命令之间放置一个竖线 ( &verbar )。
当一个程序从另一个程序获取输入时,它对该输入执行一些操作,并将结果写入标准输出。它被称为过滤器。
grep 命令
grep 命令在一个或多个文件中搜索具有特定模式的行。语法是 –
$grep pattern file(s)
名称“grep”来自 ed(Unix 行编辑器)命令g/re/p,意思是“全局搜索正则表达式并打印包含它的所有行”。
正则表达式是一些纯文本(例如一个词)和/或用于模式匹配的特殊字符。
grep 最简单的用法是查找由单个单词组成的模式。它可以在管道中使用,以便仅将包含给定字符串的输入文件的那些行发送到标准输出。如果你不给 grep 一个要读取的文件名,它会读取它的标准输入;这就是所有过滤程序的工作方式 –
$ls -l | grep "Aug" -rw-rw-rw- 1 john doc 11008 Aug 6 14:10 ch02 -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros $
有多种选项可以与grep命令一起使用–
Sr.No. | 选项和说明 |
---|---|
1 |
-v 打印所有与模式不匹配的行。 |
2 |
-n 打印匹配的行及其行号。 |
3 |
-l 仅打印具有匹配行的文件名(字母“l”) |
4 |
-c 仅打印匹配行的计数。 |
5 |
-i 匹配大写或小写。 |
现在让我们使用一个正则表达式,它告诉 grep 查找带有“carol”的行,后跟零或其他在正则表达式中缩写为“.*”的字符,然后是“Aug”。-
在这里,我们使用-i选项进行不区分大小写的搜索 –
$ls -l | grep -i "carol.*aug" -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros $
排序命令
该类型的文本命令行排列按字母或数字。以下示例对食物文件中的行进行排序 –
$sort food Afghani Cuisine Bangkok Wok Big Apple Deli Isle of Java Mandalay Sushi and Sashimi Sweet Tooth Tio Pepe's Peppers $
该类型的默认文字的字母顺序排列的命令行。有许多选项可以控制排序 –
Sr.No. | 描述 |
---|---|
1 |
-n 按数字排序(例如:10 将在 2 之后排序),忽略空格和制表符。 |
2 |
-r 颠倒排序顺序。 |
3 |
-f 将大写和小写一起排序。 |
4 |
&plusx 排序时忽略前x 个字段。 |
可以将两个以上的命令链接到一个管道中。以前面使用grep 的管道示例为例,我们可以进一步按大小顺序对 8 月份修改的文件进行排序。
以下管道由命令ls、grep和sort 组成–
$ls -l | grep "Aug" | sort +4n -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-rw- 1 john doc 11008 Aug 6 14:10 ch02 $
该管道将您在 8 月份修改的目录中的所有文件按大小顺序排序,并将它们打印在终端屏幕上。排序选项 &plus4n 跳过四个字段(字段由空格分隔)然后按数字顺序对行进行排序。
pg 和更多命令
您通常可以在屏幕上压缩较长的输出,但是如果您通过 more 运行文本或使用pg命令作为过滤器;一旦屏幕充满文本,显示就会停止。
假设您有一个很长的目录列表。为了更容易阅读排序后的列表,通过如下管道输出更多–
$ls -l | grep "Aug" | sort +4n | more -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-r-- 1 john doc 14827 Aug 9 12:40 ch03 . . . -rw-rw-rw- 1 john doc 16867 Aug 6 15:56 ch05 --More--(74%)
一旦屏幕充满了由按文件大小顺序排列的行组成的文本,屏幕就会填满。屏幕底部是更多提示,您可以在其中键入命令以在已排序的文本中移动。
完成此屏幕后,您可以使用 more 程序的讨论中列出的任何命令。
Unix – 进程管理
在本章中,我们将详细讨论 Unix 中的进程管理。当您在 Unix 系统上执行程序时,系统会为该程序创建一个特殊的环境。该环境包含系统运行程序所需的一切,就好像系统上没有其他程序在运行一样。
每当您在 Unix 中发出命令时,它都会创建或启动一个新进程。当您尝试使用ls命令列出目录内容时,您启动了一个进程。一个进程,简单来说,就是一个正在运行的程序的实例。
操作系统通过称为pid或进程 ID的五位 ID 号来跟踪进程。系统中的每个进程都有一个唯一的pid。
pid 最终会重复,因为所有可能的数字都用完了,下一个 pid 滚动或重新开始。在任何时候,系统中都不存在具有相同 pid 的两个进程,因为 Unix 使用 pid 来跟踪每个进程。
启动进程
当您启动一个进程(运行命令)时,您可以通过两种方式运行它 –
- 前台进程
- 后台进程
前台进程
默认情况下,您启动的每个进程都在前台运行。它从键盘获取输入并将其输出发送到屏幕。
您可以使用ls命令看到这种情况。如果要列出当前目录中的所有文件,可以使用以下命令 –
$ls ch*.doc
这将显示所有文件,其名称以ch开头并以.doc结尾–
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc
该进程在前台运行,输出被定向到我的屏幕,如果ls命令需要任何输入(它不需要),它会等待来自键盘的输入。
当程序在前台运行并且很耗时时,不能运行其他命令(启动任何其他进程),因为在程序完成处理并出现之前,提示将不可用。
后台进程
后台进程无需连接到键盘即可运行。如果后台进程需要任何键盘输入,它就会等待。
在后台运行一个进程的好处是可以运行其他命令;你不必等到它完成再开始另一个!
启动后台进程的最简单方法是在命令末尾添加一个与号( & )。
$ls ch*.doc &
这将显示所有名称以ch开头并以.doc结尾的文件–
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc
在这里,如果ls命令需要任何输入(它不需要),它会进入停止状态,直到我们将它移到前台并从键盘给它数据。
第一行包含有关后台进程的信息 – 作业号和进程 ID。您需要知道作业编号才能在后台和前台之间对其进行操作。
按 Enter 键,您将看到以下内容 –
[1] + Done ls ch*.doc & $
第一行告诉您ls命令后台进程成功完成。第二个是另一个命令的提示。
列出正在运行的进程
通过运行ps(进程状态)命令很容易查看您自己的进程,如下所示 –
$ps PID TTY TIME CMD 18358 ttyp3 00:00:00 sh 18361 ttyp3 00:01:31 abiword 18789 ttyp3 00:00:00 ps
ps 最常用的标志之一是-f(f 代表完整)选项,它提供更多信息,如下例所示 –
$ps -f UID PID PPID C STIME TTY TIME CMD amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f
以下是ps -f命令显示的所有字段的说明–
Sr.No. | 列和描述 |
---|---|
1 |
UID 此进程所属的用户 ID(运行它的人) |
2 |
PID 进程标识 |
3 |
PPID 父进程 ID(启动它的进程的 ID) |
4 |
C 进程的 CPU 使用率 |
5 |
STIME 进程开始时间 |
6 |
TTY 与进程关联的终端类型 |
7 |
TIME 进程占用的 CPU 时间 |
8 |
CMD 启动此进程的命令 |
还有其他选项可以与ps命令一起使用–
Sr.No. | 选项和说明 |
---|---|
1 |
-a 显示所有用户的信息 |
2 |
-x 显示有关没有终端的进程的信息 |
3 |
-u 显示附加信息,如 -f 选项 |
4 |
-e 显示扩展信息 |
停止进程
可以通过几种不同的方式结束进程。通常,从基于控制台的命令中,发送 CTRL + C 键击(默认中断字符)将退出命令。这在进程以前台模式运行时有效。
如果进程在后台运行,您应该使用ps命令获取其作业 ID 。之后,您可以使用kill命令来终止进程,如下所示 –
$ps -f UID PID PPID C STIME TTY TIME CMD amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f $kill 6738 Terminated
在这里,kill命令终止first_one进程。如果进程忽略常规 kill 命令,您可以使用kill -9后跟进程 ID,如下所示 –
$kill -9 6738 Terminated
父进程和子进程
每个 unix 进程都有两个分配给它的 ID 号:进程 ID (pid) 和父进程 ID (ppid)。系统中的每个用户进程都有一个父进程。
您运行的大多数命令都将 shell 作为其父级。检查ps -f示例,其中此命令列出了进程 ID 和父进程 ID。
僵尸进程和孤儿进程
通常,当子进程被杀死时,父进程会通过SIGCHLD信号更新。然后父级可以执行其他任务或根据需要重新启动新子级。然而,有时父进程在其子进程被杀死之前被杀死。在这种情况下,“所有进程的父进程”,即init进程,将成为新的 PPID(父进程 ID)。在某些情况下,这些进程称为孤立进程。
当一个进程被杀死时,ps列表可能仍会显示该进程具有Z状态。这是一个僵尸或已失效的进程。该进程已死且未被使用。这些进程不同于孤儿进程。他们已经完成了执行,但仍然在进程表中找到了一个条目。
守护进程
守护进程是与系统相关的后台进程,通常在 root 和来自其他进程的服务请求的权限下运行。
守护进程没有控制终端。它无法打开/dev/tty。如果您执行“ps -ef”并查看tty字段,所有守护进程都会有一个? 对于tty。
确切地说,守护进程是一个在后台运行的进程,通常等待它能够处理的事情发生。例如,等待打印命令的打印机守护进程。
如果您有一个需要长时间处理的程序,那么值得将其设为守护进程并在后台运行。
顶部命令
的顶部的命令是用于快速示出由各种标准排序处理的非常有用的工具。
它是一种交互式诊断工具,经常更新并显示有关物理和虚拟内存、CPU 使用率、平均负载和繁忙进程的信息。
以下是运行 top 命令并查看不同进程的 CPU 利用率统计信息的简单语法 –
$top
作业 ID 与进程 ID
后台和挂起的进程通常通过作业号(作业 ID)进行操作。该编号与进程 ID 不同,使用它是因为它较短。
此外,一个作业可以由多个连续或同时、并行运行的进程组成。使用作业 ID 比跟踪单个进程更容易。
Unix – 网络通信实用程序
在本章中,我们将详细讨论 Unix 中的网络通信实用程序。当您在分布式环境中工作时,您需要与远程用户进行通信,您还需要访问远程 Unix 机器。
有几个 Unix 实用程序可以帮助用户在网络分布式环境中进行计算。本章列出了其中的一些。
ping 实用程序
的平命令发送的回波请求给网络上可用的主机。使用此命令,您可以检查远程主机是否响应良好。
ping 命令对以下情况很有用 –
- 跟踪和隔离硬件和软件问题。
- 确定网络和各种外部主机的状态。
- 测试、测量和管理网络。
句法
以下是使用 ftp 命令的简单语法 –
$ping hostname or ip-address
上面的命令每秒钟开始打印一个响应。要退出命令,您可以通过按CNTRL &plus C键终止它。
例子
以下是检查网络上可用主机的可用性的示例 –
$ping google.com PING google.com (74.125.67.100) 56(84) bytes of data. 64 bytes from 74.125.67.100: icmp_seq = 1 ttl = 54 time = 39.4 ms 64 bytes from 74.125.67.100: icmp_seq = 2 ttl = 54 time = 39.9 ms 64 bytes from 74.125.67.100: icmp_seq = 3 ttl = 54 time = 39.3 ms 64 bytes from 74.125.67.100: icmp_seq = 4 ttl = 54 time = 39.1 ms 64 bytes from 74.125.67.100: icmp_seq = 5 ttl = 54 time = 38.8 ms --- google.com ping statistics --- 22 packets transmitted, 22 received, 0% packet loss, time 21017ms rtt min/avg/max/mdev = 38.867/39.334/39.900/0.396 ms $
如果主机不存在,您将收到以下输出 –
$ping giiiiiigle.com ping: unknown host giiiiigle.com $
ftp 实用程序
在这里,FTP代表˚F ILE牛逼转让(BOT)P rotocol。此实用程序可帮助您将文件从一台计算机上传和下载到另一台计算机。
ftp 实用程序有自己的一组类 Unix 命令。这些命令可帮助您执行任务,例如 –
-
连接并登录到远程主机。
-
导航目录。
-
列出目录内容。
-
放置和获取文件。
-
以ascii、ebcdic或binary传输文件。
句法
以下是使用 ftp 命令的简单语法 –
$ftp hostname or ip-address
上面的命令会提示您输入登录 ID 和密码。通过身份验证后,您可以访问登录帐户的主目录,并且可以执行各种命令。
下表列出了一些重要的命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
put filename 将文件名从本地机器上传到远程机器。 |
2 |
get filename 将文件名从远程机器下载到本地机器。 |
3 |
mput file list 将多个文件从本地机器上传到远程机器。 |
4 |
mget file list 从远程机器下载多个文件到本地机器。 |
5 |
prompt off 关闭提示。默认情况下,您将收到使用mput或mget命令上传或下载文件的提示。 |
6 |
prompt on 打开提示。 |
7 |
dir 列出远程机器当前目录中的所有可用文件。 |
8 |
cd dirname 在远程机器上将目录更改为 dirname。 |
9 |
lcd dirname 将目录更改为本地计算机上的 dirname。 |
10 |
quit 帮助从当前登录中注销。 |
应该注意的是,所有文件都将被下载或上传到当前目录或从当前目录上传。如果要将文件上传到特定目录,则需要先更改到该目录,然后再上传所需文件。
例子
以下是显示一些命令工作的示例 –
$ftp amrood.com Connected to amrood.com. 220 amrood.com FTP server (Ver 4.9 Thu Sep 2 20:35:07 CDT 2009) Name (amrood.com:amrood): amrood 331 Password required for amrood. Password: 230 User amrood logged in. ftp> dir 200 PORT command successful. 150 Opening data connection for /bin/ls. total 1464 drwxr-sr-x 3 amrood group 1024 Mar 11 20:04 Mail drwxr-sr-x 2 amrood group 1536 Mar 3 18:07 Misc drwxr-sr-x 5 amrood group 512 Dec 7 10:59 OldStuff drwxr-sr-x 2 amrood group 1024 Mar 11 15:24 bin drwxr-sr-x 5 amrood group 3072 Mar 13 16:10 mpl -rw-r--r-- 1 amrood group 209671 Mar 15 10:57 myfile.out drwxr-sr-x 3 amrood group 512 Jan 5 13:32 public drwxr-sr-x 3 amrood group 512 Feb 10 10:17 pvm3 226 Transfer complete. ftp> cd mpl 250 CWD command successful. ftp> dir 200 PORT command successful. 150 Opening data connection for /bin/ls. total 7320 -rw-r--r-- 1 amrood group 1630 Aug 8 1994 dboard.f -rw-r----- 1 amrood group 4340 Jul 17 1994 vttest.c -rwxr-xr-x 1 amrood group 525574 Feb 15 11:52 wave_shift -rw-r--r-- 1 amrood group 1648 Aug 5 1994 wide.list -rwxr-xr-x 1 amrood group 4019 Feb 14 16:26 fix.c 226 Transfer complete. ftp> get wave_shift 200 PORT command successful. 150 Opening data connection for wave_shift (525574 bytes). 226 Transfer complete. 528454 bytes received in 1.296 seconds (398.1 Kbytes/s) ftp> quit 221 Goodbye. $
telnet 实用程序
有时我们需要连接到远程 Unix 机器并远程在该机器上工作。Telnet是一种实用程序,它允许一个站点的计算机用户建立连接、登录,然后在另一个站点的计算机上进行工作。
使用 Telnet 登录后,您可以在远程连接的机器上执行所有活动。以下是 Telnet 会话的示例 –
C:>telnet amrood.com Trying... Connected to amrood.com. Escape character is '^]'. login: amrood amrood's Password: ***************************************************** * * * * * WELCOME TO AMROOD.COM * * * * * ***************************************************** Last unsuccessful login: Fri Mar 3 12:01:09 IST 2009 Last login: Wed Mar 8 18:33:27 IST 2009 on pts/10 { do your work } $ logout Connection closed. C:>
手指实用程序
将手指在一个给定主机上的用户命令显示的信息。主机可以是本地的,也可以是远程的。
出于安全原因,Finger 可能在其他系统上被禁用。
以下是使用手指命令的简单语法 –
检查本地机器上的所有登录用户 –
$ finger Login Name Tty Idle Login Time Office amrood pts/0 Jun 25 08:03 (62.61.164.115)
获取有关本地机器上可用的特定用户的信息 –
$ finger amrood Login: amrood Name: (null) Directory: /home/amrood Shell: /bin/bash On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115 No mail. No Plan.
检查远程机器上的所有登录用户 –
$ finger @avtar.com Login Name Tty Idle Login Time Office amrood pts/0 Jun 25 08:03 (62.61.164.115)
获取有关远程机器上可用的特定用户的信息 –
$ finger [email protected] Login: amrood Name: (null) Directory: /home/amrood Shell: /bin/bash On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115 No mail. No Plan.
Unix – vi 编辑器教程
在本章中,我们将了解 vi 编辑器如何在 Unix 中工作。在 Unix 中有很多方法可以编辑文件。使用面向屏幕的文本编辑器vi编辑文件是最好的方法之一。此编辑器使您能够在上下文中编辑文件中的其他行的行。
现在还提供了一个改进版的 vi 编辑器,称为VIM。在这里,VIM 代表Vi IM证明。
vi 通常被认为是 Unix 编辑器中的事实标准,因为 –
-
它通常可用于所有类型的 Unix 系统。
-
它的实现非常相似。
-
它需要很少的资源。
-
它比其他编辑器(例如ed或ex)更加用户友好。
您可以使用vi编辑器来编辑现有文件或从头开始创建新文件。您也可以使用此编辑器来读取文本文件。
启动 vi 编辑器
下表列出了使用 vi 编辑器的基本命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
vi filename 如果新文件不存在则创建新文件,否则打开现有文件。 |
2 |
vi -R filename 以只读模式打开现有文件。 |
3 |
view filename 以只读模式打开现有文件。 |
以下是在当前工作目录中不存在时创建新文件testfile的示例–
$vi testfile
上面的命令将生成以下输出 –
| ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ "testfile" [New File]
您会注意到光标后的每一行都有一个波浪号(~)。波浪号代表未使用的行。如果一行不以波浪号开头并且显示为空白,则表示存在空格、制表符、换行符或其他一些不可见的字符。
您现在可以开始处理一个打开的文件。在继续之前,让我们先了解几个重要的概念。
操作模式
在使用 vi 编辑器时,我们通常会遇到以下两种模式 –
-
命令模式– 此模式使您能够执行管理任务,例如保存文件、执行命令、移动光标、剪切(猛拉)和粘贴行或单词,以及查找和替换。在此模式下,您键入的任何内容都被解释为命令。
-
插入模式– 此模式使您能够将文本插入到文件中。在此模式下输入的所有内容都被解释为输入并放置在文件中。
vi 总是以命令模式启动。要输入文本,您必须处于插入模式,只需输入i 即可。要退出插入模式,请按Esc键,这将带您返回命令模式。
提示– 如果您不确定自己处于哪种模式,请按两次 Esc 键;这将带您进入命令模式。使用 vi 编辑器打开文件。首先输入一些字符,然后进入命令模式以了解差异。
退出vi
退出 vi 的命令是:q。进入命令模式后,键入冒号和“q”,然后回车。如果您的文件以任何方式被修改,编辑器会警告您这一点,并且不会让您退出。要忽略此消息,退出 vi 而不保存的命令是:q! . 这使您可以退出 vi 而不保存任何更改。
保存编辑器内容的命令是:w。您可以将上述命令与退出命令结合使用,或者使用:wq并返回。
保存更改并退出 vi的最简单方法是使用 ZZ 命令。当您处于命令模式时,键入ZZ。该ZZ命令的工作方式相同:WQ命令。
如果要为文件指定/说明任何特定名称,可以通过在:w之后指定它来实现。例如,如果您想将您正在处理的文件保存为另一个名为filename2 的文件名,您可以键入:w filename2并返回。
在文件内移动
要在文件中移动而不影响文本,您必须处于命令模式(按 Esc 两次)。下表列出了一些可用于一次移动一个字符的命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
k 将光标向上移动一行 |
2 |
j 将光标向下移动一行 |
3 |
h 将光标向左移动一个字符位置 |
4 |
l 将光标向右移动一个字符位置 |
在文件中移动需要考虑以下几点 –
-
vi 区分大小写。使用命令时需要注意大小写。
-
vi 中的大多数命令都可以以您希望操作发生的次数作为开头。例如,2j将光标向下移动两行。
在 vi 中还有许多其他方法可以在文件中移动。请记住,您必须处于命令模式(按 Esc 两次)。下表列出了一些在文件中移动的命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
0 or &verbar 将光标定位在一行的开头 |
2 |
$ 将光标定位在一行的末尾 |
3 |
w 将光标定位到下一个单词 |
4 |
b 将光标定位到上一个单词 |
5 |
( 将光标定位到当前句子的开头 |
6 |
) 将光标定位到下一个句子的开头 |
7 |
E 移动到空白分隔词的末尾 |
8 |
{ 向后移动一个段落 |
9 |
} 向前移动一个段落 |
10 |
[[ 向后移动一个部分 |
11 |
]] 向前移动一个部分 |
12 |
n| 移动到当前行的第n列 |
13 |
1G 移动到文件的第一行 |
14 |
G 移动到文件的最后一行 |
15 |
nG 移动到nth 文件行 |
16 |
:n 移动到nth 文件行 |
17 |
fc 向前移动到c |
18 |
Fc 移回c |
19 |
H 移动到屏幕顶部 |
20 |
nH 移动到nth 从屏幕顶部的线 |
21 |
M 移动到屏幕中间 |
22 |
L 移动到屏幕底部 |
23 |
nL 移动到nth 屏幕底部的线 |
24 |
😡 冒号后跟一个数字会将光标定位在由x表示的行号上 |
控制命令
以下命令可与控制键一起使用以执行下表中给出的功能 –
Sr.No. | 命令和描述 |
---|---|
1 |
CTRL&plusd 向前移动 1/2 屏幕 |
2 |
CTRL&plusf 向前移动一整屏 |
3 |
CTRL&plusu 向后移动 1/2 屏幕 |
4 |
CTRL&plusb 向后移动一整屏 |
5 |
CTRL&pluse 将屏幕向上移动一行 |
6 |
CTRL&plusy 将屏幕向下移动一行 |
7 |
CTRL&plusu 将屏幕向上移动 1/2 页 |
8 |
CTRL&plusd 将屏幕向下移动 1/2 页 |
9 |
CTRL&plusb 将屏幕向上移动一页 |
10 |
CTRL&plusf 将屏幕向下移动一页 |
11 |
CTRL&plusI 重绘屏幕 |
编辑文件
要编辑文件,您需要处于插入模式。有很多方法可以从命令模式进入插入模式 –
Sr.No. | 命令和描述 |
---|---|
1 |
i 在当前光标位置之前插入文本 |
2 |
I 在当前行的开头插入文本 |
3 |
a 在当前光标位置后插入文本 |
4 |
A 在当前行的末尾插入文本 |
5 |
o 在光标位置下方为文本输入创建一个新行 |
6 |
O 在光标位置上方为文本输入创建一个新行 |
删除字符
这是一个重要命令列表,可用于删除打开文件中的字符和行 –
Sr.No. | 命令和描述 |
---|---|
1 |
x 删除光标所在位置下的字符 |
2 |
X 删除光标位置之前的字符 |
3 |
dw 从当前光标位置删除到下一个单词 |
4 |
d^ 从当前光标位置删除到行首 |
5 |
d$ 从当前光标位置删除到行尾 |
6 |
D 从光标位置删除到当前行的末尾 |
7 |
dd 删除光标所在的行 |
如上所述,vi 中的大多数命令都可以以您希望操作发生的次数作为开头。例如,2x删除光标位置下的两个字符,2dd删除光标所在的两行。
建议先练习这些命令,然后再继续。
更改命令
您还可以更改 vi 中的字符、单词或行而不删除它们。以下是相关命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
cc 删除该行的内容,让您处于插入模式。 |
2 |
cw 将光标所在的单词从光标更改为单词的小写w结尾。 |
3 |
r 替换光标下的字符。vi 进入替换后返回命令模式。 |
4 |
R 覆盖以当前光标下的字符开头的多个字符。您必须使用Esc来停止覆盖。 |
5 |
s 用您键入的字符替换当前字符。之后,您将处于插入模式。 |
6 |
S 删除光标所在的行并用新文本替换它。输入新文本后,vi 仍处于插入模式。 |
复制和粘贴命令
您可以从一个地方复制行或单词,然后可以使用以下命令将它们粘贴到另一个地方 –
Sr.No. | 命令和描述 |
---|---|
1 |
yy 复制当前行。 |
2 |
yw 从小写 w 光标所在的字符复制当前单词,直到单词结束。 |
3 |
p 将复制的文本放在光标之后。 |
4 |
P 将拉出的文本放在光标之前。 |
高级命令
有一些高级命令可以简化日常编辑并允许更有效地使用 vi –
Sr.No. | 命令和描述 |
---|---|
1 |
J 将当前行与下一行连接起来。j 个命令连接了许多行。 |
2 |
<< 将当前行向左移动一个移动宽度。 |
3 |
>> 将当前行向右移动一个移位宽度。 |
4 |
~ 切换光标下字符的大小写。 |
5 |
^G 同时按下 Ctrl 和 G 键可显示当前文件名和状态。 |
6 |
U 将当前行恢复到光标进入该行之前的状态。 |
7 |
u 这有助于撤消在文件中所做的最后更改。再次键入“u”将重新进行更改。 |
8 |
J 将当前行与下一行连接起来。一个计数连接了那么多行。 |
9 |
:f 以%显示当前文件中的位置和文件名,文件总数。 |
10 |
:f filename 将当前文件重命名为 filename。 |
11 |
:w filename 写入文件 filename。 |
12 |
:e filename 用文件名打开另一个文件。 |
13 |
:cd dirname 将当前工作目录更改为 dirname。 |
14 |
:e # 在两个打开的文件之间切换。 |
15 |
:n 如果您使用 vi 打开多个文件,请使用:n转到系列中的下一个文件。 |
16 |
:p 如果您使用 vi 打开多个文件,请使用:p转到系列中的上一个文件。 |
17 |
:N 如果您使用 vi 打开多个文件,请使用:N转到系列中的上一个文件。 |
18 |
:r file 读取文件并将其插入到当前行之后。 |
19 |
:nr file 读取文件并将其插入到第n行之后。 |
单词和字符搜索
vi 编辑器有两种搜索:string和character。对于字符串搜索,/和? 命令被使用。当您启动这些命令时,刚刚键入的命令将显示在屏幕的最后一行,您可以在其中键入要查找的特定字符串。
这两个命令仅在搜索发生的方向上有所不同 –
-
所述/该文件中命令搜索转发(向下)。
-
的?命令在文件中向后(向上)搜索。
的Ñ和Ñ命令在相同或相反的方向上分别重复前面的搜索命令。有些字符有特殊含义。这些字符必须以反斜杠 ( \ )开头,以作为搜索表达式的一部分。
Sr.No. | 字符和描述 |
---|---|
1 |
^ 在行首搜索(在搜索表达式的开头使用)。 |
2 |
. 匹配单个字符。 |
3 |
* 匹配零个或多个前一个字符。 |
4 |
$ 行尾(在搜索表达式的末尾使用)。 |
5 |
[ 开始一组匹配或不匹配的表达式。 |
6 |
< 这是放在一个用反斜杠转义的表达式中,以查找单词的结尾或开头。 |
7 |
> 这有助于查看上面的 ‘ < ‘ 字符描述。 |
字符搜索在一行内搜索以查找在命令后输入的字符。该˚F和˚F命令搜索仅在当前行的文字。f向前搜索,F向后搜索,光标移动到找到的字符位置。
所述吨和Ť命令搜索仅在当前行的字符,但对于吨,光标移动到字符之前的位置,并且Ť搜索线向后的字符后的位置。
设置命令
您可以使用以下:set命令更改 vi 屏幕的外观。进入命令模式后,键入:set后跟以下任何命令。
Sr.No. | 命令和描述 |
---|---|
1 |
:set ic 搜索时忽略大小写 |
2 |
:set ai 设置自动缩进 |
3 |
:set noai 取消自动缩进 |
4 |
:set nu 在左侧显示带有行号的行 |
5 |
:set sw 设置软件制表位的宽度。例如,您可以使用此命令将移位宽度设置为 4 — :set sw = 4 |
6 |
:set ws 如果设置了wrapscan,并且文件底部没有找到该词,它会尝试从头开始搜索 |
7 |
:set wm 如果此选项的值大于零,编辑器将自动“自动换行”。例如,要将换行边距设置为两个字符,您可以输入::set wm = 2 |
8 |
:set ro 将文件类型更改为“只读” |
9 |
:set term 打印终端类型 |
10 |
:set bf 丢弃输入中的控制字符 |
运行命令
vi 能够从编辑器中运行命令。要运行命令,您只需要进入命令模式并键入:! 命令。
例如,如果您想在尝试使用该文件名保存文件之前检查文件是否存在,您可以键入:! ls,您将在屏幕上看到ls的输出。
您可以按任意键(或命令的转义序列)返回到您的 vi 会话。
替换文本
替换命令 ( :s/ ) 使您能够快速替换文件中的单词或单词组。以下是替换文本的语法 –
:s/search/replace/g
该摹代表全球。此命令的结果是光标所在行上的所有匹配项都被更改。
注意事项
以下几点将增加您使用 vi 的成功 –
-
您必须处于命令模式才能使用这些命令。(随时按 Esc 两次以确保您处于命令模式。)
-
你必须小心这些命令。这些是区分大小写的。
-
您必须处于插入模式才能输入文本。
Unix – 什么是 Shell?
一个壳牌为您提供了Unix系统的接口。它收集您的输入并根据该输入执行程序。当程序完成执行时,它会显示该程序的输出。
Shell 是一个我们可以在其中运行命令、程序和 shell 脚本的环境。有不同风格的外壳,就像有不同风格的操作系统一样。每种 shell 都有自己的一组可识别的命令和函数。
外壳提示
提示符$称为命令提示符,由 shell 发出。显示提示时,您可以键入命令。
按Enter后,Shell 会读取您的输入。它通过查看输入的第一个单词来确定您要执行的命令。一个词是一组完整的字符。空格和制表符分隔单词。
以下是date命令的一个简单示例,它显示当前日期和时间 –
$date Thu Jun 25 08:30:19 MST 2009
您可以使用环境教程中解释的环境变量 PS1 自定义命令提示符。
外壳类型
在 Unix 中,有两种主要类型的 shell –
-
Bourne shell – 如果您使用的是 Bourne 类型的 shell,则$字符是默认提示。
-
C shell – 如果您使用的是 C 类型的 shell,则 % 字符是默认提示。
Bourne Shell 具有以下子类别 –
- 伯恩壳 (sh)
- 科恩壳 (ksh)
- Bourne Again shell (bash)
- POSIX 外壳 (sh)
不同的 C 型壳如下 –
- C 壳 (csh)
- TENEX/TOPS C 壳 (tcsh)
最初的 Unix shell 是由 Stephen R. Bourne 在 1970 年代中期在新泽西州 AT&T 贝尔实验室期间编写的。
Bourne shell 是第一个出现在 Unix 系统上的 shell,因此它被称为“shell”。
在大多数 Unix 版本上,Bourne shell 通常安装为/bin/sh。因此,它是编写可在不同 Unix 版本上使用的脚本的首选 shell。
在本章中,我们将介绍大部分基于 Borne Shell 的 Shell 概念。
外壳脚本
shell 脚本的基本概念是一个命令列表,这些命令按执行顺序列出。一个好的 shell 脚本会有注释,前面有#符号,描述步骤。
有条件测试,例如值A大于值B,循环允许我们遍历大量数据,文件读取和存储数据,变量读取和存储数据,脚本可能包含函数。
我们将在接下来的部分中编写许多脚本。这将是一个简单的文本文件,我们将在其中放置我们所有的命令和其他几个必需的结构,这些结构告诉 shell 环境要做什么以及何时做。
Shell 脚本和函数都被解释。这意味着它们没有被编译。
示例脚本
假设我们创建了一个test.sh脚本。请注意,所有脚本都具有.sh扩展名。在向脚本添加任何其他内容之前,您需要提醒系统正在启动一个 shell 脚本。这是使用shebang构造完成的。例如 –
#!/bin/sh
这告诉系统接下来的命令将由 Bourne shell 执行。之所以称为shebang,是因为#符号称为哈希,而! 符号称为 bang。
要创建包含这些命令的脚本,请先放置 shebang 行,然后添加命令 –
#!/bin/bash pwd ls
壳牌评论
您可以将您的评论放在脚本中,如下所示 –
#!/bin/bash # Author : Zara Ali # Copyright (c) Tutorialspoint.com # Script follows here: pwd ls
保存上述内容并使脚本可执行 –
$chmod +x test.sh
现在可以执行 shell 脚本了 –
$./test.sh
执行后,您将收到以下结果 –
/home/amrood index.htm unix-basic_utilities.htm unix-directories.htm test.sh unix-communication.htm unix-environment.htm
注意– 要执行当前目录中可用的程序,请使用./program_name
扩展的 Shell 脚本
Shell 脚本有几个必需的结构,它们告诉 shell 环境要做什么以及何时做。当然,大多数脚本都比上面的更复杂。
毕竟,shell 是一种真正的编程语言,包含变量、控制结构等。无论脚本变得多么复杂,它仍然只是一个按顺序执行的命令列表。
以下脚本使用读取命令,该命令从键盘获取输入并将其分配为变量 PERSON 的值,最后将其打印在 STDOUT 上。
#!/bin/sh # Author : Zara Ali # Copyright (c) Tutorialspoint.com # Script follows here: echo "What is your name?" read PERSON echo "Hello, $PERSON"
这是脚本的示例运行 –
$./test.sh What is your name? Zara Ali Hello, Zara Ali $
Unix – 使用 Shell 变量
在本章中,我们将学习如何在 Unix 中使用 Shell 变量。变量是我们为其赋值的字符串。分配的值可以是数字、文本、文件名、设备或任何其他类型的数据。
变量只不过是指向实际数据的指针。shell 使您能够创建、分配和删除变量。
变量名
变量的名称只能包含字母(a 到 z 或 A 到 Z)、数字(0 到 9)或下划线字符 (_)。
按照惯例,Unix shell 变量的名称为大写。
以下示例是有效的变量名称 –
_ALI TOKEN_A VAR_1 VAR_2
以下是无效变量名称的示例 –
2_VAR -VARIABLE VAR1-VAR2 VAR_A!
您不能使用其他字符的原因,例如! 、*或–是这些字符对 shell 具有特殊含义。
定义变量
变量定义如下 –
variable_name=variable_value
例如 –
NAME="Zara Ali"
上面的示例定义了变量 NAME 并为其分配了值“Zara Ali”。这种类型的变量称为标量变量。标量变量一次只能保存一个值。
Shell 使您能够在变量中存储您想要的任何值。例如 –
VAR1="Zara Ali" VAR2=100
访问值
要访问存储在变量中的值,请在其名称前加上美元符号 ( $ ) –
例如,以下脚本将访问已定义变量 NAME 的值并将其打印在 STDOUT 上 –
#!/bin/sh NAME="Zara Ali" echo $NAME
上面的脚本将产生以下值 –
Zara Ali
只读变量
Shell 提供了一种使用只读命令将变量标记为只读的方法。将变量标记为只读后,其值将无法更改。
例如,以下脚本在尝试更改 NAME 的值时会生成错误 –
#!/bin/sh NAME="Zara Ali" readonly NAME NAME="Qadiri"
上面的脚本将生成以下结果 –
/bin/sh: NAME: This variable is read only.
取消设置变量
取消设置或删除变量会指示 shell 从它跟踪的变量列表中删除该变量。一旦取消设置变量,就无法访问变量中存储的值。
以下是使用unset命令取消设置已定义变量的语法–
unset variable_name
上述命令取消设置已定义变量的值。这是一个简单的示例,演示了该命令的工作原理 –
#!/bin/sh NAME="Zara Ali" unset NAME echo $NAME
上面的例子没有打印任何东西。您不能使用 unset 命令取消设置标记为readonly 的变量。
变量类型
当 shell 运行时,存在三种主要类型的变量 –
-
局部变量– 局部变量是存在于当前 shell 实例中的变量。它不适用于由 shell 启动的程序。它们是在命令提示符下设置的。
-
环境变量– 环境变量可用于 shell 的任何子进程。有些程序需要环境变量才能正常运行。通常,shell 脚本仅定义它运行的程序所需的那些环境变量。
-
外壳变量– 外壳变量是由外壳设置的特殊变量,外壳需要它才能正常运行。其中一些变量是环境变量,而另一些是局部变量。
Unix – 特殊变量
在本章中,我们将详细讨论 Unix 中的特殊变量。在我们之前的一章中,我们了解在变量名中使用某些非字母数字字符时如何小心。这是因为这些字符用于特殊 Unix 变量的名称。这些变量是为特定功能保留的。
例如,$字符表示当前 shell 的进程 ID 号或 PID –
$echo $$
上面的命令写入当前 shell 的 PID –
29949
下表显示了一些可以在 shell 脚本中使用的特殊变量 –
Sr.No. | 变量和描述 |
---|---|
1 |
$0 当前脚本的文件名。 |
2 |
$n 这些变量对应于调用脚本的参数。这里n是一个对应于参数位置的正十进制数(第一个参数是 $1,第二个参数是 $2,依此类推)。 |
3 |
$# 提供给脚本的参数数量。 |
4 |
$* 所有的参数都是双引号的。如果脚本接收两个参数,则 $* 相当于 $1 $2。 |
5 |
$@ 所有参数都单独用双引号引起来。如果脚本接收两个参数,则 $@ 相当于 $1 $2。 |
6 |
$? 执行的最后一个命令的退出状态。 |
7 |
$$ 当前shell的进程号。对于 shell 脚本,这是它们正在执行的进程 ID。 |
8 |
$! 最后一个后台命令的进程号。 |
命令行参数
命令行参数 $1, $2, $3, …$9 是位置参数, $0 指向实际的命令、程序、shell 脚本或函数, $1, $2, $3, …$9 作为参数命令。
以下脚本使用与命令行相关的各种特殊变量 –
#!/bin/sh echo "File Name: $0" echo "First Parameter : $1" echo "Second Parameter : $2" echo "Quoted Values: $@" echo "Quoted Values: $*" echo "Total Number of Parameters : $#"
这是上述脚本的示例运行 –
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2
特殊参数 $* 和 $@
有一些特殊参数允许一次访问所有命令行参数。$*和$@ 的作用相同,除非它们用双引号“”括起来。
这两个参数都指定了命令行参数。但是,“$*”特殊参数将整个列表作为一个参数,中间有空格,“$@”特殊参数将整个列表作为一个参数,并将其分隔为单独的参数。
我们可以编写如下所示的 shell 脚本,以使用 $* 或 $@ 特殊参数处理未知数量的命令行参数 –
#!/bin/sh for TOKEN in $* do echo $TOKEN done
这是上述脚本的示例运行 –
$./test.sh Zara Ali 10 Years Old Zara Ali 10 Years Old
注意– 这里do…done是一种循环,将在后续教程中介绍。
退出状态
在$?变量表示上一个命令的退出状态。
退出状态是每个命令在完成时返回的数值。通常,大多数命令在成功时返回 0 退出状态,如果不成功则返回 1。
由于特定原因,某些命令会返回额外的退出状态。例如,某些命令会区分错误类型,并会根据特定的故障类型返回各种退出值。
以下是成功命令的示例 –
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2 $echo $? 0 $
Unix – 使用 Shell 数组
在本章中,我们将讨论如何在 Unix 中使用 shell 数组。shell 变量足以保存单个值。这些变量称为标量变量。
Shell 支持一种不同类型的变量,称为数组变量。这可以同时保存多个值。数组提供了一种对一组变量进行分组的方法。您可以使用存储所有其他变量的单个数组变量,而不是为所需的每个变量创建一个新名称。
为 Shell 变量讨论的所有命名规则在命名数组时都适用。
定义数组值
数组变量和标量变量之间的区别可以解释如下。
假设您试图将不同学生的姓名表示为一组变量。每个单独的变量都是一个标量变量,如下所示 –
NAME01="Zara" NAME02="Qadir" NAME03="Mahnaz" NAME04="Ayan" NAME05="Daisy"
我们可以使用单个数组来存储上述所有名称。以下是创建数组变量的最简单方法。这有助于为其索引之一分配值。
array_name[index]=value
这里array_name是数组的名称,index是数组中要设置的项的索引,value 是要为该项设置的值。
例如,以下命令 –
NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy"
如果您使用ksh shell,这里是数组初始化的语法 –
set -A array_name value1 value2 ... valuen
如果您使用的是bash shell,这里是数组初始化的语法 –
array_name=(value1 ... valuen)
访问数组值
设置任何数组变量后,您可以按如下方式访问它 –
${array_name[index]}
这里array_name是数组的名称,index是要访问的值的索引。以下是理解概念的示例 –
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Index: ${NAME[0]}" echo "Second Index: ${NAME[1]}"
上面的例子将产生以下结果 –
$./test.sh First Index: Zara Second Index: Qadir
您可以通过以下方式之一访问数组中的所有项目 –
${array_name[*]} ${array_name[@]}
这里array_name是您感兴趣的数组的名称。以下示例将帮助您理解这个概念 –
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Method: ${NAME[*]}" echo "Second Method: ${NAME[@]}"
上面的例子将产生以下结果 –
$./test.sh First Method: Zara Qadir Mahnaz Ayan Daisy Second Method: Zara Qadir Mahnaz Ayan Daisy
Unix – Shell 基本操作符
每个外壳都支持各种运算符。我们将在本章中详细讨论 Bourne shell(默认 shell)。
我们现在将讨论以下运算符 –
- 算术运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试操作符
Bourne shell 最初没有任何执行简单算术运算的机制,但它使用外部程序,awk或expr。
以下示例显示了如何添加两个数字 –
#!/bin/sh val=`expr 2 + 2` echo "Total value : $val"
上面的脚本将生成以下结果 –
Total value : 4
添加时需要考虑以下几点 –
-
运算符和表达式之间必须有空格。例如,2+2 不正确;它应该写为 2 + 2。
-
完整的表达式应包含在‘ ‘之间,称为反引号。
算术运算符
Bourne Shell 支持以下算术运算符。
假设变量a 为10,变量b 为20,然后 –
Operator | 描述 | 例子 |
---|---|---|
&plus (Addition) | 在运算符的任一侧添加值 | `expr $a &plus $b` 将给出 30 |
– (Subtraction) | 从左手操作数中减去右手操作数 | `expr $a – $b` 将给出 -10 |
* (Multiplication) | 将运算符两侧的值相乘 | `expr $a \* $b` 将给出 200 |
/ (Division) | 将左手操作数除以右手操作数 | `expr $b / $a` 将给出 2 |
% (Modulus) | 将左手操作数除以右手操作数并返回余数 | `expr $b % $a` 将给出 0 |
= (Assignment) | 在左操作数中分配右操作数 | a = $b 会将 b 的值赋给 a |
== (Equality) | 比较两个数字,如果两者相同则返回真。 | [ $a == $b ] 将返回 false。 |
!= (Not Equality) | 比较两个数字,如果两者不同则返回真。 | [ $a != $b ] 将返回 true。 |
理解所有条件表达式都应该在方括号内并在它们周围有空格非常重要,例如[ $a == $b ]是正确的,而[$a==$b]是不正确的。
所有算术计算都是使用长整数完成的。
关系运算符
Bourne Shell 支持以下特定于数值的关系运算符。这些运算符不适用于字符串值,除非它们的值是数字。
例如,以下运算符将用于检查 10 和 20 之间以及“10”和“20”之间的关系,但不会检查“十”和“二十”之间的关系。
假设变量a 为10,变量b 为20,然后 –
Operator | 描述 | 例子 |
---|---|---|
-eq | 检查两个操作数的值是否相等;如果是,则条件变为真。 | [ $a -eq $b ] 不正确。 |
-ne | 检查两个操作数的值是否相等;如果值不相等,则条件为真。 | [ $a -ne $b ] 是真的。 |
-gt | 检查左操作数的值是否大于右操作数的值;如果是,则条件变为真。 | [ $a -gt $b ] 不正确。 |
-lt | 检查左操作数的值是否小于右操作数的值;如果是,则条件变为真。 | [ $a -lt $b ] 是真的。 |
-ge | 检查左操作数的值是否大于或等于右操作数的值;如果是,则条件变为真。 | [ $a -ge $b ] 不正确。 |
-le | 检查左操作数的值是否小于或等于右操作数的值;如果是,则条件变为真。 | [ $a -le $b ] 是真的。 |
理解所有条件表达式都应该放在方括号内并在它们周围有空格是非常重要的。例如,[ $a <= $b ]是正确的,而[$a <= $b]是不正确的。
布尔运算符
Bourne Shell 支持以下布尔运算符。
假设变量a 为10,变量b 为20,然后 –
Operator | 描述 | 例子 |
---|---|---|
! | 这是逻辑否定。这将真条件转换为假,反之亦然。 | [!假] 是真的。 |
-o | 这是逻辑OR。如果操作数之一为真,则条件为真。 | [ $a -lt 20 -o $b -gt 100 ] 是真的。 |
-a | 这是合乎逻辑的AND。如果两个操作数都为真,则条件为真,否则为假。 | [ $a -lt 20 -a $b -gt 100 ] 是假的。 |
字符串运算符
Bourne Shell 支持以下字符串运算符。
假设变量a保存“abc”,变量b保存“efg”然后 –
Operator | 描述 | 例子 |
---|---|---|
= | 检查两个操作数的值是否相等;如果是,则条件变为真。 | [ $a = $b ] 不正确。 |
!= | 检查两个操作数的值是否相等;如果值不相等,则条件变为真。 | [ $a != $b ] 是真的。 |
-z | 检查给定的字符串操作数大小是否为零;如果长度为零,则返回 true。 | [ -z $a ] 不正确。 |
-n | 检查给定的字符串操作数大小是否非零;如果它是非零长度,则返回 true。 | [ -n $a ] 不是假的。 |
str | 检查str是否不是空字符串;如果为空,则返回false。 | [ $a ] 不是假的。 |
文件测试操作符
我们有一些运算符可用于测试与 Unix 文件相关的各种属性。
假设一个变量文件包含一个现有的文件名“test”,其大小为 100 字节,并且具有读取、写入和执行权限 –
Operator | 描述 | 例子 |
---|---|---|
-b file | 检查文件是否为块特殊文件;如果是,则条件变为真。 | [ -b $file ] 是假的。 |
-c file | 检查文件是否为字符特殊文件;如果是,则条件变为真。 | [ -c $file ] 是假的。 |
-d file | 检查文件是否为目录;如果是,则条件变为真。 | [ -d $file ] 不正确。 |
-f file | 检查文件是否是普通文件,而不是目录或特殊文件;如果是,则条件变为真。 | [ -f $file ] 是真的。 |
-g file | 检查文件是否设置了组 ID (SGID) 位;如果是,则条件变为真。 | [ -g $file ] 是假的。 |
-k file | 检查文件是否设置了粘滞位;如果是,则条件变为真。 | [ -k $file ] 是假的。 |
-p file | 检查文件是否为命名管道;如果是,则条件变为真。 | [ -p $file ] 是假的。 |
-t file | 检查文件描述符是否打开并与终端关联;如果是,则条件变为真。 | [ -t $file ] 是假的。 |
-u file | 检查文件是否设置了设置用户 ID (SUID) 位;如果是,则条件变为真。 | [ -u $file ] 是假的。 |
-r file | 检查文件是否可读;如果是,则条件变为真。 | [ -r $file ] 是真的。 |
-w file | 检查文件是否可写;如果是,则条件变为真。 | [ -w $file ] 是真的。 |
-x file | 检查文件是否可执行;如果是,则条件变为真。 | [ -x $file ] 是真的。 |
-s file | 检查文件的大小是否大于 0;如果是,则条件变为真。 | [ -s $file ] 是真的。 |
-e file | 检查文件是否存在;即使文件是目录但存在,也是如此。 | [ -e $file ] 是真的。 |
C Shell 运算符
以下链接将为您简要介绍 C Shell 运算符 –
Korn Shell 运营商
以下链接可帮助您了解 Korn Shell Operators –
Unix – Shell 决策
在本章中,我们将了解 Unix 中的 shell 决策。在编写 shell 脚本时,可能会出现需要从给定的两条路径中选择一条路径的情况。因此,您需要利用条件语句来让您的程序做出正确的决定并执行正确的操作。
Unix Shell 支持用于根据不同条件执行不同操作的条件语句。我们现在将在这里理解两个决策声明 –
-
该IF … ELSE语句
-
的情况下… ESAC声明
if…else 语句
If else 语句是有用的决策语句,可用于从给定的选项集中选择一个选项。
Unix Shell 支持以下形式的if…else语句 –
大多数 if 语句使用上一章中讨论的关系运算符检查关系。
案例… esac 声明
您可以使用多个if…elif语句来执行多路分支。然而,这并不总是最好的解决方案,尤其是当所有分支都依赖于单个变量的值时。
Unix Shell 支持case…esac语句,它可以准确地处理这种情况,并且它比重复的if…elif语句更有效。
只有一种形式的case…esac语句已在此处详细描述 –
Unix shell 中的case…esac语句与我们在其他编程语言(如C或C++和PERL等)中的switch…case语句非常相似。
Unix – Shell 循环类型
在本章中,我们将讨论 Unix 中的 shell 循环。循环是一种强大的编程工具,可让您重复执行一组命令。在本章中,我们将检查以下可供 shell 程序员使用的循环类型 –
您将根据情况使用不同的循环。例如,while循环执行给定的命令,直到给定的条件保持为真;在直到循环执行到给定的条件为真。
一旦您有良好的编程实践,您将获得专业知识,从而根据情况开始使用适当的循环。在这里,while和for循环可用于大多数其他编程语言,如C、C++和PERL等。
嵌套循环
所有循环都支持嵌套概念,这意味着您可以将一个循环放入另一个类似或不同的循环中。根据您的要求,这种嵌套可以达到无限次。
这是嵌套while循环的示例。其他循环可以根据编程要求以类似的方式嵌套 –
嵌套 while 循环
可以使用 while 循环作为另一个 while 循环体的一部分。
句法
while command1 ; # this is loop1, the outer loop do Statement(s) to be executed if command1 is true while command2 ; # this is loop2, the inner loop do Statement(s) to be executed if command2 is true done Statement(s) to be executed if command1 is true done
例子
这是循环嵌套的一个简单示例。让我们在用于计数到 9 的循环中添加另一个倒计时循环 –
#!/bin/sh a=0 while [ "$a" -lt 10 ] # this is loop1 do b="$a" while [ "$b" -ge 0 ] # this is loop2 do echo -n "$b " b=`expr $b - 1` done echo a=`expr $a + 1` done
这将产生以下结果。重要的是要注意echo -n在这里是如何工作的。这里-n选项让 echo 避免打印换行符。
0 1 0 2 1 0 3 2 1 0 4 3 2 1 0 5 4 3 2 1 0 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
Unix – Shell 循环控制
在本章中,我们将讨论 Unix 中的 shell 循环控制。到目前为止,您已经了解了创建循环和使用循环来完成不同的任务。有时您需要停止循环或跳过循环的迭代。
在本章中,我们将学习以下两个用于控制 shell 循环的语句:
-
该破声明
-
在继续发言
无限循环
所有循环的生命周期都是有限的,一旦条件为假或真,取决于循环,它们就会出现。
如果不满足所需条件,循环可能会一直持续下去。永远执行而不终止的循环执行无限次。因此,这种循环称为无限循环。
例子
这是一个使用while循环显示数字 0 到 9的简单示例–
#!/bin/sh a=10 until [ $a -lt 10 ] do echo $a a=`expr $a + 1` done
这个循环永远持续下去,因为a总是大于或等于 10并且它永远不会小于 10。
中断声明
该休息语句用于终止整个循环的执行,完成所有的代码行的执行到break语句之后。然后它逐步执行循环结束后的代码。
句法
以下break语句用于跳出循环 –
break
break 命令也可用于退出使用此格式的嵌套循环 –
break n
这里n指定了nth 封闭循环到退出。
例子
这是一个简单的例子,它显示循环在a变为 5 时立即终止–
#!/bin/sh a=0 while [ $a -lt 10 ] do echo $a if [ $a -eq 5 ] then break fi a=`expr $a + 1` done
执行后,您将收到以下结果 –
0 1 2 3 4 5
这是嵌套 for 循环的简单示例。如果var1 等于 2且var2 等于 0,则此脚本会跳出两个循环–
#!/bin/sh for var1 in 1 2 3 do for var2 in 0 5 do if [ $var1 -eq 2 -a $var2 -eq 0 ] then break 2 else echo "$var1 $var2" fi done done
执行后,您将收到以下结果。在内部循环中,您有一个带参数 2 的 break 命令。这表明如果满足条件,您应该退出外部循环并最终退出内部循环。
1 0 1 5
继续声明
该继续语句是类似休息命令,但是它会导致循环退出的当前迭代,而不是整个循环。
当发生错误但您想尝试执行循环的下一次迭代时,此语句很有用。
句法
continue
与 break 语句一样,可以给 continue 命令一个整数参数以跳过嵌套循环中的命令。
continue n
这里n指定了nth 封闭循环继续。
例子
以下循环使用从continue语句返回的 continue 语句并开始处理下一条语句 –
#!/bin/sh NUMS="1 2 3 4 5 6 7" for NUM in $NUMS do Q=`expr $NUM % 2` if [ $Q -eq 0 ] then echo "Number is an even number!!" continue fi echo "Found odd number" done
执行后,您将收到以下结果 –
Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number
Unix – Shell 替换
什么是替代?
当 shell 遇到包含一个或多个特殊字符的表达式时,它会执行替换。
例子
这里,变量的打印值被替换为它的值。同时,“\n”被换行 –
#!/bin/sh a=10 echo -e "Value of a is $a \n"
您将收到以下结果。这里的-e选项可以解释反斜杠转义。
Value of a is 10
以下是没有-e选项的结果–
Value of a is 10\n
以下是可以在 echo 命令中使用的以下转义序列 –
Sr.No. | 转义和描述 |
---|---|
1 |
\\ 反斜杠 |
2 |
\a 警报 (BEL) |
3 |
\b 退格 |
4 |
\c 抑制尾随换行 |
5 |
\f 换页 |
6 |
\n 新队 |
7 |
\r 回车 |
8 |
\t 水平标签 |
9 |
\v 垂直制表符 |
您可以使用-E选项禁用反斜杠转义的解释(默认)。
您可以使用-n选项禁用新行的插入。
命令替换
命令替换是 shell 执行一组给定命令然后用它们的输出替换命令的机制。
句法
当命令被给出时执行命令替换 –
`command`
执行命令替换时,请确保使用反引号,而不是单引号字符。
例子
命令替换通常用于将命令的输出分配给变量。以下每个示例都演示了命令替换 –
#!/bin/sh DATE=`date` echo "Date is $DATE" USERS=`who | wc -l` echo "Logged in user are $USERS" UP=`date ; uptime` echo "Uptime is $UP"
执行后,您将收到以下结果 –
Date is Thu Jul 2 03:59:57 MST 2009 Logged in user are 1 Uptime is Thu Jul 2 03:59:57 MST 2009 03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
变量替换
变量替换使 shell 程序员能够根据变量的状态操作变量的值。
以下是所有可能替换的下表 –
Sr.No. | 表格和说明 |
---|---|
1 |
${var} 替换var的值。 |
2 |
${var:-word} 如果var为 null 或未设置,则用word替换var。var的值不会改变。 |
3 |
${var:=word} 如果var为 null 或未设置,则将var设置为word的值。 |
4 |
${var:?message} 如果var为 null 或未设置,则将消息打印到标准错误。这将检查变量设置是否正确。 |
5 |
${var:&plusword} 如果VAR设置,字代替变种。var的值不会改变。 |
例子
以下是显示上述替换的各种状态的示例 –
#!/bin/sh echo ${var:-"Variable is not set"} echo "1 - Value of var is ${var}" echo ${var:="Variable is not set"} echo "2 - Value of var is ${var}" unset var echo ${var:+"This is default value"} echo "3 - Value of var is $var" var="Prefix" echo ${var:+"This is default value"} echo "4 - Value of var is $var" echo ${var:?"Print this message"} echo "5 - Value of var is ${var}"
执行后,您将收到以下结果 –
Variable is not set 1 - Value of var is Variable is not set 2 - Value of var is Variable is not set 3 - Value of var is This is default value 4 - Value of var is Prefix Prefix 5 - Value of var is Prefix
Unix – Shell 引用机制
在本章中,我们将详细讨论 Shell 的引用机制。我们将从讨论元字符开始。
元字符
Unix Shell 提供了各种元字符,这些元字符在任何 Shell 脚本中使用时都具有特殊含义,除非被引用,否则会导致单词终止。
例如,? 列出目录中的文件时匹配单个字符,*匹配多个字符。这是大多数 shell 特殊字符(也称为元字符)的列表 –
* ? [ ] ' " \ $ ; & ( ) | ^ < > new-line space tab
一个字符可以通过在它前面加上\来引用(即代表它自己)。
例子
以下示例显示了如何打印*或? –
#!/bin/sh echo Hello; Word
执行后,您将收到以下结果 –
Hello ./test.sh: line 2: Word: command not found shell returned 127
现在让我们尝试使用带引号的字符 –
#!/bin/sh echo Hello\; Word
执行后,您将收到以下结果 –
Hello; Word
该$符号是元字符之一,所以必须引述外壳以避免特殊处理-
#!/bin/sh echo "I have \$1200"
执行后,您将收到以下结果 –
I have $1200
下表列出了四种引用形式 –
Sr.No. | 引用和描述 |
---|---|
1 |
Single quote 这些引号之间的所有特殊字符都失去了它们的特殊含义。 |
2 |
Double quote 除了这些例外,这些引号之间的大多数特殊字符都失去了特殊含义 –
|
3 |
Backslash 紧跟在反斜杠后面的任何字符都失去了它的特殊含义。 |
4 |
Back quote 反引号之间的任何内容都将被视为命令并被执行。 |
单引号
考虑一个包含许多特殊 shell 字符的 echo 命令 –
echo <-$1500.**>; (update?) [y|n]
在每个特殊字符前面加一个反斜杠很乏味,而且使行难以阅读 –
echo \<-\$1500.\*\*\>\; \(update\?\) \[y\|n\]
有一种简单的方法可以引用一大群字符。在字符串的开头和结尾放置一个单引号 (‘) –
echo '<-$1500.**>; (update?) [y|n]'
单引号内的字符被引用,就像每个字符前面都有一个反斜杠一样。有了这个,echo 命令以正确的方式显示。
如果要输出的字符串中出现单引号,则不应将整个字符串放在单引号内,而应在其前面使用反斜杠 (\),如下所示 –
echo 'It\'s Shell Programming
双引号
尝试执行以下 shell 脚本。这个 shell 脚本使用单引号 –
VAR=ZARA echo '$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]'
执行后,您将收到以下结果 –
$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]
这不是必须显示的内容。很明显,单引号可以防止变量替换。如果要替换变量值并使引号按预期工作,则需要将命令放在双引号中,如下所示 –
VAR=ZARA echo "$VAR owes <-\$1500.**>; [ as of (`date +%m/%d`) ]"
执行后,您将收到以下结果 –
ZARA owes <-$1500.**>; [ as of (07/02) ]
双引号消除了所有字符的特殊含义,但以下字符除外 –
-
$用于参数替换
-
命令替换的反引号
-
\$启用文字美元符号
-
\`启用文字反引号
-
\”启用嵌入式双引号
-
\\启用嵌入的反斜杠
-
所有其他\字符都是文字(不是特殊的)
单引号内的字符被引用,就像每个字符前面都有一个反斜杠一样。这有助于 echo 命令正确显示。
如果要输出的字符串中出现单引号,则不应将整个字符串放在单引号内,而应在其前面使用反斜杠 (\),如下所示 –
echo 'It\'s Shell Programming'
反引号
将任何 Shell 命令放在反引号之间都会执行该命令。
句法
这是将任何 Shell命令放在反引号之间的简单语法–
var=`command`
例子
的日期命令在下面的示例中执行,并且所产生的结果被存储在DATA变量。
DATE=`date` echo "Current Date: $DATE"
执行后,您将收到以下结果 –
Current Date: Thu Jul 2 05:28:45 MST 2009
Unix – Shell 输入/输出重定向
在本章中,我们将详细讨论 Shell 输入/输出重定向。大多数 Unix 系统命令从您的终端获取输入并将结果输出发送回您的终端。命令通常从标准输入读取其输入,默认情况下它恰好是您的终端。类似地,命令通常将其输出写入标准输出,默认情况下也是您的终端。
输出重定向
通常用于标准输出的命令的输出可以轻松地转移到文件中。此功能称为输出重定向。
如果符号 > file 附加到任何通常将其输出写入标准输出的命令,则该命令的输出将写入文件而不是终端。
检查以下who命令,该命令重定向用户文件中命令的完整输出。
$ who > users
请注意,终端上没有出现任何输出。这是因为输出已从默认标准输出设备(终端)重定向到指定文件。您可以检查用户文件以获取完整内容 –
$ cat users oko tty01 Sep 12 07:30 ai tty15 Sep 12 13:32 ruth tty21 Sep 12 10:10 pat tty24 Sep 12 13:07 steve tty25 Sep 12 13:03 $
如果命令将其输出重定向到文件并且该文件已包含一些数据,则该数据将丢失。考虑以下示例 –
$ echo line 1 > users $ cat users line 1 $
您可以使用 >> 运算符将输出附加到现有文件中,如下所示 –
$ echo line 2 >> users $ cat users line 1 line 2 $
输入重定向
正如命令的输出可以重定向到文件一样,命令的输入也可以从文件重定向。由于大于号 >用于输出重定向,小于号 <用于重定向命令的输入。
通常从标准输入获取输入的命令可以以这种方式从文件重定向其输入。例如,要计算上面生成的文件用户中的行数,您可以执行如下命令 –
$ wc -l users 2 users $
执行后,您将收到以下输出。您可以通过从文件用户重定向wc命令的标准输入来计算文件中的行数–
$ wc -l < users 2 $
请注意,wc 命令的两种形式产生的输出存在差异。在第一种情况下,文件 users 的名称与行数一起列出;在第二种情况下,它不是。
在第一种情况下, wc 知道它正在从文件 users 读取其输入。在第二种情况下,它只知道它正在从标准输入读取其输入,因此它不显示文件名。
这里文档
一个here文档用于输入重定向到一个交互的shell脚本或程序。
通过为交互式程序或交互式 shell 脚本提供所需的输入,我们可以在没有用户操作的情况下在 shell 脚本中运行交互式程序。
此处文档的一般形式是 –
command << delimiter document delimiter
在这里,shell 将<<运算符解释为读取输入的指令,直到找到包含指定分隔符的行。然后,所有输入行直到包含分隔符的行都被送入命令的标准输入中。
分隔符告诉 shell,here文档已经完成。没有它,shell 将永远读取输入。分隔符必须是不包含空格或制表符的单个单词。
以下是命令wc -l的输入以计算总行数 –
$wc -l << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town. EOF 3 $
您可以使用此处的文档使用脚本打印多行,如下所示 –
#!/bin/sh cat << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town. EOF
执行后,您将收到以下结果 –
This is a simple lookup program for good (and bad) restaurants in Cape Town.
以下脚本使用vi文本编辑器运行会话并将输入保存在文件test.txt 中。
#!/bin/sh filename=test.txt vi $filename <<EndOfCommands i This file was created automatically from a shell script ^[ ZZ EndOfCommands
如果您使用 vim 作为 vi 运行此脚本,那么您可能会看到如下输出 –
$ sh test.sh Vim: Warning: Input is not from a terminal $
运行脚本后,您应该会看到以下内容添加到文件test.txt 中–
$ cat test.txt This file was created automatically from a shell script $
丢弃输出
有时您需要执行命令,但不希望输出显示在屏幕上。在这种情况下,您可以通过将输出重定向到文件/dev/null来丢弃输出–
$ command > /dev/null
这里的 command 是您要执行的命令的名称。文件/dev/null是一个特殊的文件,它会自动丢弃其所有输入。
要丢弃命令的输出及其错误输出,请使用标准重定向将STDERR重定向到STDOUT –
$ command > /dev/null 2>&1
这里2代表STDERR,1代表STDOUT。您可以通过将 STDOUT 重定向到 STDERR 来显示消息到 STDERR,如下所示 –
$ echo message 1>&2
重定向命令
以下是可用于重定向的完整命令列表 –
Sr.No. | 命令和描述 |
---|---|
1 |
pgm > file pgm 的输出被重定向到文件 |
2 |
pgm < file 程序 pgm 从文件中读取它的输入 |
3 |
pgm >> file pgm 的输出附加到文件 |
4 |
n > file 带有描述符n 的流的输出重定向到文件 |
5 |
n >> file 将描述符n附加到文件的流的输出 |
6 |
n >& m 将流n 的输出与流m合并 |
7 |
n <& m 将来自流n 的输入与流m合并 |
8 |
<< tag 标准输入从这里到行首的下一个标签 |
9 |
&verbar 从一个程序或进程中获取输出,并将其发送到另一个程序或进程 |
请注意,文件描述符0通常是标准输入 (STDIN),1是标准输出 (STDOUT),而2是标准错误输出 (STDERR)。
Unix – Shell 函数
在本章中,我们将详细讨论 shell 函数。函数使您能够将脚本的整体功能分解为更小的逻辑子部分,然后可以在需要时调用它们来执行各自的任务。
使用函数执行重复性任务是创建代码重用的极好方法。这是现代面向对象编程原则的重要组成部分。
Shell 函数类似于其他编程语言中的子例程、过程和函数。
创建函数
要声明一个函数,只需使用以下语法 –
function_name () { list of commands }
您的函数的名称是function_name,这就是您将用于从脚本中的其他地方调用它的名称。函数名称后必须跟括号,然后是括在大括号内的命令列表。
例子
以下示例显示了函数的使用 –
#!/bin/sh # Define your function here Hello () { echo "Hello World" } # Invoke your function Hello
执行后,您将收到以下输出 –
$./test.sh Hello World
将参数传递给函数
您可以定义一个在调用函数时接受参数的函数。这些参数将由$1、$2等表示。
下面是一个例子,我们传递两个参数Zara和Ali,然后我们在函数中捕获并打印这些参数。
#!/bin/sh # Define your function here Hello () { echo "Hello World $1 $2" } # Invoke your function Hello Zara Ali
执行后,您将收到以下结果 –
$./test.sh Hello World Zara Ali
从函数返回值
如果从函数内部执行退出命令,其效果不仅会终止函数的执行,还会终止调用该函数的 shell 程序。
如果你只想终止函数的执行,那么有办法从定义的函数中出来。
根据情况,您可以使用return命令从函数中返回任何值,其语法如下 –
return code
这里的代码可以是您在此处选择的任何内容,但显然您应该选择在整个脚本上下文中有意义或有用的内容。
例子
以下函数返回值 10 –
#!/bin/sh # Define your function here Hello () { echo "Hello World $1 $2" return 10 } # Invoke your function Hello Zara Ali # Capture value returnd by last command ret=$? echo "Return value is $ret"
执行后,您将收到以下结果 –
$./test.sh Hello World Zara Ali Return value is 10
嵌套函数
函数更有趣的特性之一是它们可以调用自己和其他函数。调用自身的函数称为递归函数。
以下示例演示了两个函数的嵌套 –
#!/bin/sh # Calling one function from another number_one () { echo "This is the first function speaking..." number_two } number_two () { echo "This is now the second function speaking..." } # Calling function one. number_one
执行后,您将收到以下结果 –
This is the first function speaking... This is now the second function speaking...
从提示中调用函数
您可以将常用函数的定义放在.profile 中。无论何时登录,这些定义都将可用,您可以在命令提示符下使用它们。
或者,您可以将定义分组在一个文件中,比如test.sh,然后通过键入在当前 shell 中执行该文件 –
$. test.sh
这会导致test.sh 中定义的函数被读取并定义到当前 shell,如下所示 –
$ number_one This is the first function speaking... This is now the second function speaking... $
要从 shell 中删除函数的定义,请使用带有.f选项的 unset 命令。此命令还用于删除 shell 的变量定义。
$ unset -f function_name
Unix – Shell 手册页帮助
所有 Unix 命令都带有许多可选和强制选项。忘记这些命令的完整语法是很常见的。
因为没有人可能记得每一个 Unix 命令及其所有选项,所以我们有在线帮助可以从 Unix 处于开发阶段时就缓解这种情况。
Unix 版本的帮助文件称为man pages。如果有一个命令名称并且您不确定如何使用它,那么手册页可以帮助您完成每一步。
句法
这是一个简单的命令,可帮助您在使用系统时获取任何 Unix 命令的详细信息 –
$man command
例子
假设有一个命令需要你获得帮助;假设您想了解pwd,那么您只需要使用以下命令 –
$man pwd
上述命令可帮助您了解有关pwd命令的完整信息。在命令提示符下亲自尝试以获取更多详细信息。
您可以使用以下命令获取有关man命令本身的完整详细信息–
$man man
手册页部分
手册页通常分为几个部分,这些部分通常因手册页作者的偏好而异。下表列出了一些常见部分 –
Sr.No. | 部分和说明 |
---|---|
1 |
NAME 命令名称 |
2 |
SYNOPSIS 命令的一般使用参数 |
3 |
DESCRIPTION 描述命令的作用 |
4 |
OPTIONS 描述命令的所有参数或选项 |
5 |
SEE ALSO 列出与手册页中的命令直接相关或与其功能非常相似的其他命令 |
6 |
BUGS 解释命令或其输出中存在的任何已知问题或错误 |
7 |
EXAMPLES 使读者了解如何使用命令的常见用法示例 |
8 |
AUTHORS 手册页/命令的作者 |
总而言之,当您需要有关 Unix 系统中的命令或文件的信息时,手册页是一种重要的资源,也是研究的第一条途径。
有用的 Shell 命令
以下链接为您提供了最重要和最常用的 Unix Shell 命令列表。
如果您不知道如何使用任何命令,请使用手册页获取有关该命令的完整详细信息。
这是Unix Shell – 有用命令的列表
Unix – 带有 SED 的正则表达式
在本章中,我们将详细讨论 Unix 中使用 SED 的正则表达式。
正则表达式是一个字符串,可用于描述多个字符序列。正则表达式由几个不同的 Unix 命令使用,包括ed、sed、awk、grep,以及在更有限的范围内vi。
这里SED代表小号tream版itor。这个面向流的编辑器专为执行脚本而创建。因此,您输入的所有输入都会通过并进入 STDOUT,并且不会更改输入文件。
调用 sed
在我们开始之前,让我们确保我们有一个/etc/passwd文本文件的本地副本来使用sed。
如前所述,可以通过如下方式通过管道向其发送数据来调用 sed –
$ cat /etc/passwd | sed Usage: sed [OPTION]... {script-other-script} [input-file]... -n, --quiet, --silent suppress automatic printing of pattern space -e script, --expression = script ...............................
该猫命令转储的内容/ etc / passwd中以SED通过管道进入的sed的模式空间。模式空间是 sed 用于其操作的内部工作缓冲区。
sed 通用语法
以下是 sed 的一般语法 –
/pattern/action
其中,pattern是一个正则表达式,action是下表中给出的命令之一。如果模式被省略,行动是为每正如我们所看到上面这一行执行。
模式周围的斜线字符 (/) 是必需的,因为它们用作分隔符。
Sr.No. | 范围和描述 |
---|---|
1 |
p 打印行 |
2 |
d 删除行 |
3 |
s/pattern1/pattern2/ 用模式 2 替换第一次出现的模式 1 |
用sed删除所有行
我们现在将了解如何使用 sed 删除所有行。再次调用sed;但是 sed 现在应该使用编辑命令 delete line,由单个字母d 表示–
$ cat /etc/passwd | sed 'd' $
可以指示 sed 从文件中读取数据,而不是通过管道向其发送文件来调用 sed,如下例所示。
以下命令与前面的示例完全相同,没有 cat 命令 –
$ sed -e 'd' /etc/passwd $
sed 地址
sed 也支持地址。地址要么是文件中的特定位置,要么是应应用特定编辑命令的范围。当 sed 没有遇到地址时,它会在文件的每一行上执行操作。
以下命令为您一直使用的 sed 命令添加了一个基本地址 –
$ cat /etc/passwd | sed '1d' |more daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh $
请注意,在删除编辑命令之前添加了数字 1 。这指示 sed 在文件的第一行执行编辑命令。在这个例子中,sed 将删除/etc/password的第一行并打印文件的其余部分。
sed 地址范围
我们现在将了解如何使用sed 地址范围。那么如果你想从一个文件中删除多于一行怎么办?您可以使用 sed 指定地址范围,如下所示 –
$ cat /etc/passwd | sed '1, 5d' |more games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh $
上述命令将应用于从 1 到 5 的所有行。这将删除前五行。
尝试以下地址范围 –
Sr.No. | 范围和描述 |
---|---|
1 |
‘4,10d’ 线路从 4th 直到 10th 被删除 |
2 |
‘10,4d’ 只有 10th 行被删除,因为 sed 不能反向工作 |
3 |
‘4,&plus5d’ 这匹配文件中的第 4 行,删除该行,继续删除接下来的五行,然后停止删除并打印其余的行 |
4 |
‘2,5!d’ 这将删除所有内容,除了从 2 开始nd 直到 5th 线 |
5 |
‘1~3d’ 这将删除第一行,跳过接下来的三行,然后删除第四行。Sed 继续应用此模式,直到文件结束。 |
6 |
‘2~2d’ 这告诉 sed 删除第二行,跳过下一行,删除下一行,并重复直到到达文件末尾 |
7 |
‘4,10p’ 从 4 开始的行th 直到 10th 被印刷 |
8 |
‘4,d’ 这会产生语法错误 |
9 |
‘,10d’ 这也会产生语法错误 |
注意– 使用p操作时,您应该使用-n选项以避免重复行打印。检查以下两个命令之间的差异 –
$ cat /etc/passwd | sed -n '1,3p' Check the above command without -n as follows − $ cat /etc/passwd | sed '1,3p'
替换命令
用s表示的替换命令将用您指定的任何其他字符串替换您指定的任何字符串。
要将一个字符串替换为另一个字符串,sed 需要具有有关第一个字符串结束位置和替换字符串开始位置的信息。为此,我们继续使用正斜杠 ( / ) 字符对两个字符串进行预订。
以下命令用字符串amrood 替换字符串root的一行中的第一次出现。
$ cat /etc/passwd | sed 's/root/amrood/' amrood:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh ..........................
需要注意的是 sed 只替换一行中的第一次出现,这一点非常重要。如果字符串根在一行中出现不止一次,则只会替换第一个匹配项。
要让 sed 执行全局替换,请在命令末尾添加字母g,如下所示 –
$ cat /etc/passwd | sed 's/root/amrood/g' amrood:x:0:0:amrood user:/amrood:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh ...........................
替换标志
除了g标志之外,还有许多其他有用的标志可以传递,您可以一次指定多个。
Sr.No. | 标志和描述 |
---|---|
1 |
g 替换所有匹配项,而不仅仅是第一个匹配项 |
2 |
NUMBER 仅替换 NUMBERth 比赛 |
3 |
p 如果进行了替换,则打印模式空间 |
4 |
w FILENAME 如果进行了替换,则将结果写入 FILENAME |
5 |
I or i 以不区分大小写的方式匹配 |
6 |
M or m 除了特殊正则表达式字符 ^ 和 $ 的正常行为外,该标志还会导致 ^ 匹配换行符之后的空字符串,而 $ 匹配换行符之前的空字符串 |
使用替代字符串分隔符
假设您必须对包含正斜杠字符的字符串进行替换。在这种情况下,您可以通过在s之后提供指定字符来指定不同的分隔符。
$ cat /etc/passwd | sed 's:/root:/amrood:g' amrood:x:0:0:amrood user:/amrood:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh
在上面的例子中,我们使用:作为分隔符而不是斜杠 / 因为我们试图搜索/root而不是简单的根。
用空白空间替换
使用空替换字符串从/etc/passwd文件中完全删除根字符串–
$ cat /etc/passwd | sed 's/root//g' :x:0:0::/:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh
地址替换
如果您只想在第 10 行用字符串quiet替换字符串sh,您可以指定如下:
$ cat /etc/passwd | sed '10s/sh/quiet/g' root:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/quiet
同样,要进行地址范围替换,您可以执行以下操作 –
$ cat /etc/passwd | sed '1,5s/sh/quiet/g' root:x:0:0:root user:/root:/bin/quiet daemon:x:1:1:daemon:/usr/sbin:/bin/quiet bin:x:2:2:bin:/bin:/bin/quiet sys:x:3:3:sys:/dev:/bin/quiet sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
从输出中可以看出,前五行将字符串sh更改为quiet,但其余行保持不变。
匹配命令
您可以使用p选项和-n选项来打印所有匹配的行,如下所示 –
$ cat testing | sed -n '/root/p' root:x:0:0:root user:/root:/bin/sh [root@ip-72-167-112-17 amrood]# vi testing root:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
使用正则表达式
在匹配模式时,您可以使用提供更多灵活性的正则表达式。
检查以下示例,该示例匹配所有以daemon开头的行,然后删除它们 –
$ cat testing | sed '/^daemon/d' root:x:0:0:root user:/root:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
以下是删除所有以sh结尾的行的示例–
$ cat testing | sed '/sh$/d' sync:x:4:65534:sync:/bin:/bin/sync
下表列出了在正则表达式中非常有用的四个特殊字符。
Sr.No. | 字符和描述 |
---|---|
1 |
^ 匹配行的开头 |
2 |
$ 匹配行尾 |
3 |
. 匹配任何单个字符 |
4 |
* 匹配前一个字符的零次或多次出现 |
5 |
[chars] 匹配 chars 中给出的任何一个字符,其中 chars 是一个字符序列。您可以使用 – 字符来指示字符范围。 |
匹配字符
再看几个表达式来演示元字符的使用。例如,以下模式 –
Sr.No. | 表达和描述 |
---|---|
1 |
/a.c/ 匹配包含a&plusc、ac、abc、match和a3c 等字符串的行 |
2 |
/a*c/ 匹配相同的字符串以及诸如ace、yacc和arctic 之类的字符串 |
3 |
/[tT]he/ 匹配字符串The和the |
4 |
/^$/ 匹配空行 |
5 |
/^.*$/ 匹配整行,无论它是什么 |
6 |
/ */ 匹配一个或多个空格 |
7 |
/^$/ 匹配空行 |
下表显示了一些常用的字符集 –
Sr.No. | 设置和说明 |
---|---|
1 |
[a-z] 匹配单个小写字母 |
2 |
[A-Z] 匹配单个大写字母 |
3 |
[a-zA-Z] 匹配单个字母 |
4 |
[0-9] 匹配单个数字 |
5 |
[a-zA-Z0-9] 匹配单个字母或数字 |
字符类关键字
一些特殊的关键字通常可用于regexp,尤其是使用regexp 的GNU 实用程序。这些对于 sed 正则表达式非常有用,因为它们可以简化事情并增强可读性。
例如,字符a 到 z和字符A 到 Z构成一类具有关键字[[:alpha:]]的字符
使用字母字符类关键字,此命令仅打印/etc/syslog.conf文件中以字母开头的那些行–
$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p' authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron uucp,news.crit /var/log/spooler local7.* /var/log/boot.log
下表是 GNU sed 中可用字符类关键字的完整列表。
Sr.No. | 字符类和描述 |
---|---|
1 |
[[:alnum:]] 字母数字 [az AZ 0-9] |
2 |
[[:alpha:]] 字母 [az AZ] |
3 |
[[:blank:]] 空白字符(空格或制表符) |
4 |
[[:cntrl:]] 控制字符 |
5 |
[[:digit:]] 数字 [0-9] |
6 |
[[:graph:]] 任何可见字符(不包括空格) |
7 |
[[:lower:]] 小写字母 [az] |
8 |
[[:print:]] 可打印字符(非控制字符) |
9 |
[[:punct:]] 标点符号 |
10 |
[[:space:]] 空白 |
11 |
[[:upper:]] 大写字母 [AZ] |
12 |
[[:xdigit:]] 十六进制数字 [0-9 af AF] |
与号引用
所述的sed元字符&代表被匹配的模式的内容。例如,假设您有一个名为phone.txt的文件,其中包含电话号码,如下所示 –
5555551212 5555551213 5555551214 6665551215 6665551216 7775551217
您希望将区号(前三位数字)用括号括起来以便于阅读。为此,您可以使用与号替换字符 –
$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt (555)5551212 (555)5551213 (555)5551214 (666)5551215 (666)5551216 (777)5551217
在模式部分,您匹配前 3 位数字,然后使用&将这 3 位数字替换为周围的括号。
使用多个 sed 命令
您可以在单个 sed 命令中使用多个 sed 命令,如下所示 –
$ sed -e 'command1' -e 'command2' ... -e 'commandN' files
这里的command1到commandN是前面讨论过的类型的 sed 命令。这些命令应用于 files 给出的文件列表中的每一行。
使用相同的机制,我们可以编写上面的电话号码示例如下 –
$ sed -e 's/^[[:digit:]]\{3\}/(&)/g' \ -e 's/)[[:digit:]]\{3\}/&-/g' phone.txt (555)555-1212 (555)555-1213 (555)555-1214 (666)555-1215 (666)555-1216 (777)555-1217
注意– 在上面的示例中,我们没有将字符类关键字[[:digit:]]重复三次,而是将其替换为\{3\},这意味着前面的正则表达式匹配了三次。我们还使用\来给出换行符,并且必须在运行命令之前将其删除。
返回参考
该符号元字符是有用的,但更有用在正则表达式定义特定区域的能力。这些特殊区域可用作替换字符串中的参考。通过定义正则表达式的特定部分,您可以使用特殊的引用字符来引用这些部分。
要进行反向引用,您必须先定义一个区域,然后再引用该区域。要定义区域,请在每个感兴趣区域周围插入反斜线括号。然后用反斜杠包围的第一个区域由\1引用,第二个区域由\2引用,依此类推。
假设phone.txt具有以下文本 –
(555)555-1212 (555)555-1213 (555)555-1214 (666)555-1215 (666)555-1216 (777)555-1217
尝试以下命令 –
$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \ code: Second: Third: /' Area code: (555) Second: 555- Third: 1212 Area code: (555) Second: 555- Third: 1213 Area code: (555) Second: 555- Third: 1214 Area code: (666) Second: 555- Third: 1215 Area code: (666) Second: 555- Third: 1216 Area code: (777) Second: 555- Third: 1217
注意– 在上面的示例中,括号内的每个正则表达式将被\1、\2等反向引用。我们在这里使用\来换行。这应该在运行命令之前删除。
Unix – 文件系统基础
文件系统是分区或磁盘上文件的逻辑集合。分区是信息的容器,如果需要,可以跨越整个硬盘驱动器。
您的硬盘驱动器可以有各种分区,这些分区通常只包含一个文件系统,例如一个文件系统包含/file system或另一个包含/home 文件系统。
每个分区一个文件系统允许对不同文件系统进行逻辑维护和管理。
Unix 中的一切都被认为是一个文件,包括物理设备,如 DVD-ROM、USB 设备和软盘驱动器。
目录结构
Unix 使用分层文件系统结构,很像一棵倒置的树,根 (/) 位于文件系统的底部,所有其他目录从那里扩展。
Unix 文件系统是具有以下属性的文件和目录的集合 –
-
它有一个包含其他文件和目录的根目录 ( / )。
-
每个文件或目录都由其名称、它所在的目录和唯一标识符(通常称为inode )唯一标识。
-
按照惯例,根目录的inode编号为2,而lost&plusfound目录的inode编号为3。不使用索引节点编号0和1。文件inode编号可以通过指定可见-i选项来ls命令。
-
它是独立的。一个文件系统和另一个文件系统之间没有依赖关系。
这些目录具有特定用途,并且通常包含相同类型的信息,以便轻松定位文件。以下是 Unix 主要版本上存在的目录 –
Sr.No. | 目录和说明 |
---|---|
1 |
/ 这是根目录,应仅包含文件结构顶层所需的目录 |
2 |
/bin 这是可执行文件所在的位置。这些文件可供所有用户使用 |
3 |
/dev 这些是设备驱动程序 |
4 |
/etc 主管目录命令、配置文件、磁盘配置文件、有效用户列表、组、以太网、主机、发送关键消息的位置 |
5 |
/lib 包含共享库文件,有时还包含其他内核相关文件 |
6 |
/boot 包含用于引导系统的文件 |
7 |
/home 包含用户和其他帐户的主目录 |
8 |
/mnt 用于安装其他临时文件系统,如CD-ROM和软驱的CD-ROM驱动器和软盘驱动器分别 |
9 |
/proc 包含通过进程号或其他对系统动态的信息标记为文件的所有进程 |
10 |
/tmp 保存系统启动之间使用的临时文件 |
11 |
/usr 用于各种用途,可供许多用户使用。包括管理命令、共享文件、库文件等 |
12 |
/var 通常包含可变长度文件,例如日志和打印文件以及可能包含可变数据量的任何其他类型的文件 |
13 |
/sbin 包含二进制(可执行)文件,通常用于系统管理。例如,fdisk和ifconfig实用程序 |
14 |
/kernel 包含内核文件 |
浏览文件系统
现在您了解了文件系统的基础知识,您可以开始导航到您需要的文件。以下命令用于导航系统 –
Sr.No. | 命令和描述 |
---|---|
1 |
cat filename 显示文件名 |
2 |
cd dirname 将您移动到指定的目录 |
3 |
cp file1 file2 将一个文件/目录复制到指定位置 |
4 |
file filename 标识文件类型(二进制、文本等) |
5 |
find filename dir 查找文件/目录 |
6 |
head filename 显示文件的开头 |
7 |
less filename 从结尾或开头浏览文件 |
8 |
ls dirname 显示指定目录的内容 |
9 |
mkdir dirname 创建指定目录 |
10 |
more filename 从头到尾浏览文件 |
11 |
mv file1 file2 移动文件/目录的位置或重命名 |
12 |
pwd 显示用户所在的当前目录 |
13 |
rm filename 删除文件 |
14 |
rmdir dirname 删除目录 |
15 |
tail filename 显示文件的结尾 |
16 |
touch filename 创建一个空白文件或修改现有文件或其属性 |
17 |
whereis filename 显示文件的位置 |
18 |
which filename 如果文件在 PATH 中,则显示文件的位置 |
您可以使用手册页帮助检查此处提到的每个命令的完整语法。
df 命令
管理分区空间的第一种方法是使用df(无磁盘)命令。命令DF -k(磁盘免费)显示磁盘空间以千字节的使用,如下面的-
$df -k Filesystem 1K-blocks Used Available Use% Mounted on /dev/vzfs 10485760 7836644 2649116 75% / /devices 0 0 0 0% /devices $
某些目录(例如/devices )在 kbytes、used 和avail 列中显示为 0,在容量中显示为 0%。这些是特殊(或虚拟)文件系统,尽管它们驻留在 / 下的磁盘上,但它们本身不占用磁盘空间。
该DF -k输出通常是所有Unix系统一样。这是它通常包括的内容 –
Sr.No. | 列和描述 |
---|---|
1 |
Filesystem 物理文件系统名称 |
2 |
kbytes 存储介质上的总可用空间千字节 |
3 |
used 使用的总空间千字节(按文件) |
4 |
avail 可用的总千字节数 |
5 |
capacity 文件使用的总空间百分比 |
6 |
Mounted on 文件系统挂载在什么位置 |
您可以使用-h(人类可读)选项以更易于理解的符号显示大小的格式显示输出。
du 命令
在杜(磁盘使用率)命令,可以指定目录,以显示在特定目录的磁盘空间使用情况。
如果您想确定特定目录占用了多少空间,则此命令很有用。以下命令显示每个目录消耗的块数。根据您的系统,单个块可能需要 512 字节或 1 千字节。
$du /etc 10 /etc/cron.d 126 /etc/default 6 /etc/dfs ... $
该-h选项使输出更容易理解-
$du -h /etc 5k /etc/cron.d 63k /etc/default 3k /etc/dfs ... $
挂载文件系统
必须挂载文件系统才能供系统使用。要查看系统上当前安装的内容(可供使用),请使用以下命令 –
$ mount /dev/vzfs on / type reiserfs (rw,usrquota,grpquota) proc on /proc type proc (rw,nodiratime) devpts on /dev/pts type devpts (rw) $
根据Unix 约定,/mnt目录是临时安装(例如 CDROM 驱动器、远程网络驱动器和软盘驱动器)所在的位置。如果您需要挂载文件系统,您可以使用具有以下语法的 mount 命令 –
mount -t file_system_type device_to_mount directory_to_mount_to
例如,如果要将CD-ROM挂载到目录/mnt/cdrom,则可以键入 –
$ mount -t iso9660 /dev/cdrom /mnt/cdrom
这假设您的 CD-ROM 设备名为/dev/cdrom并且您希望将其挂载到/mnt/cdrom。有关更多具体信息,请参阅 mount 手册页,或在命令行中键入 mount -h以获取帮助信息。
挂载后,您可以使用 cd 命令通过您刚刚创建的挂载点导航新可用的文件系统。
卸载文件系统
要从系统中卸载(移除)文件系统,请通过标识安装点或设备来使用umount命令。
例如,要卸载 cdrom,请使用以下命令 –
$ umount /dev/cdrom
在mount命令使您能够访问你的文件系统,但在大多数现代Unix系统中,自动安装功能,使这个过程对用户不可见的,不需要干预。
用户和组配额
用户和组配额提供了一种机制,通过该机制可以将单个用户或特定组内所有用户使用的空间量限制为管理员定义的值。
配额在两个限制附近运行,如果空间量或磁盘块数开始超过管理员定义的限制,则允许用户采取一些措施 –
-
软限制– 如果用户超过定义的限制,则有一个宽限期,允许用户释放一些空间。
-
硬限制– 当达到硬限制时,无论宽限期如何,都不能分配更多文件或块。
有许多命令可以管理配额 –
Sr.No. | 命令和描述 |
---|---|
1 |
quota 显示组用户的磁盘使用情况和限制 |
2 |
edquota 这是一个配额编辑器。可以使用此命令编辑用户或组配额 |
3 |
quotacheck 扫描文件系统的磁盘使用情况,创建、检查和修复配额文件 |
4 |
setquota 这是一个命令行配额编辑器 |
5 |
quotaon 这向系统宣布应该在一个或多个文件系统上启用磁盘配额 |
6 |
quotaoff 这向系统宣布应该为一个或多个文件系统禁用磁盘配额 |
7 |
repquota 这将打印指定文件系统的磁盘使用情况和配额的摘要 |
您可以使用手册页帮助检查此处提到的每个命令的完整语法。
Unix – 用户管理
在本章中,我们将详细讨论 Unix 中的用户管理。
Unix 系统上有三种类型的帐户 –
根账户
这也称为超级用户,可以完全且不受限制地控制系统。超级用户可以不受任何限制地运行任何命令。该用户应被假定为系统管理员。
系统账号
系统帐户是操作特定于系统的组件所需的帐户,例如邮件帐户和sshd帐户。这些帐户通常是系统上某些特定功能所必需的,对它们进行任何修改都可能对系统产生不利影响。
用户帐号
用户帐户为用户和用户组提供对系统的交互式访问。一般用户通常分配给这些帐户,并且通常对关键系统文件和目录具有有限的访问权限。
Unix 支持Group Account的概念,它在逻辑上将多个帐户分组。每个帐户都将是另一个组帐户的一部分。Unix 组在处理文件权限和进程管理方面起着重要作用。
管理用户和组
有四个主要的用户管理文件 –
-
/etc/passwd – 保留用户帐户和密码信息。该文件包含有关 Unix 系统上帐户的大部分信息。
-
/etc/shadow – 保存相应帐户的加密密码。并非所有系统都支持此文件。
-
/etc/group – 此文件包含每个帐户的组信息。
-
/etc/gshadow – 此文件包含安全组帐户信息。
使用cat命令检查上述所有文件。
下表列出了大多数 Unix 系统上可用于创建和管理帐户和组的命令 –
Sr.No. | 命令和描述 |
---|---|
1 |
useradd 将帐户添加到系统 |
2 |
usermod 修改账户属性 |
3 |
userdel 从系统中删除帐户 |
4 |
groupadd 向系统添加组 |
5 |
groupmod 修改组属性 |
6 |
groupdel 从系统中删除组 |
您可以使用手册页帮助检查此处提到的每个命令的完整语法。
创建组
我们现在将了解如何创建组。为此,我们需要在创建任何帐户之前创建组,否则,我们可以利用系统中现有的组。我们在/etc/groups文件中列出了所有组。
所有默认组都是系统帐户特定组,不建议将它们用于普通帐户。因此,以下是创建新组帐户的语法 –
groupadd [-g gid [-o]] [-r] [-f] groupname
下表列出了参数 –
Sr.No. | 选项和说明 |
---|---|
1 |
-g GID 组ID的数值 |
2 |
-o 此选项允许添加具有非唯一 GID 的组 |
3 |
-r 此标志指示groupadd添加系统帐户 |
4 |
-f 如果指定的组已存在,则此选项仅以成功状态退出。使用 -g,如果指定的 GID 已经存在,则选择其他(唯一的)GID |
5 |
groupname 要创建的实际组名 |
如果不指定任何参数,则系统使用默认值。
以下示例创建了一个具有默认值的开发人员组,这对于大多数管理员来说是非常可接受的。
$ groupadd developers
修改组
要修改组,请使用groupmod语法 –
$ groupmod -n new_modified_group_name old_group_name
要将 developer_2 组名称更改为 developer,请键入 –
$ groupmod -n developer developer_2
以下是您将财务 GID 更改为 545 的方法 –
$ groupmod -g 545 developer
删除组
我们现在将了解如何删除组。要删除现有组,您只需要groupdel 命令和组名即可。要删除财务组,命令是 –
$ groupdel developer
这只会删除该组,而不是与该组关联的文件。这些文件的所有者仍然可以访问这些文件。
创建一个帐户
让我们看看如何在您的 Unix 系统上创建一个新帐户。以下是创建用户帐户的语法 –
useradd -d homedir -g groupname -m -s shell -u userid accountname
下表列出了参数 –
Sr.No. | 选项和说明 |
---|---|
1 |
-d homedir 指定帐户的主目录 |
2 |
-g groupname 为这个账户指定一个组账户 |
3 |
-m 如果主目录不存在,则创建它 |
4 |
-s shell 指定此帐户的默认 shell |
5 |
-u userid 您可以为此帐户指定用户 ID |
6 |
accountname 要创建的实际帐户名称 |
如果不指定任何参数,则系统使用默认值。该useradd的命令修改/ etc / passwd文件,/ etc / shadow文件和/ etc / group的文件,并创建一个主目录。
以下是创建帐户mcmohd的示例,将其主目录设置为/home/mcmohd并将组设置为开发人员。该用户将拥有 Korn Shell 分配给它。
$ useradd -d /home/mcmohd -g developers -s /bin/ksh mcmohd
在发出上述命令之前,请确保您已经使用groupadd命令创建了开发人员组。
创建帐户后,您可以使用passwd命令设置其密码,如下所示 –
$ passwd mcmohd20 Changing password for user mcmohd20. New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully.
当您输入passwd accountname 时,它会为您提供更改密码的选项,前提是您是超级用户。否则,您可以使用相同的命令仅更改密码,但无需指定您的帐户名。
修改账户
该usermod命令命令,可以更改命令行的现有帐户。它使用与useradd命令相同的参数,加上 -l 参数,它允许您更改帐户名称。
例如,要将帐户名mcmohd更改为mcmohd20并相应地更改主目录,您需要发出以下命令 –
$ usermod -d /home/mcmohd20 -m -l mcmohd mcmohd20
删除帐户
的则userdel命令可以用来删除现有用户。如果不小心使用,这是一个非常危险的命令。
命令.r只有一个参数或选项可用,用于删除帐户的主目录和邮件文件。
例如,要删除帐户mcmohd20,请发出以下命令 –
$ userdel -r mcmohd20
如果要保留主目录以进行备份,请省略-r选项。您可以稍后根据需要删除主目录。
Unix – 系统性能
在本章中,我们将详细讨论 Unix 中的系统性能。
我们将向您介绍一些可用于监控和管理 Unix 系统性能的免费工具。这些工具还提供了有关如何诊断和修复 Unix 环境中的性能问题的指南。
Unix 具有以下需要监控和调整的主要资源类型 –
-
中央处理器
-
记忆
-
磁盘空间
-
通讯线路
-
输入输出时间
-
网络时间
-
应用程序
性能组件
下表列出了占用系统时间的五个主要组件 –
Sr.No. | 组件和描述 |
---|---|
1 |
User State CPU CPU 在用户状态下运行用户程序所花费的实际时间。它包括执行库调用所花费的时间,但不包括代表其在内核中花费的时间 |
2 |
System State CPU 这是 CPU 代表此程序在系统状态中花费的时间。所有I/O 例程都需要内核服务。程序员可以通过阻塞 I/O 传输来影响这个值 |
3 |
I/O Time and Network Time 这是移动数据和服务 I/O 请求所花费的时间 |
4 |
Virtual Memory Performance 这包括上下文切换和交换 |
5 |
Application Program 运行其他程序所花费的时间 – 当系统不为该应用程序提供服务时,因为另一个应用程序当前拥有 CPU |
性能工具
Unix 提供以下重要工具来测量和微调 Unix 系统性能 –
Sr.No. | 命令和描述 |
---|---|
1 |
nice/renice 运行具有修改调度优先级的程序 |
2 |
netstat 打印网络连接、路由表、接口统计信息、伪装连接和多播成员资格 |
3 |
time 帮助计时一个简单的命令或提供资源使用情况 |
4 |
uptime 这是系统负载平均值 |
5 |
ps 报告当前进程的快照 |
6 |
vmstat 报告虚拟内存统计信息 |
7 |
gprof 显示调用图配置文件数据 |
8 |
prof 促进过程分析 |
9 |
top 显示系统任务 |
您可以使用手册页帮助检查此处提到的每个命令的完整语法。
Unix – 系统日志
在本章中,我们将详细讨论 Unix 中的系统日志记录。
Unix 系统有一个非常灵活和强大的日志系统,它使您能够记录几乎所有您能想象到的内容,然后操作日志以检索您需要的信息。
许多版本的 Unix 提供了一个称为syslog的通用日志工具。需要记录信息的各个程序将信息发送到 syslog。
Unix syslog是一种主机可配置的统一系统日志记录工具。系统使用运行程序/etc/syslogd或/etc/syslog的集中系统日志记录进程。
系统记录器的操作非常简单。程序将它们的日志条目发送到syslogd,它会查阅配置文件/etc/syslogd.conf或/etc/syslog并在找到匹配项时将日志消息写入所需的日志文件。
您应该了解四个基本的系统日志术语 –
Sr.No. | 术语和描述 |
---|---|
1 |
Facility 用于描述提交日志消息的应用程序或进程的标识符。例如,邮件、内核和 ftp。 |
2 |
Priority 消息重要性的指标。级别在 syslog 中定义为指导方针,从调试信息到关键事件。 |
3 |
Selector 一个或多个设施和级别的组合。当传入事件与选择器匹配时,将执行操作。 |
4 |
Action 匹配选择器的传入消息会发生什么 – 操作可以将消息写入日志文件,将消息回显到控制台或其他设备,将消息写入登录用户,或将消息发送到另一个系统日志服务器。 |
系统日志设施
我们现在将了解系统日志设施。以下是选择器的可用工具。并非所有工具都存在于所有版本的 Unix 上。
Facility | 描述 |
---|---|
1 |
auth 与请求名称和密码相关的活动(getty、su、login) |
2 |
authpriv 与 auth 相同,但登录到只能由选定用户读取的文件 |
3 |
console 用于捕获通常定向到系统控制台的消息 |
4 |
cron 来自 cron 系统调度程序的消息 |
5 |
daemon 系统守护进程包罗万象 |
6 |
ftp 与 ftp 守护进程相关的消息 |
7 |
kern 内核消息 |
8 |
local0.local7 每个站点定义的本地设施 |
9 |
lpr 来自行式打印系统的消息 |
10 |
与邮件系统相关的消息 |
11 |
mark 用于在日志文件中生成时间戳的伪事件 |
12 |
news 与网络新闻协议 (nntp) 相关的消息 |
13 |
ntp 与网络时间协议相关的消息 |
14 |
user 常规用户流程 |
15 |
uucp UUCP子系统 |
系统日志优先级
下表总结了系统日志优先级 –
Sr.No. | 优先级和描述 |
---|---|
1 |
emerg 紧急情况,例如即将发生的系统崩溃,通常会广播给所有用户 |
2 |
alert 应立即纠正的情况,例如系统数据库损坏 |
3 |
crit 临界条件,例如硬件错误 |
4 |
err 普通错误 |
5 |
Warning 警告 |
6 |
notice 不是错误但可能应该以特殊方式处理的情况 |
7 |
info 信息性消息 |
8 |
debug 调试程序时使用的消息 |
9 |
none 用于指定不记录消息的伪级别 |
设施和级别的组合使您能够辨别记录的内容以及该信息的去向。
当每个程序尽职尽责地将其消息发送到系统记录器时,记录器会根据选择器中定义的级别来决定要跟踪什么和丢弃什么。
当您指定一个级别时,系统将跟踪该级别及更高级别的所有内容。
/etc/syslog.conf 文件
在/etc/syslog.conf文件记录消息的位置文件控制。典型的syslog.conf文件可能如下所示 –
*.err;kern.debug;auth.notice /dev/console daemon,auth.notice /var/log/messages lpr.info /var/log/lpr.log mail.* /var/log/mail.log ftp.* /var/log/ftp.log auth.* @prep.ai.mit.edu auth.* root,amrood netinfo.err /var/log/netinfo.log install.* /var/log/install.log *.emerg * *.alert |program_name mark.* /dev/console
文件的每一行包含两部分 –
-
一个消息选择器,指定要记录的消息类型。例如,来自内核的所有错误消息或所有调试消息。
-
一个操作字段,说明应该对消息做什么。例如,将其放入文件或将消息发送到用户的终端。
以下是上述配置的值得注意的点 –
-
消息选择器有两个部分:一个工具和一个优先级。例如,kern.debug选择内核(工具)生成的所有调试消息(优先级)。
-
消息选择器kern.debug选择所有大于 debug 的优先级。
-
代替设施或优先级的星号表示“全部”。例如,*. debug 表示所有调试消息,而kern.*表示内核生成的所有消息。
-
您还可以使用逗号来指定多个设施。可以使用分号将两个或多个选择器组合在一起。
记录操作
动作字段指定五个动作之一 –
-
将消息记录到文件或设备。例如,/var/log/lpr.log或/dev/console。
-
向用户发送消息。您可以通过用逗号分隔来指定多个用户名;例如,root、amrood。
-
向所有用户发送消息。在这种情况下,操作字段由星号组成;例如, *。
-
将消息通过管道传送到程序。在这种情况下,程序在 Unix 管道符号 (|) 之后指定。
-
将消息发送到另一台主机上的系统日志。在这种情况下,操作字段包含一个主机名,前面是一个 at 符号;例如,@tutorialspoint.com。
记录器命令
Unix 提供了logger命令,这是一个处理系统日志非常有用的命令。所述记录器命令发送消息记录到syslogd守护进程,并且因此引发系统日志记录。
这意味着我们可以随时从命令行检查syslogd守护进程及其配置。logger 命令提供了一种从命令行向系统日志文件添加单行条目的方法。
命令的格式是 –
logger [-i] [-f file] [-p priority] [-t tag] [message]...
这是参数的详细信息 –
Sr.No. | 选项和说明 |
---|---|
1 |
-f filename 使用文件 filename 的内容作为要记录的消息。 |
2 |
-i 用每一行记录记录器进程的进程 ID。 |
3 |
-p priority 输入具有指定优先级的消息(指定的选择器条目);消息优先级可以用数字指定,也可以指定为一个 factory.priority 对。默认优先级是 user.notice。 |
4 |
-t tag 用指定的标签标记添加到日志的每一行。 |
5 |
message 其内容按指定顺序连接在一起的字符串参数,由空格分隔。 |
您可以使用手册页帮助检查此命令的完整语法。
日志轮换
日志文件具有增长非常快并消耗大量磁盘空间的倾向。为了启用日志轮换,大多数发行版使用诸如newsyslog或logrotate 之类的工具。
应该使用cron 守护程序在频繁的时间间隔内调用这些工具。查看newsyslog或logrotate的手册页以获取更多详细信息。
重要日志位置
所有系统应用程序都在/var/log及其子目录中创建它们的日志文件。以下是一些重要的应用程序及其相应的日志目录 –
Application | 目录 |
---|---|
httpd | /var/log/httpd |
samba | /var/日志/桑巴 |
cron | /var/日志/ |
/var/日志/ | |
mysql | /var/日志/ |
Unix – 信号和陷阱
在本章中,我们将详细讨论 Unix 中的信号和陷阱。
信号是发送到程序的软件中断,用于指示发生了重要事件。事件可以从用户请求到非法内存访问错误。一些信号,例如中断信号,表明用户要求程序做一些不在通常控制流程中的事情。
下表列出了您可能会遇到并希望在您的程序中使用的常见信号 –
Signal Name | 信号编号 | 描述 |
---|---|---|
SIGHUP | 1 | 检测到控制终端挂断或控制进程死亡 |
SIGINT | 2 | 在用户发送中断信号时发出 (Ctrl + C) |
SIGQUIT | 3 | 当用户发送退出信号时发出 (Ctrl + D) |
SIGFPE | 8 | 如果尝试进行非法数学运算时发出 |
SIGKILL | 9 | 如果进程收到此信号,它必须立即退出并且不会执行任何清理操作 |
SIGALRM | 14 | 闹钟信号(用于定时器) |
SIGTERM | 15 | 软件终止信号(默认由kill发送) |
信号列表
有一种简单的方法可以列出系统支持的所有信号。只需发出kill -l命令,它就会显示所有支持的信号 –
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
信号的实际列表在 Solaris、HP-UX 和 Linux 之间有所不同。
默认操作
每个信号都有一个与之关联的默认操作。信号的默认操作是脚本或程序在收到信号时执行的操作。
一些可能的默认操作是 –
-
终止进程。
-
忽略信号。
-
转储核心。这将创建一个名为core的文件,其中包含进程收到信号时的内存映像。
-
停止进程。
-
继续停止的进程。
发送信号
有多种向程序或脚本传递信号的方法。最常见的一种方法是用户在脚本执行时键入CONTROL-C或INTERRUPT 键。
当您按下Ctrl+C键时,一个SIGINT被发送到脚本,并且根据定义的默认操作脚本终止。
传递信号的另一种常用方法是使用kill 命令,其语法如下 –
$ kill -signal pid
这里的信号是要传递的信号的编号或名称,pid是信号应发送到的进程 ID。例如 –
$ kill -1 1001
上述命令将 HUP 或挂断信号发送到正在运行的进程 ID 为 1001 的程序。要向同一进程发送终止信号,请使用以下命令 –
$ kill -9 1001
这会终止使用进程 ID 1001运行的进程。
捕获信号
当您在执行 shell 程序期间在终端上按Ctrl+C或 Break 键时,通常该程序会立即终止,并且您的命令提示符会返回。这可能并不总是可取的。例如,您最终可能会留下一堆无法清理的临时文件。
捕获这些信号非常容易,并且 trap 命令具有以下语法 –
$ trap commands signals
这里command可以是任何有效的 Unix 命令,甚至是用户定义的函数,并且 signal 可以是您想要捕获的任意数量信号的列表。
shell 脚本中的 trap 有两种常见用途 –
- 清理临时文件
- 忽略信号
清理临时文件
作为 trap 命令的示例,以下显示了如何删除一些文件,然后在有人试图从终端中止程序时退出 –
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
从 shell 程序中执行此陷阱的那一刻起,如果程序接收到信号编号 2,将自动删除两个文件work1$$和dataout$$。
因此,如果用户在执行此陷阱后中断程序的执行,您可以放心,这两个文件将被清除。rm 后面的退出命令是必要的,因为如果没有它,程序将在接收到信号时停止的点继续执行。
信号编号 1 是为挂断生成的。要么有人故意挂断线路,要么线路意外断开。
在这种情况下,您可以修改前面的陷阱以通过将信号编号 1 添加到信号列表中来删除两个指定的文件 –
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
现在,如果线路挂断或按下Ctrl+C键,这些文件将被删除。
如果指定给 trap 的命令包含多个命令,则必须用引号括起来。另请注意,shell 会在执行 trap 命令时以及在接收到列出的信号之一时扫描命令行。
因此,在前面的示例中,WORKDIR和$$的值将在执行陷阱命令时被替换。如果您希望在接收到信号 1 或 2 时发生这种替换,您可以将命令放在单引号内 –
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
忽略信号
如果为陷阱列出的命令为空,则接收时将忽略指定的信号。例如,命令 –
$ trap '' 2
这指定中断信号将被忽略。在执行不想被中断的操作时,您可能希望忽略某些信号。您可以指定多个要忽略的信号,如下所示 –
$ trap '' 1 2 3 15
请注意,必须为要忽略的信号指定第一个参数,并且不等同于编写以下内容,其具有单独的含义 –
$ trap 2
如果您忽略一个信号,则所有子 shell 也会忽略该信号。但是,如果您指定在接收到信号时要采取的操作,则所有子 shell 仍将在接收到该信号时采取默认操作。
重置陷阱
在您更改接收信号时要采取的默认操作后,如果您只需省略第一个参数,您可以使用陷阱再次将其更改回来;所以 –
$ trap 1 2
这会将在接收到信号 1 或 2 时要采取的操作重置为默认值。