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 架构

统一所有 Unix 版本的主要概念是以下四个基础知识 –

  • 内核– 内核是操作系统的核心。它与硬件和大多数任务(如内存管理、任务调度和文件管理)交互。

  • Shell – Shell 是处理您的请求的实用程序。当您在终端上输入命令时,shell 会解释该命令并调用您想要的程序。shell 对所有命令使用标准语法。C Shell、Bourne Shell 和 Korn Shell 是最著名的 shell,它们可用于大多数 Unix 变体。

  • 命令和实用程序– 您可以在日常活动中使用各种命令和实用程序。cpmvcatgrep等是命令和实用程序的几个例子。有超过 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

$

在你的系统上试试。此命令列出与当前登录关联的帐户名称。你也可以试试我是谁来获取关于你自己的信息。

谁登录了?

有时您可能有兴趣知道谁同时登录到计算机。

根据您希望了解其他用户的程度,可以使用三个命令来获取此信息:userswhow

$ 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列表示例中,每个文件行都以dl开头这些字符表示列出的文件的类型。

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目录的执行访问权才能执行lscd命令。

更改权限

要更改文件或目录权限,请使用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上面提到的所有权限也是根据所有者和组分配的。

有两个命令可用于更改所有者和文件组 –

  • chownchown命令代表“更改所有者”,用于更改文件的所有者。

  • chgrpchgrp命令代表“更改组”,用于更改文件的组。

改变所有权

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,但bashksh使用了一些其他文件

.profile 文件

文件/etc/profile由您的 Unix 机器的系统管理员维护,包含系统上所有用户所需的 shell 初始化信息。

文件.profile由您控制。您可以向该文件添加任意数量的 shell 自定义信息。您需要配置的最少信息集包括 –

  • 您使用的终端类型。
  • 用于定位命令的目录列表。
  • 影响终端外观的变量列表。

您可以检查您的主目录中可用.profile使用 vi 编辑器打开它并检查为您的环境设置的所有变量。

设置终端类型

通常,您使用的终端类型由logingetty程序自动配置有时,自动配置过程会错误地猜测您的终端。

如果您的终端设置不正确,命令的输出可能看起来很奇怪,或者您可能无法与 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 包括两个强大的文本格式化程序,nrofftroff

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 命令

命令lplpr将文件打印到纸上而不是屏幕显示。准备好使用pr命令格式化后,您可以使用这些命令中的任何一个在连接到计算机的打印机上打印文件。

您的系统管理员可能已经在您的站点设置了默认打印机。在默认打印机上打印名为food的文件,请使用lplpr命令,如下例所示 –

$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 应该是一个逗号分隔的名称列表。

以下是向 admin@yahoo.com 发送测试消息的示例。

$mail -s "Test Message" admin@yahoo.com 

然后您需要输入您的消息,然后在一行的开头输入“control-D”要停止,只需按如下方式输入点(.)

Hi,

This is a test
.
Cc: 

您可以使用重定向 < 操作符发送一个完整的文件,如下所示 –

$mail -s "Report 05/06/07" admin@yahoo.com < 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 月份修改的文件进行排序。

以下管道由命令lsgrepsort 组成

$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 命令。这些命令可帮助您执行任务,例如 –

  • 连接并登录到远程主机。

  • 导航目录。

  • 列出目录内容。

  • 放置和获取文件。

  • asciiebcdicbinary传输文件

句法

以下是使用 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

关闭提示。默认情况下,您将收到使用mputmget命令上传或下载文件的提示

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 amrood@avtar.com
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 系统。

  • 它的实现非常相似。

  • 它需要很少的资源。

  • 它比其他编辑器(例如edex)更加用户友好

您可以使用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 命令。当您处于命令模式时,键入ZZZZ命令的工作方式相同: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 编辑器有两种搜索:stringcharacter对于字符串搜索,/? 命令被使用。当您启动这些命令时,刚刚键入的命令将显示在屏幕的最后一行,您可以在其中键入要查找的特定字符串。

这两个命令仅在搜索发生的方向上有所不同 –

  • 所述/该文件中命令搜索转发(向下)。

  • 命令在文件中向后(向上)搜索。

ÑÑ命令在相同或相反的方向上分别重复前面的搜索命令。有些字符有特殊含义。这些字符必须以反斜杠 ( \ )开头,以作为搜索表达式的一部分。

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 最初没有任何执行简单算术运算的机制,但它使用外部程序,awkexpr

以下示例显示了如何添加两个数字 –

#!/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 运算符 –

C Shell 运算符

Korn Shell 运营商

以下链接可帮助您了解 Korn Shell Operators –

Korn Shell 运营商

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语句与我们在其他编程语言(如CC++PERL等)中switch…case语句非常相似

Unix – Shell 循环类型

在本章中,我们将讨论 Unix 中的 shell 循环。循环是一种强大的编程工具,可让您重复执行一组命令。在本章中,我们将检查以下可供 shell 程序员使用的循环类型 –

您将根据情况使用不同的循环。例如,while循环执行给定的命令,直到给定的条件保持为真;直到循环执行到给定的条件为真。

一旦您有良好的编程实践,您将获得专业知识,从而根据情况开始使用适当的循环。在这里,whilefor循环可用于大多数其他编程语言,如CC++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 等于 2var2 等于 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替换varvar的值不会改变。

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代表STDERR1代表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等表示。

下面是一个例子,我们传递两个参数ZaraAli,然后我们在函数中捕获并打印这些参数。

#!/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 命令使用,包括edsedawkgrep,以及在更有限的范围内vi

这里SED代表小号treamitor。这个面向流的编辑器专为执行脚本而创建。因此,您输入的所有输入都会通过并进入 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&pluscacabcmatcha3c 等字符串的行

2

/a*c/

匹配相同的字符串以及诸如aceyaccarctic 之类的字符串

3

/[tT]he/

匹配字符串Thethe

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

这里的command1commandN是前面讨论过的类型的 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不使用索引节点编号01文件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

包含二进制(可执行)文件,通常用于系统管理。例如,fdiskifconfig实用程序

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

mail

与邮件系统相关的消息

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

其内容按指定顺序连接在一起的字符串参数,由空格分隔。

您可以使用手册页帮助检查此命令的完整语法。

日志轮换

日志文件具有增长非常快并消耗大量磁盘空间的倾向。为了启用日志轮换,大多数发行版使用诸如newsysloglogrotate 之类的工具

应该使用cron 守护程序在频繁的时间间隔内调用这些工具查看newsysloglogrotate的手册页以获取更多详细信息。

重要日志位置

所有系统应用程序都在/var/log及其子目录中创建它们的日志文件以下是一些重要的应用程序及其相应的日志目录 –

Application 目录
httpd /var/log/httpd
samba /var/日志/桑巴
cron /var/日志/
mail /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-CINTERRUPT 键

当您按下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 时要采取的操作重置为默认值。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