【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

11.命令执行顺序控制与管道

11.1命令执行顺序控制

通常情况下,我们每次只在终端输入一条命令,回车执行完成后,再输入第二条命令。倘若有事需要离开,就很耽误事。此时就要把命令一次性输入完,让它自己去依次执行。

通常操作:

sudo apt-get update #等该命令执行完,输入下一行命令,安装软件包

sudo apt-get install some-tool #等软件包安装完,输入下一行命令,执行软件

some-tool

一次性输完:

sudo apt-get update;sudo apt-get install some-tool;some-tool

简单的顺序执行用分号;隔开即可。

但是倘若中间的一条命令执行不成功,下一条命令又依赖于上一条命令的结果,就会造成花了时间,最终得到一个错误的结果。

这时就需要&&||来进行有选择的执行命令。

&&表示如果前面的命令执行结果(不是表示终端输出的内容,而是表示命令执行状态的结果)返回值0,则执行后面的,否则不执行。

||&&恰恰相反,当上一条命令执行结果≠0时,则执行后面的命令。

举例如下:

使用which(第六章文件查找)判断是否安装某程序,如cowsay,从$?环境变量获取上一次命令的返回结果。

which cowsay

倘若该程序有安装,则终端无任何输出,倘若未安装,则会输出:

cowsay not found

此时使用以下命令,获取上一次命令返回结果:

echo $?

可以得出,若该程序安装,which cowsay返回得结果为0,若未安装,返回得结果是1。

因此我们可以用以下命令控制命令执行:

which cowsay>/dev/null || sudo apt-get install cowsay

注意1:以上命令中的/dev/null,在类Unix系统中,称为空设备,也称位桶或黑洞,是一个特殊的设备文件,它可以丢弃一切写入其中的数据,读取它则会立即得到一个EOF。/dev/null通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。

注意2:以上命令中的>,代表重定向到一个文件或设备,覆盖原来的文件。此时使用该重定向符号可以将屏幕输出的信息转存到黑洞,不干扰屏幕正常的输出结果。若不重定向,并不影响结果,但是屏幕会多输出一行:cowsay not found

以上为基本操作,还可以将&&||结合使用,如下:

which cowsay>/dev/null && echo "exist" || echo "not exist"

【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

11.2管道

管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式就是将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)。

管道又分匿名管道和具名管道。我们在使用一些过滤程序时经常会用到的就是匿名管道,在命令行中由分隔符|表示。具名管道简单的说就是有名字的管道,通常只会在源程序中用到具名管道。

举例:

使用ls命令查看/etc目录:

ls -al /etc

终端会输出太多内容,不方便查看和寻找目标文件信息。假设我们要寻找有关任务计划cron相关文件:

ls -al /etc | grep cron*

在上一条命令查找出来的众多目录中,查找出与cron相关的并输出。

11.3cut命令

该命令可从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。

cut option <file name>

cut命令参数说明:

参数 说明
-b 以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非指定了-n
-c 以字符为单位进行分割
-d 自定义分隔符,默认为制表符
-f -d一起使用,指定显示哪个区域
-n 取消分割多字节字符。仅和-b一起使用。如果字符的最后一个字节落在-b的List参数指示的范围之内,该字符将被写出,否则会被排除。

举例:

打印/etc/passwd文件中以:为分隔符的第一个字段和第6个字段,分别表示用户名和其家目录:

cut /etc/passwd -d ‘:‘ -f 1,6

打印/etc/passwd文件中每一行的前N个字符:

cut /etc/passwd -c -5 前五个(包含第五个)

cut /etc/passwd -c 5- 前五个之后的(包含第五个)

cut /etc/passwd -c 5 第五个

cut /etc/passwd -c 2-5 2 到 5 之间的(包含第二个和第五个)

11.4grep命令

该命令是一个强大而又相当常用的一个命令,结合正则表达式可以实现很复杂却很高效的匹配和查找。

