硬件层
、Liunx系统层
、Shell
、应用程序层
,如图1。直接解析执行
(批处理)图1:
图2:
/etc/profile
:
用户第一次登录时,该文件被执行
,~/.bashrc
:
.bashrc
(隐藏文件,使用 ls -a 命令查看)注意:
- 无论是系统调用的还是需要我们自己调用的,其
语法规则都一样
1、创建文件,shell脚本一般以
.sh
结尾,也可以不是或者没有
2、编写代码
3、执行脚本
#!/bin/bash
echo "Hello Shall"
echo 今天不冷
说明:
#!
用来声明脚本由什么 shell解释,否则使用默认 shell(bash)#
表示注释本行
注意:
创建文件时:
- 如果是在windows中创建编写的Shell脚本文件,拖拽到Liunx下无法运行,因为Windows与Liunx下
\表示的含义不同
,所以导致程序无法被识别- 解决方案1:
- 在Liunx中使用
vim编辑器
,在最后一行模式(命令行模式) 下输入set ff=unix
- 解决方案2:
- 在Linux中安装dos2unix,使用dos2unix转换
- 步骤:
- 1、命令行输入:sudo apt-age install dos2unix
- 2、命令行输入:dos2unix 文件地址
编写代码:
#
:注释
#!
:用来声明脚本由什么 shell 解释
echo
:否则使用默认 shell 输出执行脚本方式:
方式1:使用
sh
或bash
- sh 文件名
- bash 文件名
方式2:
./
文件名
- 需要可执行权限,添加权限命令:chmod +x 文件名
- +增加权限
- -减少权限
- x:可执行
- 方式1、方式2 会开启 子Shell
方式3:
source
文件名 或. 文件名
- source 文件路径 借鉴cshell
- . 文件路径 借鉴bash
- 方式3 不会开启子Shell
开启子Shell与不开启的区别:
- 开启子Shell后,子Shell中的变量父Shell不可见
- 区别:
./
和bash
执行过程基本一致,
bash
明确指定 bash 解释器去执行脚本,脚本中#!指定的解释器不起作用./
首先检测#!,使用#!指定的 shell,如果没有使用默认的 shell- 用./和 bash 去执行会在后台启动一个新的 shell去执行脚本
- 用. 或source 去执行脚本不会启动新的 shell,直接由当前的 shell去解释执行脚本
HOME、PWD、SHELL、USER
#!/bin/bash
#家目录的路径
echo $HOME
#当前路径
echo $PWD
#Shell解析器的路径
echo $SHELL
#当前用户名
echo $USER
# #系统提供的所有全局变量可以使用env命令查询
# env
# echo -----------------------------
# NAME=aaa
# #当前Shell中的所有变量
# set
语法:
echo 变量名
如:
echo $HOME
语法:
env或printenv
如:
env
printenv
语法:
set
如:
set
变量名=变量值
注意:
- =号前后不能有空格
- 声明的变量为局部变量
unset 变量名
readonly 变量
示例:
#!/bin/bash
readonly num=10
#unset num
num=100
echo $num
$变量名
注意:如果变量不存在返回空
作用:
语法:
export 变量名
注意:
示例:
#!/bin/bash
export DATA=10
bash执行脚本:
source执行脚本
declare -i 变量
示例:
#!/bin/bash
declare -i num=10
num=$num+1
echo $num
变量默认
类型为都是字符
,无法 直接
进行数值运算注意:“” 与 ''的区别
- ""会解析变量值
- ''不会解析变量值
示例:
#!/bin/bash
num=1000
echo "num=$num"
echo 'num=$num'
$#: 传给 shell 脚本参数的数量
$*: 传给 shell 脚本参数的内容
$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开
$?: 命令执行后返回的状态
"$?": 用于检查上一个命令执行是否正确(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错)。
$0: 当前执行的进程名
$$: 当前进程的进程号
"$$": 最常见的用途是用作临时文件的名字以保证临时文件不会重复
示例1:
#!/bin/bash
#获取执行当前shell脚本传入的参数个数
echo $#
#获取执行当前shell脚本传入的参数
echo $*
#获取执行当前shell脚本传入的第1个参数
echo $1
#获取执行当前shell脚本传入的第2个参数
echo $2
#获取执行当前shell脚本传入的第3个参数
echo $3
ls
#$?获取上一条命令执行状态,0表示成功,非0失败
echo $?
#test.c不存在时,返回1
cat test.c
echo $?
#创建后,返回0
touch test.c
echo $?
echo $0
echo $$
echo "$$"
touch "$0$$.txt"
"":包含的变量会被解释
'':包含的变量会作为字符串处理
``:反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量
\:同c语言\n \t \r \a等echo命令需加-e转义(bash解析器需求)
( 命令 ):由子shell来完成,不影响当前shell中的变量,命令前后必须有空格
{ 命令 }:在当前shell中执行,会影响当前变量,命令前后必须有空格
示例1:转义字符\
#!/bin/bash
#以sh运行会将-e作为字符串,但是可以解析其中的转意字符
#以bash运行-e说明将打印的内容中的转意字符成为转意字符,否则当前普通字符串处理
#./使用的是#!后执行的shell解析器,如果没有#!,使用默认的shell解析器
echo -e "123\n456"
echo -e '#\n#'
示例2:
#!/bin/bash
echo date
echo "date"
echo 'date'
echo `date`
num=1
(
num=10
echo "()中的num=$num"
)
echo "()外的num=$num"
data=1
{
data=10
echo "{}中的data=$data"
}
echo "{}外的data=$data"
语法:
read 变量名
或
read -p 提示内容 变量名
示例:
#!/bin/bash
#read
#语法1:read 变量名
#语法2:read -p 提示的内容 变量名
#输入人名
#语法1
# echo 请输入姓名
# name=""
# read name
# echo "您输入的姓名为:$name"
name=""
read -p 请输入姓名: name
echo "您输入的姓名为:$name"
# 结果:
# 请输入姓名:张三
# 您输入的姓名为:张三
语法1:
test 条件
语法2:
[ 条件 ]
文件测试: 测试文件状态的条件表达式
-e 是否存在
-d 是否为目录
-f 是否为文件
-r 是否可读
-w 是否可写
-x 是否可执行
-L 是否连接
-c 是否字符设备
-b 是否块设备
-s 文件非空
示例:
#!/bin/bash
#输入文件名判断文件是否存在
#test 条件
#[ 条件 ]
filename=""
read -p 请输入文件名 filename
test -e $filename
echo "文件是否存在:$?"
test -f $filename
echo "是文件吗:$?"
test -d $filename
echo "是文件夹吗:$?"
test -r $filename
echo "是否可读:$?"
test -w $filename
echo "是否可写:$?"
test -x $filename
echo "是否可执行:$?"
[ -s $filename ]
echo "是否非空:$?"
= 两个字符串相等
!= 两个字符串不相等
-z 空串
-n 非空串
注意:
= !=前后要有空格
示例:
#!/bin/bash
str01="hello"
str02="world"
str03=$str01
echo "str01=$str01"
echo "str02=$str02"
echo "str03=$str03"
[ $str01 = $str02 ]
echo -e "str01与str02内容是否相同?\t$?"
[ $str01 = $str03 ]
echo -e "str01与str03内容是否相同?\t$?"
[ $str01 != $str03 ]
echo -e "str01与str03内容是否不相同?\t$?"
str04="123"
test -z $str04
echo -e "str04是否为空字符串?\t$?"
# str01=hello
# str02=world
# str03=hello
# str01与str02内容是否相同? 1
# str01与str03内容是否相同? 0
# str01与str03内容是否不相同? 1
# str04是否为空字符串? 1
-eq 数值相等
-ne 数值不相等
-gt 数 1 大于 数 2
-ge 数 1 大于等于 数 2
-lt 数 1 小于 数 2
-le 数 1 小于等于 数 2
示例:
#!/bin/bash
# -eq 数值相等
num01=1
num02=10
[ $num01 -eq $num02 ]
echo $?
# -ne 数值不相等
[ $num01 -ne $num02 ]
echo $?
# -gt 数 1 大于数 2
[ $num01 -gt $num02 ]
echo $?
# -ge 数 1 大于等于数 2
[ $num01 -ge $num02 ]
echo $?
# -le 数 1 小于等于数 2
[ $num01 -le $num02 ]
echo $?
# -lt 数 1 小于数 2
[ $num01 -lt $num02 ]
echo $?
# num=1
#当num存在取num的值,如果num不存在取10
# echo ${num:-10}
# echo $num
echo ${num:=10}
echo $num
# 1
# 0
# 1
# 1
# 0
# 0
# 10
# 10
&&:
command1 && command2
&&左边命令(command1)执行成功(即返回 0) shell 才执行&&右边的命令(command2)
||:
command1 || command2
||左边的命令(command1)未执行成功(即返回非 0) shell 才执行||右边的命令(command2)
多重条件:
-a:与
-o:或
!:非
示例1:
#!/bin/bash
#输入一个数判断是否在0~100之间
read -p "请输入一个数" num
test $num -gt 0 && test $num -lt 100
echo "$num 是否在0~100之间:$?"
# 结果:
# 请输入一个数12
# 12 是否在0~100之间:0
示例2:
#!/bin/bash
#输入文件名称,判断文件是否可读可写可执行
read -p "请输入文件名称" fileName
test -r $fileName -a -w $fileName -a -x $fileName
echo "文件可读可写可执行:$?"
test -r $fileName -o -w $fileName
echo "文件可读或可写:$?"
test ! -x $fileName
echo "文件是否不可执行:$?"
# 请输入文件名称test.c
# 文件可读可写可执行:1
# 文件可读或可写:0
# 文件是否不可执行:0
语法1:
if [ 条件 1 ];then
执行第一段程序
else
执行第二段程序
fi
示例:
#!/bin/bash
# if [ 条件 1 ];then
# 执行第一段程序
# else
# 执行第二段程序
# fi
#判断文件是否存在,如果存在则不管,如果不存在则创建
if [ -e "a.txt" ];then
echo "不管"
else
touch "a.txt"
fi
语法2:
if [ 条件1 ];then
执行第1段程序
elif [ 条件2 ];then
执行第2段程序
elif [ 条件3 ];then
执行第3段程序
...
else
执行第n段程序
fi
示例:
#!/bin/bash
# if [ 条件1 ];then
# 执行第1段程序
# elif [ 条件2 ];then
# 执行第2段程序
# elif [ 条件3 ];then
# 执行第3段程序
# ...
# else
# 执行第n段程序
# fi
#判断成绩对应的区间
read -p "请输入考试成绩:" score
if [ $score -lt 0 -o $score -gt 100 ];then
echo "成绩有误"
elif [ $score -lt 60 ];then
echo "D"
elif [ $score -lt 70 ];then
echo "C"
elif [ $score -lt 85 ];then
echo "B"
else
echo "A"
fi
# 请输入考试成绩:99
# A
语法:
case $变量名 in
"值1")
语句1
;;
"值2")
语句2
;;
*)
语句3
;;
esac
扩展:
exit 1 #退出shell
示例:
#!/bin/bash
# case $变量名 in
# "值1")
# 语句1
# ;;
# "值2")
# 语句2
# ;;
# *)
# 语句3
# ;;
# esac
# |
#输入月份输出季节
read -p "请输入月份" month
case $month in
"3" | "4" | "5")
echo "春季"
;;
"6" | "7" | "8")
echo "夏季"
;;
"9" | "10" | "11")
echo "秋季"
;;
"12" | "1" | "2")
echo "冬季"
;;
*)
echo "输入有误"
;;
esac
# 请输入月份9
# 秋季
语法:
for (( 初始值; 限制值; 执行步阶 ))
do
程序段
done
示例:
#!/bin/bash
# for (( 初始值; 限制值; 执行步阶 ))
# do
# 程序段
# done
# 计算100以内数之和
declare -i sum=0
declare -i i=0
for(( i=0;i<101;i++ ))
do
sum=$sum+$i
done
echo $sum
#5050
语法:
while [ 条件 ]
do
程序段
done
示例:
#!/bin/bash
# while [ 条件 ]
# do
# 程序段
# done
#打印100以内的数
declare -i i=0
while [ $i -le 100 ]
do
num=$(( i % 2 ))
if [ $num -eq 0 ];then
echo $i
fi
i=$i+1
done
变量名=$(( 值1 + 值2 ))
变量名=$(( 值1 - 值2 ))
变量名=$(( 值1 * 值2 ))
变量名=$(( 值1 / 值2 ))
变量名=$(( 值1 % 值2 ))
变量名=$(( 变量名-- ))
变量名=$(( --变量名 ))
变量名=$(( 变量名++ ))
变量名=$(( ++变量名 ))
变量名=$(( -10 > 1 ? 10 : 1 ))
示例:
echo $(( 10 + 2))
echo $(( 10 - 2))
echo $(( 10 * 2))
echo $(( 10 / 2))
echo $(( 10 % 2))
num=1
echo $(( num-- ))
echo $(( -10 > 1 ? 10 : 1 ))
# 12
# 8
# 20
# 5
# 0
# 1
# 1
语法:
until [ condition ]
do
程序段
done
注意:这种方式与 while 恰恰相反,当 condition 成立的时候退出循环,否则继续循环。
示例:
#!/bin/bash
# until [ condition ]
# do
# 程序段
# done
#打印100以内的数
declare -i num=0
until [ $num -eq 100 ]
do
echo $num
num=$num+1
done
语法1:
函数名(){
程序段
}
语法2:
function 函数名(){
程序段
}
语法
函数名 参数1 参数2
#!/bin/bash
# function add()
# {
# declare -i sum=0
# sum=$1+$2
# return $sum
# }
add()
{
declare -i sum=0
sum=$1+$2
return $sum
}
add 1 9
echo $?
//10
注意:
- 当函数定义与函数调用不在一个文件中需要在函数调用所在的文件中使用
source引用函数定义的文件
#19_01shell.sh文件
#!/bin/bash
add()
{
declare -i sum=0
sum=$1+$2
return $sum
}
#19_02shell.sh文件
#!/bin/bash
source 19_01shell.sh
add 1 10
echo $?
#!/bin/bash
# 判断用户家目录下(~)下面有没有一个叫 test 的文件夹
# 如果没有,提示按 y 创建并进入此文件夹,按 n 退出
# 如果有,直接进入,提示请输入一个字符串,并按此字符串创建一个文件,
# 如果此文件已存在,提示重新输入,重复三次自动退出,不存在创建完毕,退出
#进入家目录
cd ~
#封装函数
mkdirtest()
{
if [ -e "test" ];then
echo "文件夹存在"
cd test
return 0
else
echo "文件夹不存在, 是否创建?y|n"
read tag
case $tag in
"Y" | "y")
mkdir "test"
cd test
return 0
;;
*)
echo "退出";
return 1
;;
esac
fi
}
mkdirtest
if [ $? -eq 0 ];then
for (( i=0;i<3;i++ ))
{
read -p "请输入一个文件名" filename
if [ -e $filename ];then
echo "文件已存在,请重新输入文件名"
else
echo "文件不存在"
touch $filename
echo "每天中午吃饭都不知道吃啥" >> filename
echo "但是已创建"
break
fi
}
fi
#!/bin/bash
# 判断用户家目录下(~)下面有没有一个叫 test 的文件夹
# 如果没有,提示按 y 创建并进入此文件夹,按 n 退出
# 如果有,直接进入,提示请输入一个字符串,并按此字符串创建一个文件,
# 如果此文件已存在,提示重新输入,重复三次自动退出,不存在创建完毕,退出
#进入家目录
cd ~
#封装函数
mkdirtest()
{
if [ -e "test" ];then
echo "文件夹存在"
cd test
return 0
else
echo "文件夹不存在, 是否创建?y|n"
read tag
case $tag in
"Y" | "y")
mkdir "test"
cd test
return 0
;;
*)
echo "退出";
return 1
;;
esac
fi
}
mkdirtest
if [ $? -eq 0 ];then
for (( i=0;i<3;i++ ))
{
read -p "请输入一个文件名" filename
if [ -e $filename ];then
echo "文件已存在,请重新输入文件名"
else
echo "文件不存在"
touch $filename
echo "每天中午吃饭都不知道吃啥" >> filename
echo "但是已创建"
break
fi
}
fi