Shell 脚本语言学习笔记
echo 输出内容支持换行
# 默认情况下,echo关闭了对转移字符的解释,添加-e参数可打开echo对转义字符串的解释功能。-E关闭转义字符,是默认值
echo -e "输出内容\n"
rwx权限对应数字
rwx权限对应数字:r=4,w=2,x=1。
通过4、2、1的组合相加,得到以下几种权限:
0:没有权限;
4:读取权限;
5:读取+执行;
6:读取+写入;
7:读取+写入+执行。
而777、776、770、466、444等是有上面组合相加后的组合,个十百位分别表示用户User、组Group、及其它Other的权限。
read
选项说明:
-a:将分裂后的字段依次存储到指定的数组中,存储的起始位置从数组的index=0开始。
-d:指定读取行的结束符号。默认结束符号为换行符。
-n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
-N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
-p:给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"
-r:禁止反斜线的转义功能。这意味着"\"会变成文本的一部分。
-s:静默模式。输入的内容不会回显在屏幕上。
-t:给出超时时间,在达到超时时间时,read退出并返回错误。也就是说不会读取任何内容,即使已经输入了一部分。-u:从给定文件描述符(fd=N)中读取数据。
-
-p 提示信息换行
#还有$后接单引号的$'string',这在bash中被特殊对待:会将某些反斜线序列(如\n,\t,\",\'等)继续转义,而不认为它是字面符号(如果没有$符号,单引号会强制将string翻译为字面符号,包括反斜线) read -p $'输出内容\n'
-
读取多行值
read -p $'请输入arg1,arg2的值,中间以空格隔开:' arg1 arg2
echo "arg1 = "$arg1
echo "arg2 = "$arg2
定义变量与清除变量
-
变量定义
变量名=变量值 # 注意中间不要打空格 num=10
-
清除变量
unset 变量名 unset num
-
例子
read -p $'请输入num值:\n' num #从键盘获取变量值 echo "num 的值是: "$num unset num #清除变量值 echo "num 的值是: "$num
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SFi0DV9t-1650241328286)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220411204522703.png)]
变量的查看
查看所有变量 :set
set命令输出所有的变量,包括全局变量和局部变量
查看环境变量
env
命令只显示全局变量
查看所有的变量,函数,整数,和已经导出的变量
declare #命令输出所有的变量,函数,整数,和已经导出的变量
set -o #命令显示bashShell的所有参数配置信息
自定义环境变量
暂时设定环境变量
如果想设置环境变量,就要给在给变量赋值后或在设置变量时使用export命令,export命令和declare命令的格式
export 变量名=value
变量名=value ; export 变量名
declare - x 变量名=value
永久设定环境变量
- 用户环境变量配置
1 [root@king scripts]# ls /root/.bashrc
2 /root/.bashrc
3 [root@king scripts]# ls /root/.bash_profile
4 /root/.bash_profile
说明: 对于用户的环境变量设置,常见的是用户家目录下的.bashrc和.bash_profile
-
全局环境变量的配置
常见的全局环境变量配置文件,
/etc/profile;/etc/bashrc;/etc/profile.d
这三个配置文件,如果想要在登陆后初始化或者显示加载的内容,只需要把脚本文件放在/etc/profile.d
文件下即可(不需要加执行权限)在Java环境中,自定义环境变量,通常放在/etc/profile全局环境变量里,
export JAVA_HOME=/application/jdk export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin export RESIN_HOME=/application/resin
查看/取消环境变量
我们通常在工作中要查看一下环境变量中都配置了什么,需要做什么更改,所以我们就有了ehco或printf命令来打印查看环境变量。
$HOME
:用户登录时进入的目录
$UID
:当前用户的uid( 也就是用户的标识,相当于人的身份证)相当于id -u
[king@king ~]$ echo $HOME
/home/king
[king@king ~]$ echo $UID
300
我们可以用unset来消除本地变量和环境变量
[king@king ~]$ echo $USER
nane
[king@king ~]$ unset $USER
[king@king ~]$ echo $USER #<这里输出是个空行
变量名一定要大写,可以在自身的Shell及子Shell中使用,常用export来定义环境变量
执行enc默认可以显示所有的环境变量名称及对应的值
输出时用“$变量名”,取消用“unset 变量名”
双引号:可以解析变量的值
单引号:不能解析变量的值
预设变量
shell直接提供无需定义的变量
案例
#!/bin/bash
echo "参数的个数=$#"
echo "参数的内容=$*"
echo "第一个参数:$1"
echo "第一个参数:$2"
echo "第一个参数:$3"
echo "进程号$$"
echo "进程名$0"
echo "50*30的结果$?"
脚本标量的特殊用法
echo "今天是`date`" #反引号中的内容作为系统命令,并执行其内容可替换输出为一个变量
- () 子shell执行 不影响当前shell
#!/bin/bash
data=10
(
data=100
echo "data=$data"
echo "子shell"
)
echo "父shell data=$data"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hnD29GI-1650241328287)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220412185103521.png)]
- {} 在当前shell中执行,会影响变量
#!/bin/bash
data=10
{
data=100
echo "data=$data"
echo "子shell"
}
echo "父shell data=$data"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cDZNWYTb-1650241328288)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220412185203264.png)]
变量的扩展
判断变量是否存在
#!/bin/bash
# ${num:-val}如果num存在,输出num否在输出val
echo ${num:-1}
num=200
echo ${num:-1}
#!/bin/bash
# ${num:=val}如果num存在,输出num,否则输出val并赋值num为val值
echo ${num:-1}
num=200
echo ${num:-1}
字符串操作
#!/bin/bash
str="1 this is test code 1"
# 测量字符串长度${#str}
echo "the length of str is ${#str}"
# 从下标3的位置提取${str:3}
echo ${str:3}
# 从下标为3的位置提取长度为6字节
echo ${str:3:6}
#${str/old/new} 用new替换str中出现的第一个old
echo ${str/test/dome}
#${str//old/new}用new 替换str中出现的所有old
echo ${str//1/}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPbX3eqw-1650241328288)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220412191325681.png)]
字符串测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hUzUnOj-1650241328289)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220413111931184.png)]
-
linux中 返回值为0 是true 1为false
#!/bin/bash test -e test.sh # 测试是否存在文件 echo $? #返回上一条语句执行结果 #[condition] []中加条件判断 [-e test.sh] # 同 test -e test.sh
#!/bin/bash read str1 str2 # 判断字符串是否相同 [ $str1 = $str2 ] #注意[] 前后空格 echo $? [ -z $str1 ] #判断str1是否为空数值测试
数值测试
格式 test num1 num_operator num2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OjQxnR2X-1650241328289)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220413113450881.png)]
案例
#!/bin/bash
[ 1 -eq 1 ] # 1=1 是否成立
echo $?
符合语句测试
案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LNAyZC73-1650241328290)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220413113718688.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0n6z0s7-1650241328291)(C:\Users\11066\AppData\Roaming\Typora\typora-user-images\image-20220413113843699.png)]
test 1 -eq 1 -a 1 -ge 0 || echo ??? # 1 = 1 and 1>=0 成立 不执行echo ???
控制语句
if控制语句
格式一:
if [条件1]; then
执行第一段程序
else
执行第二段程序
fi
格式二:
if [条件1]; then
执行第一段程序
elif [条件2];then
执行第二段程序
else
执行第三段程序
fi
案例
#!/bin/bash
read -p $'请输入文件夹名称:\n' filename
if [ -e $filename ];then
echo "$filename存在 即将进入文件夹"
cd $filename
echo "即将创建测试文件"
touch dome.sh #创建新的空文件夹
else
echo "$filename 不存在,即将创建文件夹"
mkdir $filename
echo "创建文件夹成功,即将进入"
cd $filename
echo "即将创建测试文件"
touch dome.sh #创建新的空文件夹
fi
tree
case(java中switch case)
格式:
case 变量 in "指定值1") # 若变量与指定值相同,则执行程序段1
程序段1
;; # 相当于break
指定值2)
程序段2
;;
指定值3)
程序段3
;;
esac
read -p $'请输入变量的值:\n' num
case $num in 1|'一'|'壹')
echo "输入了1"
;;
2|'二'|'贰')
echo "输入了2"
;;
3|'三'|'叁')
echo "输入了3"
esac
for循环
形式一:
for((初始值;限制值;执行步长))
do
程序段
done
例子
declare -i sum=0 #定义int类型变量
declare -i i;
for((int i=0;i<=100;i++))
do
sum+=$i;
done
echo "sum=$sum" #5050
形式二
for var in con1 con2 con3
do
程序段
done
- 例子
for filename in `ls` #遍历当前目录下文件名
do
if [-d $filename];then
echo "$filename是文件夹"
elif [-f $filename];then
echo "$filename是普通文件"
fi
done
while 循环
- while 循环当条件不满足循环停止循环
while condition
do
代码块
done
#!/bin/bash
i = 0
while [ $i -le 100]
do
echo $i
let i+=1 #let命令用于指定算术运算,即 let expretion。
done
until
- until 循环 当循环满足条件 停止循环
#!/bin/bash
i=0
until [ i -le 10 ]
do
echo $i
done
函数
- 格式一
函数名(){
命令…
}
- 格式二
function 函数名(){
命令…
}
函数调用 函数名 $param1 $param2
#!/bin/bash
function test(){
echo "第一个参数为$1" $1 接收第一个参数
}
test 100
案例
#!/bin/bash
# 找出两个数的最大值
function max_value(){
if [ $1 -ge $2 ];then
return $1
else return $2
fi
}
read -p $'请输入第一个值:\n' param1
read -p $'请输入第二个值:\n' param2
max_value $param1 $param2
echo "俩个数中最大值为$?"
函数导入source 文件名
#!/bin/bash
# 找出两个数的最大值
function max_value(){
if [ $1 -ge $2 ];then
return $1
else return $2
fi
}
命令…
}
函数调用 函数名 $param1 $param2
#!/bin/bash
function test(){
echo "第一个参数为$1" $1 接收第一个参数
}
test 100
案例
#!/bin/bash
# 找出两个数的最大值
function max_value(){
if [ $1 -ge $2 ];then
return $1
else return $2
fi
}
read -p $'请输入第一个值:\n' param1
read -p $'请输入第二个值:\n' param2
max_value $param1 $param2
echo "俩个数中最大值为$?"
函数导入source 文件名
- test.sh
#!/bin/bash
# 找出两个数的最大值
function max_value(){
if [ $1 -ge $2 ];then
return $1
else return $2
fi
}
- test2.sh
#!/bin/bash
source test.sh
read -p $'请输入第一个值:\n' param1
read -p $'请输入第二个值:\n' param2
max_value $param1 $param2
echo "两个数中最大值为$?"