语法为:

grep option 用于匹配的表达式

举例:

以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串"update"的文件,并打印出该字符串所在行的内容,使用的命令为:

grep -r update /etc/acpi

以上命令中参数-r代表递归搜索子目录中的文件。

11.5wc命令

wc命令用于统计并输出一个文件中行、单词和字节的数目,比如输出/etc/passwd文件中的统计信息:

wc -l /etc/passwd 行数

wc -w /etc/passwd 单词数

wc -c /etc/passwd 字节数

wc -m /etc/passwd 字符数

wc -L /etc/passwd 最长行字节数

注意:对于西文字符来说,一个字符就是一个字节,但对于中文字符,一个汉字是大于等于两个字节的,具体数目由字符编码决定。

11.6sort排序命令

该命令就是将输入按照一定方式排序,然后再输出,它支持的排序有按字典排序、数字排序、月份排序、随机排序和反转排序、指定特定字段进行排序等等。

默认为字典排序:

cat /etc/passwd | sort

反转排序:

cat /etc/passwd | sort -r

按特定字段排序:

cat /etc/passwd | sort -t‘:‘ -k 3

以上命令中参数-t是用于指定字段的分隔符,这里以:作为分隔符;-k用于指定对哪一个字段进行排序。这里/etc/passwd文件的第三个字段为数字,默认为字典排序,如果要按数字排序,加上参数-n即可。

11.7uniq去重命令

该命令可以用于过滤或者输出重复行。

使用touch demo.txt创建一个空白文件,并使用vim进行内容编辑,如下:

【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

  • 过滤重复行

    cat demo.txt | uniq

    可以得到终端输出为:

    a
    b
    aa
    bb
    aa
    bb

    仔细观察可以发现,uniq命令去重只能去连续重复得行,并非全文去重。要达到预期效果,可以先进行排序:

    cat demo.txt | sort |uniq

    可以得到终端输出为:

    a
    aa
    b
    bb

  • 输出重复行

    通过参数-D输出demo.txt文件中所有重复的行,如下:

    cat demo.txt | sort |uniq -D

    通过参数-d输出重复过的行(重复的只输出一次),-c来输出对应的重复次数,如下:

    cat demo.txt | sort |uniq -dc

12.简单的文本处理

12.1tr命令

该命令可以用来删除一段文本信息中的某些文字,或者将其进行转换。

tr option SET1 [SET2]

常用参数:

参数 说明
-d 删除和set1匹配的字符,注意不是全词匹配也不是按字符顺序匹配
-s 去除set1指定的在输入文本中连续并重复的字符

举例:

echo ‘hello world‘ | tr -d ‘word‘ 删除‘hello world’中所有的‘w’,‘o’,‘r’,‘d’

echo ‘hello world‘ | tr -s ‘l‘ 将‘hello’中的‘ll’,去重为一个‘l’

echo ‘hello world‘ | tr ‘[:lower:]‘ ‘[:upper:]‘ 将文本进行大小写转换,也可以简单的写作:

echo ‘hello world‘ | tr ‘[a-z]‘ ‘[A-Z]‘

12.2col命令

该命令可以将【Tab】换成对等数量的空格键,或反转这个操作。

col option

参数说明:

参数 说明
-x 将【Tab】转换为空格
-h 将空格转换为【Tab】(默认选项)

举例:

查看/etc/protocols中的不可见字符,可以看到很多 ^I ,这其实就是 【Tab】 转义成可见字符的符号

cat -A /etc/protocols

使用col -x/etc/protocols中的 Tab 转换为空格,然后再使用 cat 查看,你发现^I不见了

cat /etc/protocols | col -x | cat -A

12.3join命令

该命令就是用于将两个文件中包含相同内容的那一行合并在一起。

join option <file1 name> <file2 name>

参数说明:

