一、对shell的执行
(使用 echo $SHELL 可以查看默认的shell)
1、使用 /usr/bin/zsh 或 bash 执行脚本文件:
相当于创建一个子shell进程来对脚本文件进行执行(使用 /usr/bin/zsh 或 bash 来创建子shell),
假如在父shell进程下创建变量 a ,然后有shell脚本文件的内容是输出 a 的值,那样的话使用 /bin/usr/zsh 或 bash 就不能正确输出(退出当前bash,可以直接exit退出)。
2、使用 source 执行脚本文件:
相当于在当前shell下执行脚本。
3、使用 ./ 来执行脚本文件:
必须有可执行这一权限,也是创建一个子shell进程来对脚本文件进行执行。
为了解决上述问题,就涉及到了全局变量(环境变量)和局部变量(普通变量)。
二、全局变量(环境变量)和局部变量(普通变量)
1、全局变量(环境变量)
使用 export 导出的变量就是环境变量(一般使用全大写),这时候变量就可以在子shell里面用,但是关闭终端后这个变量就消失了,所以这时候就要把它保存到配置文件中去(kali 默认是在 ~/.bashrc 中)。
$SHELL 系统默认的 shell
$HOME 用户登陆时进入的目录
$PWD 当前目录
$USER 当前用户
$UID 当前用户的UID
2、其它直接声明的变量就是局部变量(普通变量)
三、获取变量和命令的值
1、获取变量的值:
(1)a=${aa}
2、获取命令的值:
(1)a=$(ls)
(2)a=`ls`
四、字符串拼接
1、变量与变量
a=ilove
b=chunchun
echo $a$b
//输出 ilovechunchun
2、变量与字符串
a=ilove
echo ${a}chunchun
//输出 ilovechunchun
五、特殊变量的使用以及给shell脚本传递参数
1、$0
得到脚本文件的路径名称,一般是这样用:
dirname /test/test.sh
basename /test/test.sh
2、$n
获取脚本文件传入的第n个参数,若参数大于九个,例如第十个参数,则要使用${10}
//输入命令
vim test4.sh
#!/usr/bin/zsh
echo $1
echo $2
//传入两个参数
/usr/bin/zsh test4.sh ilove chunchun
//输出
ilove
chunchun
3、$#
获取脚本传参的个数
/usr/bin/zsh /test/test.sh {1..10}
//输出
10
4、$*
获取当前shell脚本所有传参的参数,如果直接用,和 $@ 作用相同,把所有参数变量的值视为单个字符,如果加上引号,则表示把所有参数视为一整个字符串。
5、$@
获取当前shell脚本所有传参的参数,无论加不加引号都是把每个参数视为不同的字符串。
6、$?
若上条指令执行成功,返回 0 ,若失败,返回非0。
六、特殊的使用
1、花括号{ }的使用
(1)快速生成一些数字
echo {1..10}或是echo {a..z}
//输出
1 2 3 4 5 6 7 8 9 10
//或是
a b c d e f g h i j k l m n o p q r s t u v w x y z
//如果要在数字前加字符,普通字符直接加,若是 $ 等特殊字符,要加转义字符\
echo \${a..z}
//输出
$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
//也可以用花括号传递参数
/usr/bin/zsh test4.sh {1..4}
//输出
1 2 3 4
2、分开文件的路径和文件名
(1)dirname:获取文件路径
dirname /test/test.sh
//输出
/test
(2)basename:获取文件名
basename /test/test.sh
//输出
test.sh
3、eval
把 eval 后的内容当作命令来执行。
vim test.sh
#!/usr/bin/zsh
echo \$$#
/usr/bin/tsh test.sh chun li
//输出
$2
vim test.sh
#!/usr/bin/zsh
eval "echo \$$#"
/usr/bin/zsh test.sh chun li
//输出
li
4、整数运算
(1)使用 (()) 来进行整数运算
//计算时
((a=1+1))
//也可以
let a=1+1
//赋值时
a=((3+3))
//作比较运算时,也需要使用
((8>7&&5==5))
5、获取命令的值
(1)a=`ls`
(2)a=$(expr 1 + 1)
6、expr
(1)获得字符的长度
name=chunchun
expr length $name
//输出
8
7、小数运算
(1)使用awk实现
echo "7.5 2.5" | awk '{print ($1-$2)}'
8、read
(1)两个参数
[options]
1、-t 设置输入等待时间,默认单位是秒
2、-p 设置提示信息
(2)例子
//输入一个数字存入变量 num 中
read -t 10 -p "please input a number:" num
9、uptime
会显示一行信息,依次为当前时间,系统运行了多长时间,目前有多少用户登录,系统在过去一分钟、五分钟、和15分钟内的平均负载。
while true # 也可以 while [1]
do
uptime >> /test/1.txt
sleep 2 # 休眠两秒
done
10、脚本后台运行
(1)bash test.sh &
vim test.sh
#!/bin/bash
while true
do
uptime >> /test/uptime.log
sleep 2
done
bash test.sh & # 脚本在后台运行,这时候会得到一个进程号
tail -f /test/uptime.log
(2)jobs
查看当前执行的脚本或任务
(3)kill
a、使用 kill 加上进程号
b、使用 kill 加上 % 加上 任务编号(任务编号通过jobs获取)
(4)fg
fg 加 % 加任务编号,把任务提到前台来执行
(5)bg
fg 加 % 加任务编号,把任务提到后台来执行
(6)ctrl + z 暂停任务,使用 bg + % + 任务号来使任务继续,ctrl + c 终止任务
11、exit
退出脚本,exit 100 ,可以用 $? 来获取 100。
12、> /dev/null
/dev/null
是一个特殊的设备文件,它会将所有写入它的数据都丢弃,相当于将输出完全抛弃,不显示在终端上。
#!/bin/bash
nmap -sT 192.168.1.8 -p 445 > /dev/null -oG EternalBluescan
cat EternalBluescan | grep open > EternalBluescan2
cat EternalBluescan2
六、条件测试
1、test 测试表达式
//打开文件,成功输出true,失败输出false
test -f /test/1.txt && echo true || echo false
//若变量为空字符,则输出1,反之输出1
test -z $a && echo 1 || echo 0
2、[测试表达式]
//打开文件,成功输出true,失败输出false
[ -f /test/1.txt ] && echo true || echo false
//若变量为空字符,则输出1,反之输出1
[ -z $a ] && echo 1 || echo 0
注意:若表达式中含有逻辑运算符,则只能用 [[]],若还是要使用 [] ,则需要用
1、-a 代替 &&
2、-o 代替 ||
3、-gt 代替 >
4、-lt 代替 <
5、-eq 代替 =或==
6、-ne 代替 !=
7、-ge 代替 >=
8、-le 代替 <=
3、[[测试表达式]]
//打开文件,成功输出true,失败输出false
[[ -f /test/1.txt ]] && echo true || echo false
//若变量为空字符,则输出1,反之输出1
[[ -z $a ]] && echo 1 || echo 0
只有 [[]] 支持通配符匹配
4、((测试表达式))
在条件运算中用的不多。
5、通用文件测试操作符
1、-d 文件存在且为目录,则表达式成立,值为真
2、-f 文件存在且不为目录,则表达式成立,值为真
3、-e 文件存在,则表达式成立,值为真
4、-s 文件存在且大小不为0,则表达式成立,值为真
5、-r 文件存在且可读,则表达式成立,值为真
6、-w 文件存在且可写,则表达式成立,值为真
7、-x 文件存在且可执行,则表达式成立,值为真
8、f1 -nt f2 若 f1 比 f2 新,则表达式成立,值为真
9、f1 -ot f2 若 f1 比 f2 旧,则表达式成立,值为真
6、通用字符串测试操作符
1、-n "字符串" 若字符串长度不为0,则为真
2、-z “字符串” 若字符串长度为0,则为真
七、分支语句
1、if 分支语句
(1)第一种语法
if 条件表达式
then
指令
else
指令
fi
(2)第二种语法
if 条件表达式;then
指令
else
指令
fi
(3)第三种语法
if 条件表达式
then
指令
elif 条件表达式
then
指令
elif 条件表达式
then
指令
else 条件表达式
then
指令
fi
2、case 分支语句
case "变量" in
值1)
指令
;;
值2)
指令
;;
[1-9]) # 支持正则表达式
指令
;;
*)
指令
esac
八、循环语句
1、while
条件为真则进入循环
while 条件表达式
do
指令
done
2、until
与 while 相反
until 条件表达式
do
指令
done
3、for
(1)形式1
for 变量名 in 变量取值列表
do
指令
done
# in 变量取值列表可以省略,for i 就相当于 for i in "$@"
(2)形式2
for ((i=0;i<10;i++))
do
指令
done
九、函数
1、注意:
(1)如果函数存放在独立文件中,被脚本加载使用时,需要使用 source 来加载,因为它是在当前bash下来执行。
(2)在函数体中,$1,$2,$3获得的是函数传入的参数,传入的参数不需要在函数定义时声明。
(3)获取函数 return 的参数,可以用 $? 来获取。
vim test.sh
#!/bin/bash
function f1(){
echo " test"
echo $2
return 100
}
f1 1 2
echo $?
# 输出
test
2
100
(4)在 shell 文件中可以执行其他 shell 文件。
#!/bin/bash
if [ -f /test/test.sh ]
then
./test/test.sh
fi
2、函数写法
(1)标准形式
function 函数名(){
指令
return n
}
(2)简化写法1
function 函数名{
指令
return n
}
(3)简化写法2
函数名{
指令
return n
}