「Linux 奏章 2」使用 Shell 命令行

916 阅读7分钟

1. 认识 Linux Shell

Shell 是实现人机交互的一个程序,是操作系统的用户界面,它提供了用户与内核交互的接口。

从本质上说,Shell 是一个命令解释器,用户可以通过 Shell 向内核提交想要执行的命令,也可以进行 Shell 脚本(Shell Script)编程。Linux 系统中所有的可执行文件都可以作为 Shell 命令使用。常见的 Shell 命令包括 Shell 内部命令二进制形式的可执行程序以及 Shell 脚本

  • Shell 内部命令为 Shell 程序内置的功能,如 cdechosettypeletumask 命令就是 Bash Shell 的内部命令。
  • 二进制形式的可执行程序包括基础 Linux 命令(如 /bin/sbin 目录下的)、Linux 工具软件、自由软件(如 /usr/bin/usr/sbin/usr/local/bin 等目录下的实用程序)、用户自己编写的 C 语言程序编译链接后生成的可执行程序。
  • Shell 脚本是按照 Shell 的语法配合 Linux 系统中的可用的 Shell 命令(包括内部命令、二进制形式可执行程序、Shell 脚本)编写的能完成复杂任务、实现更复杂功能的 Shell 脚本。

更多:c.biancheng.net/view/706.ht…

1.1 Shell 种类

  • Bourne Shell
  • BASH:是 GNU/Linux 操作系统上默认的 Shell.
  • Korn Shell
  • C Shell
  • ...

1.2 Shell 功能

  • 历史命令记忆: history

  • Tab 键补全

  • 文件名通配

    符号含义例子
    *匹配 0 个或多个字符a*b:a 与 b 之间可以由任意长度的任意字符,也可以一个都没有,如 aabcb、axyzb、a012b、ab
    ?匹配任意一个字符a?b:a 与 b 之间必须也只能有一个字符,可以是任意字符,如 aab、abb、acb
    [list]匹配 list 中的任意单一字符a[xyz]b:a 与 b 之间必须也只能有一个字符,但只能是 x 或 y 或 z,即 axb、ayb、azb
    [c1-c2]匹配 c1 - c2 中的任意单一字符形如:[0-9][a-z]a[0-9]b
    [!list]匹配除 list 中的任意单一字符a[!0-9]b:a 与 b 之间必须也只能有一个字符,但不能是阿拉伯数字
    {string1, string2, ...}匹配 string1 或 string2(或更多)其一字符串形如 a{abc,xyz,123}b 代表只能是 aabcb、axyzb、a123b 三个字符串之一

    举例:ls *.confls a*ls [ab]*ls [ab]?ls[1-9][a-z]?

  • 命令别名 alias

    # 演示 alias 命令的使用!
    
    [root@localhost etc]# type cp
    cp is aliased to `cp -i'
    [root@localhost etc]# type ll
    ll is aliased to `ls -l --color=auto'
    [root@localhost etc]# type ls
    ls is aliased to `ls --color=auto'
    [root@localhost etc]# alias
    alias cp='cp -i'
    alias egrep='egrep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias grep='grep --color=auto'
    alias l.='ls -d .* --color=auto'
    alias ll='ls -l --color=auto'
    alias ls='ls --color=auto'
    alias mv='mv -i'
    alias rm='rm -i'
    alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
    [root@localhost etc]# type lls
    bash: type: lls: not found
    [root@localhost etc]# alias lld="ls -ld"
    [root@localhost etc]# lld /etc
    drwxr-xr-x. 139 root root 8192 Oct 16 01:26 /etc
    [root@localhost etc]# type lld
    lld is aliased to `ls -ld'
    [root@localhost etc]# 
    

1.3 同时运行多条 Shell 命令

在某些情况下,如果想一次性输入多条命令提交给 Shell 去执行,而不是依次输入一条执行一条,该如何解决这个问题呢?

Ⅰ可以考虑把多条命令编写进 Shell 脚本,脚本的编写可以参考下文章节中关于 Shell 脚本编程的部分。

Ⅱ或者使用分号(;)执行连续命令的功能,在 Shell 提示符下输入多条 Shell 命令,并在命令与命令之间使用分号,其格式:

[root@localhost ~]# command1;command2;command3

例如:

[root@localhost /]# cd /wu-yikun;mkdir /wu-yikun/tmp/;cd /wu-yikun/tmp/;touch /wu-yikun/tmp/file.txt;ll

这是一个连续执行 5 条 Shell 命令的例子。这种形式执行多条命令时,没有考虑到命令的相关性:连续执行多条命令,不管前面的命令是否成功执行,后续的命令都会执行。

而在一些情况下,连续执行的多条命令间有一定的相关性:前一条命令是否成功执行会影响到是否要继续执行后一条命令。在该例中,如果 /wu-yikun 目录不存在,后续建立目录、建立文件的命令就会执行错误!

⭐如果要考虑前后两条 Shell 命令间的相关性,前一条 Shell 命令是否成功执行与后一条 Shell 命令是否要继续执行有关,这时就可以使用 &&||,其规则如下:

# 如下命令表示当 command1 正确执行时,command2 继续执行;若 command1 执行错误,command2 不执行!
$ command1 && command2

