【什么是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.
【变量的设置与引用】
变量就是可以存放数据的标识符。
- 变量的设置/赋值
varname=test //"="等号左右不能出现空格,因为,空格在shell当中,表示命令的分割
case_counts=1000 //设置变量的名称问题,别给自己找麻烦,最好就是字母开头,后面跟上字母或者数字 - 变量的引用
直接引用:$varname或者${varname}
间接引用:echo ${!a} 或 eval echo \$${a} - 变量的作用域
就是变量值的作用范围,具体说就是在那些地方可以被引用
两种类型的变量:
环境变量:可以在任何终端被引用;也叫全局变量
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
- 定义变量类型:
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
- 读取变量值:
read格式:
read 变量名
read -p “提示信息…” 变量名
read -t 时间(单位秒数) 变量名字
read -p “提示信息…” -t 输入过期时间变量名
read 变量1 变量2 ……
read 如果后面没有指定一个变量名,输入的变量值会直接赋予内置变量REPLY,相当于写: read REPLY
PS:开头的#! 是对脚本的解释器程序路径 - 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#