参数 说明
-t 指定分隔符,默认为空格
-i 忽略大小写的差异
-1 指明第一个文件要用哪个字段来对比,默认对比第一个字段
-2 指明第二个文件要用哪个字段来对比,默认对比第一个字段

举例:

join -t ‘:‘ -1 1 file1 -2 2 file2 将file1和file2两个文件合并,指定以:为分隔符,分别对比第一个字段和第二个字段

12.4paste命令

该命令与join命令类似,它是在不对比数据的情况下,简单的将多个文件合并在一起,用【Tab】隔开。

paste option file...

参数说明:

参数 说明
-d 指定合并的分隔符,默认为【Tab】
-s 不合并到一行,每个文件为一行

举例:

echo ‘hello‘>file1

echo ‘world‘>file2

paste -d ‘:‘ file1 file2

paste -s file1 file2

13.数据流重定向

大多数UNIX系统命令从你的终端接受输入并将所产生的输出发送回到你的终端。一个命令通常从一个标准输入的地方读取输入,默认情况下,这恰好是你的终端。

13.1简单的重定向

Linux默认提供了三个特殊设备,用于终端的显示和输出。

文件描述符 设备文件 说明
0 /dev/stdin 标准输入,对应于你在终端的输入
1 /dev/stdout 标准输出,对应于终端的输出
2 /dev/stderr 标准错误输出,对应于终端的输出

注意:文件描述符在形式上是一个非负整数,实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX\Linux这样的操作系统。

重定向命令列表如下:

命令 说明
command > file 将输出重定向到file
command < file 将输入重定向到file
command >> file 将输出以追加的方式重定向到file
n > file 将文件描述符为n的文件重定向到file
n >> file 将文件描述符为n的文件以追加的方式重定向到file
n >& m 将输出文件mn合并
n <& m 将输入文件mn合并
<<tag 将开始标记tag和结束标记tag之间的内容作为输入

举例:

【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

注意:这里使用cat的连续输出(heredoc方式)重定向到一个文件。

注意:管道默认是连接前一个命令的输出到下一个命令的输入,重定向通常是需要一个文件来建立两个命令的连接。

13.2标准错误重定向

标准错误重定向:标准输出和标准错误都被指向伪终端的屏幕显示,所以我们经常看到的一个命令的输出通常是同时包含了标准输出和标准错误的结果的。

有时候我们要隐藏某些错误和警告,需要用到文件描述符:

echo ‘hello‘ > file1 创建文件file1

cat file1 file2 > file3 将file1和file2的文件内容重定向到file3,实际上并不存在file2

终端会输出标准错误:

cat: file2: 没有那个文件或目录

将标准错误重定向到标准输出,再将标准输出重定向到文件,注意要将重定向到文件写到前面:

cat file1 file2 > file3 2>&1

或只用bash提供的特殊的重定向符号"&"将标准错误和标准输出同时重定向到文件:

cat file1 file2 &> file3

注意:输出重定向文件描述符前面加上&,否则shell会当做重定向到一个文件名为1的文件中。

13.3使用tee命令同时重定向到多个文件

该命令可以将输出重定向到文件,也可以将信息打印在终端:

echo ‘hello world‘ | tee file

13.4永久重定向

从前面的重定向操作可以看出,这些重定向都是临时性的,只对当前命令有效。如果在一个脚本中,需要一部分的命令的输出全部重定向,这时就用到exec命令。

exec命令实现永久重定向,该命令的作用是使用指定的命令替换当前的Shell,即使用一个进程替换当前进程,或者指定新的重定向。

zsh 先开启一个子Shell

exec 1>file 使用exec替换当前进程的重定向,将标准输出重定向到一个文件

ll 该部分为要将输出重定向的命令如:llcat

exit 退出子Shell

13.5创建输出文件描述符

在Shell中有9个文件描述符,上面使用了它默认提供的0,1,2号文件描述符。另外我们还可以使用3-8的文件描述符,只是它们默认没有打开而已。可以使用以下命令查看当前Shell进程中打开的文件描述符:

