Shell阶段07 退出循环指令(示例:分发主机公钥), 函数应用(参数传参), 函数状态返回, 环境函数
#1.exit 退出循环,退出脚本 #2.break 结束当前循环,或者跳出本地循环,继续执行循环外面的命令 #3.continue 忽略本次循环剩余的代码,直接执行下一次循环 #4.案例 先扫描内网网段的所有主机,存活的主机进行发放本机的公钥 1.本机是否要有公钥,创建密钥对 rm 2.本机是否要有公钥,创建秘钥对 ssh-keygen 交互式进行创建,免交互 -f filename #指定是要文件保存的路径 -N new_passphrase #指定一个新的密码 #无交互创建密钥对 ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" 3.批量监测内网主机是否存活 ping 4.如果存活,则发送公钥 确认信息,输入密码 如何进行免交互 -o StrictHostKeyChecking=no #忽略回复yes的交互 (避免第一次交互 公钥检查) sshpass -p123456 #指定密码为123456,忽略交互 #如果没有sshpass命令,就先安装 yum install sshpass -y #免交互发送公钥 sshpass -padmin123 ssh-copy-id -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no 172.16.1.51 #可以设定端口号(默认22端口) -p22 sshpass -padmin123 ssh-copy-id -p22 -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no 172.16.1.51 [root@shell01 scripts]# vim key.sh #!/bin/bash #1.调用函数库 [ -f /etc/init.d/functions ] && source /etc/init.d/functions || echo "函数库文件不存在!" #2.定义变量 Ip_log=/tmp/ip.log Port_log=/tmp/port.log >$Ip_log >$Port_log #3.删除旧的密钥对 rm -rf /root/.ssh/ #4.创建新的密钥对 ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" &>/dev/null if [ $? -eq 0];then echo "密钥对创建成功" else echo "密钥对创建是吧" exit fi #5.批量探测内网主机 i=1 while [ $i -le 254] do { #6.测试主机网络是否可达 Ip=10.0.0.$i ping -c1 -W1 $Ip &>/dev/null if [ $? -eq 0 ];then action "$Ip地址通畅! " /bin/true echo "$Ip地址通畅" >>$Ip_log fi } & let i++ sleep 0.1 done wait echo "IP地址扫描完成..............." echo "端口扫描开始.........." while read line do State=$(nmap -p22 $i |grep 22/ | awk '{print $2}') if [ $State == 'open' ];then action "${line} 的22端口是开放的" /bin/true echo "${line}" >> $Port_log else action "${line} 的22端口没有开放的" /bin/false fi done <$Ip_log #7.发送公钥 while read line do sshpass -padmin123 ssh-copy-id -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $line &>/dev/null if [ $State == 'open' ];then action "${line}的主机公钥发送成功" /bin/true else action "${line}的主机公钥发送失败" /bin/false fi done <$Port_log ------------------------------------- #测试,直接连接登录就说明成功了 [root@shell01 scripts]# ssh 10.0.0.6
什么是函数 函数其实就是一堆命令的集合,用来完成一些特定的代码块 作用: 便于代码的复用 函数的基本概述 #定义函数 #第一种 函数名() { 命令集合 } #第二种 function 函数名 { 命令集合 }
#函数的调用方式
1.可在交互式环境下定义函数
2.可将函数放在脚本文件中作为它的一部分
3.可放在只包含函数的单独文件中
#示例 #定义函数,函数的大括号与命令之间要空格作为分隔符 [root@shell01 scripts]# fun1() { echo "123"; } #调用函数 [root@shell01 scripts]# fun1 123 [root@shell01 scripts]# function fun2 { echo "456"; } [root@shell01 scripts]# fun2 456 #函数的内部位置变量 [root@shell01 scripts]# fun2 () { echo "$1"; } [root@shell01 scripts]# fun2 123 123 [root@shell01 scripts]# fun3() { echo "$1 $2"; } [root@shell01 scripts]# fun3 123 456 123 456 #定义任意数量位置变量 [root@shell01 scripts]# fun4() { echo "$*"; } [root@shell01 scripts]# fun4 123 123 [root@shell01 scripts]# fun4 123 456 789 123 456 789 [root@shell01 scripts]# fun5() { echo "$@"; } #$@等于$* [root@shell01 scripts]# fun5 123 456 789 123 456 789 #如何向函数传递参数,都是使用$1..$9 [root@shell01 scripts]# vim fun-1.sh #!/bin/bash fun_1() { echo "$1" } fun_1 123 [root@shell01 scripts]# sh fun-1.sh 123 #通过固定变量取值 [root@shell01 scripts]# cat fun-1.sh #!/bin/bash fun_1() { echo "$Num" } Num=123 fun_1 #注意:脚本的$1不是函数的$1 [root@shell01 scripts]# cat fun-1.sh #!/bin/bash fun_1() { echo "$1" } Num=$1 fun_1 [root@shell01 scripts]# sh fun-1.sh #这里显示为空 #注意:脚本中的位置变量不是函数中的位置变量 #编写多个位置变量 [root@shell01 scripts]# vim fun-2.sh #!/bin/bash fun_2() { echo "$1" #接受函数传递第一个位置变量 } fun_2 $1 #接受脚本传递的第一个位置变量,传入函数中第一个参数 fun_2 $2 #接受脚本传递的第二个位置变量,传入函数中第一个参数 fun_2 $3 #接受脚本传递的第三个位置变量,传入函数中第一个参数 [root@shell01 scripts]# sh fun-2.sh 123 456 789 123 456 789
local #定义函数的本地变量 只在函数中生效 (作用域在函数内,函数结束会被自动销毁)
#查看当前已定义的函数名 declare -F #查看当前已定义的函数定义 declare -f #查看指定当前已定义的函数名 declare -f func_name #查看当前已定义的函数名定义 declare -F func_name #删除函数 unset func_name
写个脚本,实现简单的计算器功能,能够实现加减乘除四种计算 [root@shell01 scripts]# vim cal.sh #!/bin/bash cal() { echo $(( $1 $2 $3 )) } if [ $# -ne 3 ];then echo "你的传参不是3个!你可以这么写: 1 + 1" exit fi echo "$1 $2 $3 = $(cal $1 "$2" $3)" [root@shell01 scripts]# sh cal.sh 1 - 1 1 - 1 = 0 [root@shell01 scripts]# sh cal.sh 1 \* 1 1 * 1 = 1
返回值在shell中有两种方式 echo #返回数据,自定义的输出数据 字符串 return #命令执行结果返回值 0-255 之间的正整数 $?获取 0 默认表示成功 非0表示失败 [root@shell01 shell12]# vim return.sh #!/bin/bash fun() { echo "123" return 1 } Test=$(fun) echo "函数的状态返回码为: $?" echo "函数的返回数据为: $Test" [root@shell01 shell12]# sh return.sh 函数的状态返回码为: 1 函数的返回数据为: 123 #示例:判断文件是否存在 [root@shell01 shell12]# vim check_file.sh #!/bin/bash File() { if [ -f /etc/hosts ];then return 0 else return 1 fi } File && echo "文件存在!" || echo "文件不存在!"
环境函数
类拟于环境变量,也可以定义环境函数,使子进程也可使用父进程定义的函数
定义环境函数: export -f function_name declare -xf function_name 查看环境函数: export -f declare -xf 例: #定义 [root@ubuntu2204 ~]# cli_func1(){ echo "cli-func1"; }; cli_func2(){ echo "cli-func2"; };export -f cli_func2; #查看 [root@ubuntu2204 ~]# export -f cli_func2 () { echo "cli-func2" } declare -fx cli_func2