# 如下命令表示当 command1 正确执行时,command2 不执行;若 command1 执行错误,则 command2 执行!
$ command1 || command2

1.4 Shell 变量

Shell 是用户访问 Linux 内核的接口,变量是 Bash Shell 是非常重要的一个特性。为了增加 Shell 命令的灵活性,以及方便用户编写 Shell Script 脚本,增加脚本的灵活性与可扩展性,并使 Shell 脚本编程更有效,Bash Shell 提供了 Shell 变量供用户使用。Shell 变量可以用于保存临时信息,保存诸如路径名、文件名或者一个数字。

⭐有三种类型的 Shell 变量:

  • 系统变量:用于对 Shell 命令执行过程中的参数判断与 Shell 命令执行结果的返回值判断,系统变量以 $ 符号开头
    • $$ 表示当前进程的 PID
    • $? 表示前一个命令或函数的返回值:0 表示成功执行,非0 表示不成功(可为同时运行多条命令提供便利)
  • 环境变量:主要用于对 Shell 环境的设置,通常用大写字符表示(区分自定义变量)
  • 用户自定义变量:用于交互式 Shell 命令,以及编写 Shell 脚本时常用

变量的定义与引用:

# 格式!
$ <变量名>=<字符串>

# 演示!
[root@localhost tmp]# name=wyk
[root@localhost tmp]# hello="Hello Linux"
[root@localhost tmp]# echo $name
wyk
[root@localhost tmp]# echo $hello
Hello Linux
[root@localhost tmp]# echo $HOME
/root
[root@localhost tmp]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin

2. Shell 命令替换

在 Bash Shell 中反引号`属于特殊符号,作为命令替换(若反引号括起来的字符串是可运行的 Shell 命令,Shell 会先运行反引号里的 Shell 命令,然后将运行结果替换重组到当前的 Shell 命令中)使用!

实践出真知

[root@localhost tmp]# date +%Y-%m-%d
2021-10-16
[root@localhost tmp]# today="today is date +%Y-%m-%d"
[root@localhost tmp]# echo today
today
[root@localhost tmp]# echo $today
today is date +%Y-%m-%d
[root@localhost tmp]# today="today is `date +%Y-%m-%d`"
[root@localhost tmp]# echo $today
today is 2021-10-16

3. Shell 输入/输出重定向与管道

每条 Shell 命令对应的进程都有三个与之相关的输入/输出流:

  • 标准输入 stdin:进程获得用户从键盘输入的数据
  • 标准输出 stdout:命令执行完毕后传回的正确信息
  • 标准错误输出 stderr命令执行失败后传回的错误信息

3.1 输入重定向

输入重定向:输入可以不来自于键盘,而来自于指定文件。

输入重定向的一般形式:

$ 命令<文件名

例1

[root@localhost tmp]# wc file.txt
 1  2 20 file.txt
[root@localhost tmp]# wc<file.txt 
 1  2 20
[root@localhost tmp]# cat file.txt 
insert something...
[root@localhost tmp]# cat<file.txt 
insert something...

例2:演示一个标准的 Document 输入重定向,可以打印多行文本

由于大多数命令都以参数的形式在命令行上指定输入文件的文件名,所以输入重定向功能并不经常使用!

尽管如此,当要使用一个不接受文件名作为输入参数的命令,而需要的输入内容又存在于一个文件里的时候,就能使用输入重定向解决问题:如在编写 Shell 脚本时,当要处理来自文件的数据时,就经常使用到输入重定向功能。

3.2 输出重定向

输出重定向:'>' 把 stdout 重定向到文件,而非屏幕输出

输出重定向的一般形式:

$ 命令>文件名

⭐由于 stdoutstderr 都是从屏幕输出,因此按以下方式区分这两类输出流:

  • stdout: ">""1>"
  • stderr: "2>"

⭐而每一类输出流的输出方式又分为两类:

  • 覆盖指定文件:>
  • 追加到指定文件末尾:>>

⭐注:&>\ 可以将标准输出流和标准错误输出流同时输出到同一个文件中!


接下来就是演示环节:

stdoutstderr

&>

>>

3.3 管道

区分:
管道:命令与命令
输入/输出重定向:命令与文件

⭐当需要将一个 Shell 命令的输出结果传递给另一个 Shell 命令作为输入时,可以使用 Linux Shell 提供的管道功能(命令与命令),不同于输入重定向 & 输出重定向(文件与命令)。

⭐管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是带管道功能命令行中最后一个命令的输出。

注意:stderr 并没有传给下一个命令的输入。

通过使用管道符 “ | ” 来建立个多条 Shell 命令联合执行的命令。通常配合管道使用的有许多 Linux 的命令,如 echowc 以及 cutgrepsortuniq 等过滤命令。


例1:统计当前登录系统的用户个数

[root@localhost tmp]# who
root     :0           2021-10-16 20:50 (:0)
root     pts/0        2021-10-16 20:50 (:0)
[root@localhost tmp]# who | wc -l
2

例2

例3

4. 小结⭐

希望本文对你有所帮助🧠
欢迎在评论区留下你的看法🌊,我们一起讨论与分享🔥