目录
概念:
shell脚本的本质:
shell脚本编程:
shell变量:
变量的定义格式:
变量的分类
自定义变量:
环境变量:
命令变量与命令行参数:
预定义变量:
shell中的语句
功能性语句
read(类似c当中 scanf)
expr
let
test
字符串测试
整数测试
文件属性测试
结构性语句
if...then...fi
基本结构
分层结构
嵌套结构
elif(多路分支结构)
case语句
for循环
for语句的几种书写格式
while循环
循环控制语句
数组
定义数组
获取数组
数组切片
gcc编译步骤
概念:
shell脚本的本质:
shell命令的有序集合
shell既是应用程序又是脚本语言,并且是解释型语言,不需要编译,解释一条执行一条。
shell脚本编程:
将shell命令结合一些按照一定逻辑集合到一起,写一个 .sh文件,实现一个或多个功能,这个脚本不用编译直接执行
创建shell脚本文件的步骤:
1. 创建一个脚本文件touch xxx.sh
2. 将脚本文件的权限修改为可执行chmod 777 xxx.sh
3. 编辑脚本内容vi xxx.sh
4. 执行脚本文件./xxx.sh 或 bash xxx.sh
练习:
1)在当前路径下创建file_1到file_5, 5个普通文件
2)删除 file_2和file_3文件(使用通配符)
3)将剩下的file文件用tar压缩成bz2的格式
4)将压缩文件复制到家目录下
5)进入到家目录解压压缩文件
6)删除压缩包
touch file_{1..5}
rm file_[23]
tar -cvjf file.tar.bz2 file_[^23]
cp file.tar.bz2 ~
cd ~
tar -xvf file.tar.bz2
rm file.tar.bz2
shell变量:
shell中允许建立变量存储数据,但是不支持数据类型
(如:整型、字符、浮点类型),所有赋值给变量的值都解释为一串字符
变量的定义格式:
变量名=值
注:等号两边不能有空格
取shell变量的值:$变量名
变量的分类
自定义变量:
YY=hello # YY="hello world"echo $YYXX=$YY ---> 将 YY 的值赋值给 XXecho $XXunset 变量名 ---> 取消该变量的值
环境变量:
系统配置好的、内置变量
使用命令查看系统环境变量: printenv或 env
export 变量名=值 临时终端有效
永久生效只需要将这个命令放到用户目录下 .bashrc 文件中,当前用户永久有效。
若放到 /etc/bash.bashrc 这个文件中所有用户永久有效
命令变量与命令行参数:
$0 执行的脚本名
$1-$9、${10}-${n} 命令行空格传的参数 n:第几个命令行参数
$# 命令行参数个数除 $0
$@$* 遍历输出命令行参数内容
预定义变量:
$? 获取的是上一个命令是否是正确的执行结果
0:真 非0:假
$$ 获取当前shell的进程 PID
shell中的语句
1) 说明性语句
以 #开始到该行结束,不被解释执行
#!/bin/bash告诉操作系统使用哪种类型的shell执行此脚本文件
2) 功能性语句
任意的shell命令、用户程序或其他的shell程序
3) 结构性语句
条件测试语句、多路分支语句、循环语句、循环控制语句
功能性语句
read(类似c当中 scanf)
从终端获取值赋值给变量
格式:read 变量名1 变量名2...
加提示语句:read-p"提示字符串"变量名1 变量名2 ...
注:把终端读入空格隔开的第一个单词赋值给第一个变量,第二个单词赋值给第二个变量,依次类推赋值,剩余所有单词赋值给最后一个变量。
expr
算术运算命令expr 主要用于进行简单的整数运算,包括(+)、减(-)、乘(*)、整除(/)、求模(%)等操作
注意:
1) 运算符左右两侧必须有空格
2) *和()必须加转义字符,\*、\( \)
3) expr语句可以直接输出运算结果
如:expr \( 12 + 3 \) \* 2
NUM=`expr \( 12 + 3 \) \* 2`:将运算结果赋值给变量
read -p "要输入的值" val1 val2 val3
expr \( $val1 + $val2 \) \* $val3
let
在运算中不能有空格
运算结果需要赋值给一个变量
变量参与运算的过程不用加 $ 取值
test
test 语句可以测试三种对象
字符串 整数 文件属性
字符串测试
s1 = s2 测试两个字符串的内容是否一样test "hello" = "world"echo $? # 1 相等为真,不相等为假s1 != s2 测试字符串的内容是否有差异test "hello" != "hello"echo $? # 1 相等为假,不相等为真-z s1 测试s1字符串长度是否为0test -z "" echo $? # 0 字符串长度为0test -z "hello"echo $? # 1 字符串长度不为0-n s1 测试s1字符串长度是否不为空 (空的时候为1,反之为0)test -n ""echo $? # 1 字符串长度为空,则为假test -n "hello"echo $? # 0 字符串有长度为真
整数测试
a -eq b 测试a和b是否相等的 # equalread A Btest $A -eq $Becho $? # 如果两个数相等则为真,反之为假a -ne b 测试 a 和 b是否不相等 # no equalread A Btest $A -ne $Becho $? # 如果两个数不相等则为真,反之为假a -gt b 测试 a 是否大于 b # greater thanread A Btest $A -gt $Becho $? # 如果a大于b则为真,反之为假a -ge b 测试 a 是否大于等于 b # greater equal thanread A Btest $A -ge $Becho $? # 如果a大于等b则为真,反之为假a -lt b 测试 a 是否小于 b # less thanread A Btest $A -lt $Becho $? # 如果a小于b则为真,反之为假a -le b 测试 a 是否小于等于 b # less eqaul thanread A Btest $A -le $Becho $? # 如果a小于等于b则为真,反之为假
文件属性测试
-d name 测试name是否为一个目录test -d 路径echo $? # 如果name是目录则为真,反之为假-f name 测试name是否为一个普通文件test -f 路径echo $? # 如果name是普通文件则为真,反之为假-e name 测试文件是否存在test -e 路径echo $? # 如果文件或目录存在则为真,反之为假
结构性语句
if...then...fi
基本结构
if 表达式
then命令表
fi
分层结构
if 表达式
then命令表1
else命令表2
fi
嵌套结构
if 表达式1
thenif 表达式2then命令表 2else命令表3fi
else命令表
fi
elif(多路分支结构)
if 表达式1
then命令表1
elif 表达式2
then命令表2
elif 表达式3
then命令表3
...
else表达式 n
fi注意:如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。 if和fi是条件语句的语句括号, 必须成对使用;命令表中的命令可以是一条, 也可以是若干条。
补充操作符:
! 非运算 例如 [ ! false ] 返回 true
&& 逻辑与 例如 [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑或 例如 [[ $a -lt 100 || $b -gt 100 ]] 返回 true
case语句
格式:
case 变量 in
模式1)命令表1;;
模式2)命令表2;;
*)命令表n;;
esac工作方式:取值后面必须为关键字 in ,每一个模式必须以右括号结束。取值可以为变量或者常量,取值检测匹配的每一个模式一旦模式匹配,其间所有命令开始执行直至 ;;执行完匹配模式相应的命令不会再继续匹配其他的模式如果无一匹配模式,使用 * 号捕获该值
| 或者 ; 转换模式
学生成绩管理系统,用shell中的case实现
90-100:A
80-89:B
70-79:C
60-69:D
<60:不及格
for循环
格式:
for 变量名 in 单词表
do命令表
done执行顺序:
变量依次取单词表中的各个单词, 每取一次单词, 就执行一次循环体中的命令. 循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条for I in 1 2 3 4 5 6 7 8 9 10
doecho "$I"
done
for语句的几种书写格式
变量I从单词表中取值
1) for I in 1 2 3 4 5 6 7 8 9 10 do ... done变量I从 1-10个数中取值
2) for I in {1..10} do ... done变量I从命令行取值,省略in、单词表
3) for I do ... done./脚本名 1 2 3 4 5书写格式类似C语言
4) for (( i = 0; i < 10; i++ )) do ... done
for (( i = 0; i < 10; i++ ))
doecho "$i"
done
while循环
格式:
while 命令或表达式
do命令表
done执行顺序:
while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。I=1
while [ $I -lt 10 ]
doecho $I(( I++ ))
doneecho $(( I++ ))
循环控制语句
breakn:结束n层循环
continuen:跳过n层本次循环,继续下一个循环
for (( i = 0; i < 10; i++ ))
dofor (( j = 0; j < 10; j++ ))doif [ $j -eq 3 ]then# continue# continue 2# breakbreak 2fiecho "$i:$j"done
done
数组
定义数组
在shell当中,用小括号 ( ) 来表示数组,数组元素之间用空格来隔开
1. 数组名=(value1 value2 value3 ...)
2. 数组名=(
value1
value2
...
)
3. 通过键值对的形式赋值
数组名=([0]=value1 [1]=value2)
4. 通过分别定义数组变量的方式来定义
数组名[0]="value1"
数组名[1]="value2"
5. 列表名="value0value1 value2"
数组名=($列表名)
注意:
1. 数组中的元素,必须以空格来隔开
2. 定义数组以其索引,可以不按顺序来定义的 如:数组名=([0]=value0 [1]=value2 [8]=array)
3. 字符串是数组中最重要的数据类型,可以通过 ($str) 转成数组
获取数组
1. 获取单个数组元素
${数组名[下标]}
2. 获取数组全部内容
${数组名[@]}或 ${数组名[*]}
3. 获取数组元素的个数
${#数组名[@]} 或 ${#数组名[*]}
数组切片
取数组中的某一段的元素的值
格式:
${数组名[@或*]:起始位置:长度}
gcc编译步骤
预处理:处理以#开头的内容,展开头文件、替换宏定义、删除注释,但是不会进行语法检查。
gcc -E xxx.c -o xxx.i编译:进行语法检查,将.i文件转化成.s汇编文件
gcc -S xxx.i -o xxx.s汇编:将汇编文件转化成二进制文件(不可执行)
gcc -c xxx.s -o xxx.o链接:链接库文件,将不可执行的二进制文件转化成可执行的二进制
gcc xxx.o -o xxx写 Makefile 时一般这样写
gcc xxx.o -o xxx
gcc -c xxx.c -o xxx.o