Shell脚本简介
Shell脚本是什么?(windows上面有相似类型的文件,一般称为批文件)
-
shell命令按一定语法组成的程序文件
Shell脚本有什么用?
批处理文件/整合命令
-
软件启动
-
性能监控
-
日志分析
...
Shell命令的本质(type命令查看)
内置命令(在启动时已经加载到内存里了,不需要重新从硬盘内加载出来)
gec@ubuntu:~$ type cd
cd 是 shell 内建
gec@ubuntu:~$ type pwd
pwd 是 shell 内建
外部命令(由其他外部程序实现)
gec@ubuntu:~$ type ifconfig
ifconfig 是 /sbin/ifconfig
ifconfig对应着一个外部的应用程序,这里实际上就是对应 /sbin下的ifconfig程序,一个应用程序成为了
在需要执行Shell命令时,设置了一个PATH的环境变量,这个path的环境变量就记录了这个外部命令所对应的一个应用程序所在的目录,通过下面的这个命令可以把当前的PATH打印出来
gec@ubuntu:~$ echo $PATH
/home/gec/bin:/home/gec/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/arm/5.4.0/usr/bin
当输入指令时,会先到内存里匹配内置命令,找不到的话shell会到这些目录下去逐个逐个寻找对应的一个应用程序,如果找到了,就会开创一个新的进程,然后在进程里执行这个新的应用程序。
举例:
gec@ubuntu:~$ sudo vi hello.c
gec@ubuntu:~$ gcc hello.c -o hello
gec@ubuntu:~$ ./hello
hello world
gec@ubuntu:~$ echo $PATH
/home/gec/bin:/home/gec/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/arm/5.4.0/usr/bin
gec@ubuntu:~$ sudo mv hello /usr/bin/
gec@ubuntu:~$ hello
hello world
通过使用GCC编译hello.c
文件并将生成的可执行文件hello
移动到了/usr/bin/
目录下,这个目录在系统的环境变量$PATH
中,此时hello成为了类似ifconfig的外部命令
hello.c
#include <stdio.h>
int main()
{
printf("hello world\r\n");
return 0;
}
应用程序变成了shell的外部命令
编译型语言
Shell脚本语言和C语言一样吗?
-
编译型 vs 解释型:C语言是一种编译型语言,需要通过编译器将源代码转换为机器码,然后再执行生成的可执行文件。而Shell脚本语言是一种解释型语言,它逐行解释执行脚本,不需要编译生成可执行文件。
-
语言用途:C语言通常用于系统级编程和底层开发,可以直接操作内存和硬件资源,因此更适合开发性能要求高且对硬件控制要求较多的应用程序。而Shell脚本语言主要用于自动化任务、系统管理和脚本编程,更适合处理文件操作、运行系统命令以及编写简单的脚本。
-
语法特点:C语言具有较为严格的语法规则,包括强类型变量声明、复杂的控制结构和指针等概念。而Shell脚本语言的语法相对简单灵活,支持直接调用系统命令和利用管道进行数据处理。
常用的Shell解释器有哪些?
gec@ubuntu:~$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
gec@ubuntu:~$ ls /bin/*sh
/bin/bash /bin/dash /bin/rbash /bin/sh /bin/static-sh
第一个Shell脚本
helloworld
编辑、保存、改权限、运行/排错
gec@ubuntu:~$ sudo vi hello.sh
gec@ubuntu:~$ sudo chmod 777 hello.sh
gec@ubuntu:~$ sudo vi hello.sh
gec@ubuntu:~$ ./hello.sh
hello world
Shell启动方式
-
当程序执行
-
指定解释器运行
-
source和.
gec@ubuntu:~$ ./hello.sh
hello world
gec@ubuntu:~$ /bin/bash hello.sh
hello world
gec@ubuntu:~$ source hello.sh
hello world
gec@ubuntu:~$ . hello.sh
hello world
Shell脚本语法讲解
定义变量
-
variable=value
适用于无空格符 -
variable='value'
不会解引用,会原封不动打印下来 -
variable="value"
会解引用gec@ubuntu:~$ sudo vi test.sh gec@ubuntu:~$ ./test.sh 123 5674aaa gec@ubuntu:~$ sudo vi test.sh gec@ubuntu:~$ ./test.sh ${var}aaa
使用变量
-
$variable
-
${variable}
-
1 #! /bin/bash 2 3 var="123 5674" 4 var1='${var}aaa' 5 echo "$var1"
不要忘记变量的{}来饮用变量值
将命令的结果赋值给变量
-
variable=`command`
-
variable=$(command)
这两种都可以把命令的结果赋给左边的变量
删除变量
unset
#! /bin/bash
var="123 5674"
var1='${var}aaa'
unset var
echo "$var"
特殊变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名。 |
$n(n≥1) | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。当被双引号" " 包含时,$@ 与 $* 稍有不同. |
$? | 上个命令的退出状态或者获取函数返回值。 |
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
1 #! /bin/bash
2
3 var="123 5674"
4 var1='${var}aaa'
5
6 unset var
7 echo "$var"
8 echo "$0"
9 echo "$1"
10 echo "$2"
11 echo "$#"
12 echo "$*"
13 echo "$$"
14
15
16
17 exit 123
~
gec@ubuntu:~$ ./test.sh 10 11 13 14
./test.sh
10
11
4
10 11 13 14
10870
字符串拼接
并排放
读取从键盘输入的数据
read有点类似scanf
1 #! /bin/bash
2
3
4 read -p "input a:" a
5 read -p "input b:" b
6 var="123 5674"
7 var1='${var}aaa'
8
9 #unset var
10 #echo "$var"
11 #echo "$0"
12 #echo "$1"
13 #echo "$2"
14 #echo "$#"
15 echo "$*"
16 #echo "$$"
17
18 echo "${a}"
19 echo "${b}"
20
21
22
23 exit 123
~
结果
gec@ubuntu:~$ ./test.sh
input a:111
input b:222
111
222
退出当前进程
exit
对整数进行数学运算
(())
逻辑与/或
command1 && command2
command1 || command2
&&时,前面为假后面不执行;||时前一个为真后一个不执行
检测某个条件是否成立
test expression和[ expression ]
选 项 | 作 用 |
---|---|
-eq | 判断数值是否相等 |
-ne | 判断数值是否不相等 |
-gt | 判断数值是否大于 |
-lt | 判断数值是否小于 |
-ge | 判断数值是否大于等于 |
-le | 判断数值是否小于到等于 |
-z str | 判断字符串 str 是否为空 |
-n str | 判断字符串str是否为非空 |
=和== | 判断字符串str是否相等 |
-d filename | 判断文件是否存在,并且是否为目录文件。 |
-f filename | 判断文件是否存在,井且是否为普通文件。 |
管道
command1 | command2
if语句
if condition then statement(s) fi
if else 语句
if condition then statement1 else statement2 fi
if elif else 语句
if condition1 then statement1 elif condition2 then statement2
…… else statementn fi
case in语句
case expression in pattern1) statement1 ;; pattern2) statement2 ;; pattern3) statement3 ;; …… *) statementn esac
for in 循环
for variable in value_list do statements done
value_list
-
直接给出具体的值
-
给出一个取值范围
-
使用命令的执行结果
-
使用 Shell 通配符
-
使用特殊变量
while 循环
while condition do statements done
函数
function name() { statements [return value] }