调试
shell -x 脚本
执行
sh 脚本 [参数] (开启新的bash去执行)
添加执行权限,指定路径执行 (开启新的bash去执行)
source 脚本 (不开启新的bash去执行,可以调用当前shell环境变量)
. 脚本 (不开启新的bash去执行,,可以调用当前shell环境变量)
区别展示
环境变量
先读profile,再读bashrc
/etc/profile 全局环境变量
/etc/bashrc 全局bash环境
谁后读谁生效
~/.bashrc 用户bash环境
~/.bash_profile 用户环境变量
用户环境
修改.bashrc文件添加export a=1,生效
修改.bash_profile文件,添加export a=10,生效
再次使得.bashrc生效,发现a的值再次改变
全局(在没有用户变量的设置下生效)
设置/etc/bashrc文件中a=10,设置/etc/profile文件中a=100,使得profile文件先生效,a的值为10
修改生效顺序,发现a的值仍为10
取消/etc/bashrc中a=10的赋值,再次生效,此时a=100
切换命令时时加 “-”切换profile文件
脚本中参数的传递
$@ 多个参数对应多个变量
$* 多个参数对应一个变量
$# 变量个数
$$ 进程PID
$1 第一个参数
$0 文件名
编写打印脚本
#!/bin/bash
echo \$0 is $0
echo \$1 is $1
echo \$2 is $2
echo \$# is $#
echo \$@ is $@
echo \$* is $*
echo \$$ is $$
执行结果
交互式输入
read
-p 提示内容
-s 隐匿输入
编写脚本
#!/bin/bash
read -p "please input your name:" name
echo "hello,$name!"
执行结果
利用-s隐藏输入
#!/bin/bash
read -s -p "please input your name:" name
echo -e "\nhello,$name!"
脚本
执行结果
其中$@和$*的区别
$@ 多个参数分割
$* 多个参数合并
脚本
#!/bin/bash
for n in “$@”
do
echo $n
done
for n in "$*"
do
echo $n
done
执行结果
alias别名设置
alias 别名
设置
alias octo='vim'
取消设置
unalias octo
可以作为环境变量写入下列文件中
/etc/bashrc
/etc/profile
.bash_profile
.bashrc
设置别名
取消设置
写入文件
取消设置
返回值
执行命令后的返回值
echo $?
数组
连续地址存放数据
a=(1 2 3 4)
常用语句
for do done for循环
# for n in 参数
# for ((i=1;i<10;i+=1))
while do done while循环条件为真
if if语句
case 分支语句
exit 退出程序
break 中断循环
continue 跳过本次循环
until do done 条件为假
if-elif then
Case使用
case $1 in
a|A)
action A
;;
b|B)
action B
;;
C|c)
action C
;;
*)
action Default
esac
使用实例
根据文件内容创建用户并给予密码
Judge_File()
{
for File in $1 $2
do
{
if [ "$File" == "" ]
then
echo -e "\nWrong args'\n'"
echo -e "Please try usage : sh create_user.sh Userfile Passfile.\n"
exit
elif [ ! -e "$File" ]
then
echo -e "\nFile $File is not exist.\n"
exit
elif [ ! -s "$File" ]
then
echo -e "\nFile $File is empty.\n"
exit
fi
}
done
}
Create_User()
{
LinesUser=`sed -n '/^$/!p' $1|sed -n '$='`
for n in `seq 1 $LinesUser`
do
UserName=`sed -n '/^$/!p' $1|sed -n "${n}p"`
PassWord=`sed -n '/^$/!p' $2|sed -n "${n}p"`
id $UserName &>/dev/null && {
echo -e "\nUser $UserName is exist.\n"
} || {
useradd $UserName
#echo "$PassWord" &>/dev/null |passwd $UserName --stdin
passwd $UserName &>/dev/null <<-EOF
$PassWord
$PassWord
EOF
echo -e "\nUser $UserName Creates Successfully.\n"
}
done
}
Judge_File $1 $2
Create_User $1 $2
文件
执行结果
expect的使用
安装软件
yum install expect -y
操作参数
设定变量
set IP [ lindex $argv 0 ]
监控命令
spawn ssh root@$IP
应答
expect {
"continue" { send "yes\r" ; exp_continue } #继续下一条操作
"password" { send "$PassWord\r" }
}
保留环境
interact
退出环境
expexct eof
指定IP,密进行ssh链接
运行结果
bash环境中可以调用expect脚本,但是expect脚本中无法调用bash环境中的变量
查找某远程主机的主机名
Search()
{
expect<<-EOF
spawn ssh root@172.25.254.241 "hostname"
expect {
"continue" { send "yes\r" ; exp_continue }
"password" { send "redhat\r" }
}
expect eof
EOF
}
Search|tail -1
结果
continue
打印1到10中对2取余为1的值
for N in `seq 1 10`
do
if [ "$((${N}%2))" == "0" ]
then
continue
fi
echo $N
done
结果
break
打印1-10,但是到5停止
#!/bin/bash
for N in seq 1 10
do
if [ “$N” == “5” ]
then
break
fi
echo $N
done
结果
数值运算
运算方式
(())
let
expr
bc
$[]
运算符号
+ 加法
- 减法
* 乘法
/ 除法
% 取余
++ 自加
-- 自减
< 小于
> 大于
+= 加等于
/= 除等于
*= 乘等于
%= 除等于
倒计时程序
#!/bin/bash
[ "$1" == "" ] && {
echo -e "\nWrong args'\n'"
echo -e "Please try usage : sh time.sh MM:SS.\n"
exit 1
}
Minute=`echo $1|awk -F ":" '{print$1}'`
Second=`echo $1|awk -F ":" '{print$2}'`
Time=$((${Minute}*60+${Second}))
for N in `seq $Time -1 1`
do
echo "Now is $N"
sleep 1
done
打印结果
关于换行符号的处理问题
^M的处理
通过crtl+v以及crtl+M在vim生成^M,通过sed进行替换