cd /dev/fd/;ls -Al

使用exec命令可以创建新的文件描述符:

zsh

exec 3>file

cd /dev/fd/;ll;cd - 查看文件描述符3是否打开

echo ‘hello world‘ >&3

exit

使用如下命令,可以关闭打开的文件描述符:

exec 3>&-

13.6完全屏蔽命令的输出

在Linux中,有一个被称为黑洞的设备文件,所有导入它的数据都将被吞噬。

/dev/null,或称空设备,特殊的设备文件,通常用于丢弃不需要的输出流,或作为用于输入流的空文件,这些操作通常由重定向完成。读取它则会立即得到一个EOF。

使用该设备屏蔽命令的输出:

cat file > /dev/null 2>&1

13.7使用xargs分割参数列表

该命令是一条UNIX和类UNIX操作系统的常用命令。是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

  • 可以将管道或标准输入数据转换成命令行参数,也能够从文件的输出中读取数据。

  • 可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行

  • 默认的命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。

之所以用到这个命令,关键是因为很多命令不支持管道传递参数,而日常工作中有这个必要,所以就有了xargs命令。

语法格式:

somecommand | xargs -item command

常见参数说明:

参数 说明
-a 从文件中读入作为stdin
-e flag 有时候会是-Eflag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止
-p 每当执行一个argument的时候询问一次用户
-n num 后面加次数,表示命令在执行一次用的argument的个数,默认是用所有的
-l num/-L num 从标准输入一次读取num行送给command命令
-d 默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符

举例:

cut -d ‘:‘ -f 1 /etc/passwd | sort | xargs -n 3

14.正则表达式

//TODO 正则表达式

15.Linux下软件安装

通常Linux上的软件安装主要有四种方式:

  • 在线安装
  • 从磁盘安装deb软件包
  • 从二进制软件包安装
  • 从源代码编译安装

这几种安装方式各有优劣,而大多数软件包会采用多种方式发布软件,所以我们常常需要全部掌握这几种软件安装方式,以便适应各种环境。

15.1apt包管理工具介绍

APT是Advance Packaging Tool(高级包装工具)的缩写,是Debian及其派生发行版的软件包管理器。APT可以自动下载、配置、安装二进制或源代码格式的软件包。因此简化了Unix系统上管理软件的过程。APT最早被设计成dpkg的前端,用来处理deb格式的软件包。现在经过APT-RPM组织修改,APT已经可以安装在支持RPM的系统管理RPM包。这个包管理器包含以apt-开头的多个工具,如apt-get apt-cache apt-cdrom等,在Debian系列的发行版中使用。

当你在执行安装操作时,首先apt-get工具会在本地的一个数据库中搜索关于该软件的相关信息,并根据这些信息在相关的服务器上下载软件安装。

这里在本地的数据库中检索,是因为我们需要定期从软件源镜像服务器上下载一个软件包列表,使用sudo apt-get update命令来保持本地的软件包列表时最新的(当然有时也需要手动执行该操作),而这个表里会有软件依赖信息的记录,我们在安装一个软件的时候,可以将其所需要的其他软件包一并下载安装。

15.2apt-get

apt-get是用于处理apt包的公用程序集,我们可以用它来在线安装、卸载和升级软件包等,下面列出一个apt-get包含的常用的一些工具:

工具 说明
install 其后加上软件包名,用于安装一个软件包
update 从软件源镜像服务器上下载/更新用于更新本地软件源的软件包列表
upgrade 升级本地可更新的全部软件包,但存在依赖问题时将不会升级,通常会在更新之前执行一次update
dist-upgrade 解决依赖关系并升级(存在一定危险性)
remove 移除已安装的软件包,包括与被移除软件包有依赖关系的软件包,但不包含软件包的配置文件
autoremove 移除之前被其他软件包依赖,但现在不再被使用的软件包
purge remove相同,但会完全移除软件包,包含其配置文件
clean 移除下载到本地的已经安装的软件包,默认保存在/var/cache/apt/archives
autoclean 移除已安装的软件的旧版本软件包

