什么是Shell?
• shell是用C语言编写的一种(外壳)程序,既是一种命令语言,也是一种程序设计语言;
• shell是用户与Linux操作系统之间的接口;是用户与内核的交互;
• shell解释用户输入的命令,并且传递给内核,然后内核操作之后,将结果传递给shell,返回给用户;

交互式shell与非交互式shell:
• 交互式shell:操作过程中,用户需要和内核进行交互;
• 非交互shell:shell脚本,通过自动化/批处理的方式完成操作;

Shell的用途:
设计shell的目的不仅仅是用于人机交互,对shell脚本(包含shell命令的文本文件)
进行解释也是其中用途之一。为实现这一目的,每款shell都内置有许多通常与编
程语言相关的功能,其中包括变量、循环和条件语句、I/O命令以及函数等。

Shell的分类:

Bourne shell(简称为sh): 第一个shell,/usr/bin/sh或/bin/sh
Bourne Again Shell(简称为bash): 这是对Bourne shell的增强版本,/bin/bash或/usr/bin/bash
 C shell(简称为csh): 由于语法和C语言类似而得名,/usr/bin/csh
Tenex C shell(简称tcsh): 是C shell的增强版本,/usr/bin/tcsh
 Korn Shell(简称ksh): 是Bourne shell 的超集(superset),比C shell 更为先进,/usr/bin/ksh