下面是一些apt-get常用的参数:

参数 说明
-y 自动回应是否安装软件包的选项,在一些自动化安装脚本中使用这个参数将十分有用
-s 模拟安装
-q 静默安装方式,指定多个q或者-q=##表示数字,用于设定静默级别,防止安装软件包时屏幕输出过多
-f 修复损坏的依赖关系
-d 只下载不安装
--reinstall 重新安装已经安装但可能存在问题的软件包
--install-suggests 同时安装APT给出的建议安装的软件包
  • 安装软件包

    普通软件安装:

    sudo apt-get install <packagename>

    重新安装软件包(比如系统被破坏,或者一些错误的配置导致软件无法正常工作):

    sudo apt-get --reinsyall install <packagename>

    若不知道软件包完整名的时候,通常使用【Tab】键补全软件包名。

    若需要同时安装多个软件包,可以使用正则表达式匹配软件包名进行批量安装。

  • 软件升级

    sudo apt-get update 更换软件源

    sudo apt-get upgrade 升级没有依赖问题的软件包

    sudo apt-get dist-upgrade 升级并解决依赖关系

  • 卸载软件

    普通卸载:

    sudo apt-get remove <packagename>

    若不保留配置文件且移除不再需要依赖的软件包:

    sudo apt-get --purge remove <packagename>

    sudo apt-get autoremove

  • 软件搜索

    当你知道了一个软件,想下载使用,需要确认软件仓库里有没有,需要用到搜索功能:

    sudo apt-cache search sortname

更多关于APT的内容,可以参考:APT HowTo

15.3使用dpkg

dpkg是Debian Package的简写,是Debian软件包管理的基础,它被伊恩·默多克创建于1993年。dpkg与RPM十分相似,同样被用于安装、卸载和供给和.deb软件包相关的信息。

dpkg本身是一个底层的工具。上层的工具,像是APT,被用于从远程获取软件包以及处理复杂的软件包关系。

dpkg常用参数:

参数 说明
-i 安装指定deb包
-R 后面加上目录名,用于安装该目录下的所有deb安装包
-r remove,移除某个已安装的软件包
-I 显示deb包文件的信息
-s 显示已安装软件的信息
-S 搜索已安装的软件包
-L 显示已安装软件包的目录信息

举例:

假设需要使用dpkg安装emacs,先使用apt-get加上参数-d只下载不安装:

sudo apt-get update

sudo apt-get -d install -y emacs

下载完成后,进入/var/cache/apt/archives目录,将第一个文件,即emacs24_24.5+1-6ubuntu1.1_amd64.deb文件拷贝至/usr/local/src下,使用dpkg加参数-I查看包信息,使用参数-i进行安装。

sudo cp /var/cache/apt/archives/emacs24_24.5+1-6ubuntu1.1_amd64.deb /usr/local/src/

sudo dpkg -I emacs24_24.5+1-6ubuntu1.1_amd64.deb

sudo dpkg -i emacs24_24.5+1-6ubuntu1.1_amd64.deb

此时会发现依赖关系问题,无法继续安装。【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

此时使用apt-get-f参数,解决依赖关系的安装:

sudo apt-get -f install -y

就可以安装成功,使用命令emacs24即可运行程序。

15.4从二进制包安装

二进制包的安装比较简单,我们需要做的只是将从网络上下载的二进制包解压后放到合适的目录,然后将包含可执行的主程序文件的目录添加进PATH环境变量即可。

【Linux】Linux学习之命令执行顺序控制与管道、简单的文本处理、数据流定向、Linux下软件安装

上一篇:Linux非root用户mialx发送邮件,报错:Error initializing NSS: Unknown error -8015.报错解决


下一篇:Linux开机启动脚本