Shell for Root(/sbin/sh): 缺省的root shell
[root@cloudos ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
[root@cloudos ~]# bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

变量的设置与引用
变量就是可以存放数据的标识符。

  1. 变量的设置/赋值
    varname=test //"="等号左右不能出现空格,因为,空格在shell当中,表示命令的分割
    case_counts=1000 //设置变量的名称问题,别给自己找麻烦,最好就是字母开头,后面跟上字母或者数字
  2. 变量的引用
    直接引用:$varname或者${varname}
    间接引用:echo ${!a} 或 eval echo \$${a}
  3. 变量的作用域
    就是变量值的作用范围,具体说就是在那些地方可以被引用
    两种类型的变量:
    环境变量:可以在任何终端被引用;也叫全局变量
    env
    env | wc –l
    本地变量:仅限于当前shell终端引用,也叫局部变量
    本地变量如何升级为全局变量?
[root@cloudos ~]# env | grep ^a
[root@cloudos ~]#
[root@cloudos ~]#
[root@cloudos ~]# env | grep ^a
[root@cloudos ~]# a=1
[root@cloudos ~]# export a
[root@cloudos ~]# env | grep ^a
a=1

注:此环境变量,作用域限于当前shell和当前shell派生的子shell

如何生成一个所有终端都能读取的环境变量?
以下四个文件任何一个写export a=1,
在新终端source,然后env查看
/etc/profile
/etc/bashrc
~/.bash_profile
~/.bashrc

  1. 定义变量类型:
    declare:用于声明shell 变量
    参数:
    [+/-] "-“可用来指定变量的属性,”+"则是取消变量所设的属性。
    [ -f ] 仅显示函数。
    [ -r ] 将变量设置为只读。
    [ -x ] 指定的变量会成为环境(全局)变量,可供shell以外的程序来使用。
    [ -i ] "设置值"可以是整数,字符串或运算式,“重点”
[root@cloudos ~]# a=4
[root@cloudos ~]# b=5
[root@cloudos ~]# c=$a*$b
[root@cloudos ~]# echo $c
4*5
[root@cloudos ~]# declare -i a=4
[root@cloudos ~]# declare -i b=5
[root@cloudos ~]# declare -i c=$a*$b
[root@cloudos ~]# echo $c
20
  1. 读取变量值:
    read格式:
    read 变量名
    read -p “提示信息…” 变量名
    read -t 时间(单位秒数) 变量名字
    read -p “提示信息…” -t 输入过期时间变量名
    read 变量1 变量2 ……
    read 如果后面没有指定一个变量名,输入的变量值会直接赋予内置变量REPLY,相当于写: read REPLY
    PS:开头的#! 是对脚本的解释器程序路径
  2. Shell的位置变量:
$0: 脚本的名称
	$1: 脚本的第一个参数,$2表示第二个参数,$n 表示第n个参数。
	$#: 脚本参数的个数
	$@: 脚本所有参数列表
	$*: 脚本所有参数列表,只有在被""引起来的时候,与$@才有区别
	$$: 表示当前进程的pid
	$!: 显示最后一个进入后台运行的进程pid
	$?: 表示上一条命令的执行结果,如果返回0=成功;如果返回非0=失败;**
	$-: 判断命令环境是否是交互式的,如果返回值里包含"i",说明是交互式;
	$_: 表示上一条命令的最后一个参数

shell的文本显示
echo :显示输出文本行内容,用于交互式或者脚本的输出显示
-e : 支持转义字符的功能含义
-n : 不换行输出

引用符

名称

说明

‘’

单引号

称全引用或强引用,引用所有的字符,相当于单引号内所有内容,无论常量还是变量都原样输出

“”

双引号

称部分引用或弱引用,双引号内部的变量,会被取值。引用除美元符号$、反引号` 和反斜线\之外的所有字符

``

反引号

反引号shell 把反引符中的内容解释为系统命令优先执行,其输出被放入主命令后,再被执行

\

反斜杠

反斜杠转义符,屏蔽下一个字符的特殊意义

[root@cloudos ~]# echo "hello world\nthis is a test! "
hello world\nthis is a test!
[root@cloudos ~]# echo -e "hello world\nthis is a test! "
hello world
this is a test!
[root@cloudos ~]# echo -n "hello world! "
hello world! [root@cloudos ~]#
[root@cloudos ~]# var=zhangsan
[root@cloudos ~]# echo "hello $var"
hello zhangsan
[root@cloudos ~]# echo 'hello $var'
hello $var
[root@cloudos ~]# echo hello `echo $var`
hello zhangsan
[root@cloudos ~]#

反引号``与$()的应用举例

$(command) 与`command` 效果是一样的,都是将$()或者``中命令输出的结果赋值给一个变量
$() 相对更直观一些

[root@cloudos ~]# date
Mon Nov 16 22:23:33 CST 2020
[root@cloudos ~]# echo date
date
[root@cloudos ~]# echo `date`
Mon Nov 16 22:23:58 CST 2020
[root@cloudos ~]# echo $(date)
Mon Nov 16 22:24:07 CST 2020
[root@cloudos ~]#

Shell 的通配符
Shell的通配符是由shell处理的, 它只会出现在命令的“参数”里。shell会将其当作路径或文件名去搜寻可能的匹配,实际上就是一种shell实现的路径扩展功能。

Shell的常见通配符:

\* 		表示匹配零个或多个字符
? 		表示匹配单个字符
\ 		转义字符,将特殊字符还原成一般字符
& 		程序的后台运行./run.sh &
; 		表示命令的分割符,用于执行连续命令
() 		命令组的概念
[abc] 	表示中括号中的任意一个字符,a ,b ,c 任意一个
[!abc] 	表示取反,除了a,b,c之外的任意一个字符
[^a-c] 	逻辑非,非a到c之外的任意一个字符
root@bras-01:/tmp# ll
total 10
drwxrwxrwt  8 root root 4096 Nov 15 23:23 ./
drwxr-xr-x 24 root root 4096 Jun 10 21:14 ../
-rw-r--r--  1 root root    0 Nov 15 23:23 a1
-rw-r--r--  1 root root    0 Nov 15 23:23 a2
-rw-r--r--  1 root root    0 Nov 15 23:28 a12
-rw-r--r--  1 root root    0 Nov 15 23:28 a13
-rw-r--r--  1 root root    0 Nov 15 23:23 b1
-rw-r--r--  1 root root    0 Nov 15 23:23 b2
-rw-r--r--  1 root root    0 Nov 15 23:23 c1
-rw-r--r--  1 root root    0 Nov 15 23:23 c2
-rw-r--r--  1 root root    0 Nov 15 23:23 d1
-rw-r--r--  1 root root    0 Nov 15 23:23 d2
root@bras-01:/tmp# ll a?
-rw-r--r-- 1 root root 0 Nov 15 23:23 a1
-rw-r--r-- 1 root root 0 Nov 15 23:23 a2
root@bras-01:/tmp# ll a*
-rw-r--r-- 1 root root 0 Nov 15 23:23 a1
-rw-r--r-- 1 root root 0 Nov 15 23:28 a12
-rw-r--r-- 1 root root 0 Nov 15 23:28 a13
-rw-r--r-- 1 root root 0 Nov 15 23:23 a2
root@bras-01:/tmp# ll [a]2
-rw-r--r-- 1 root root 0 Nov 15 23:23 a2
root@bras-01:/tmp# ll [!a]2
-rw-r--r-- 1 root root 0 Nov 15 23:23 b2
-rw-r--r-- 1 root root 0 Nov 15 23:23 c2
-rw-r--r-- 1 root root 0 Nov 15 23:23 d2
root@bras-01:/tmp# ll [^a-c]2
-rw-r--r-- 1 root root 0 Nov 15 23:23 d2
root@bras-01:/tmp# ll [^a-b]2
-rw-r--r-- 1 root root 0 Nov 15 23:23 c2
-rw-r--r-- 1 root root 0 Nov 15 23:23 d2

Shell 的命令结果重定向
1.“2>&1”,将标准错误输出绑定到标准正确输出上。由于此时的标准正确输出是默认值,也就是重定向到屏幕上,所以此时标准错误输出会重定向到屏幕上。
2.“>/dev/null”,将标准正确输出1重定向到/dev/null(黑洞),相当于不输出任何信息。

命令

标准正确输出

标准错误输出

>/dev/null 2>&1

丢弃

丢弃

2>&1 >/dev/null

丢弃

屏幕

root@bras-01:/tmp# cp a1
cp: missing destination file operand after 'a1'
Try 'cp --help' for more information.
root@bras-01:/tmp# cp a1 /root >/dev/null 2>&1
root@bras-01:/tmp# cp a1 >/dev/null 2>&1
root@bras-01:/tmp# cp a1 /root 2>&1 >/dev/null
root@bras-01:/tmp# cp a1 2>&1 >/dev/null
cp: missing destination file operand after 'a1'
Try 'cp --help' for more information.
root@bras-01:/tmp#