Linux Shell 脚本基础
2020-01-13 16:54 清晨、午后 阅读(154) 评论(0) 编辑 收藏 举报使用“:set paste” 来实现vim 按照源文件格式复制
#!/bin/bash
在Unix中,凡是被 #! 注释的,统统是指明加载器(解释器)的路径,也就是声明用哪个程序来运行本文件。 比如: #!/bin/bash #上面的意思是说,把下面的字符统统传递给/bin/bash echo "Hello Boy!" ... 当然,还有很多。 #!/bin/lua #!/bin/perl #!/bin/python
# 终止执行
exit 2
接收用户参数
#!/bin/bash echo "当前脚本名称:$0" echo "参数个数: $#" #个数不包含脚本名称,与 python 不同 echo "参数 list: $*" echo "第一个参数 $1" echo "==============" ls echo "==============" echo "上次命令返回值:$?"
文件测试语句
-b file 如果文件为一个块特殊文件,则为真 -c file 如果文件为一个字符特殊文件,则为真 -d file 如果文件为一个目录,则为真 -e file 如果文件存在,则为真 -f file 如果文件为一个普通文件,则为真 -g file 如果设置了文件的 SGID 位,则为真 -G file 如果文件存在且归该组所有,则为真 -k file 如果设置了文件的粘着位,则为真 -O file 如果文件存在并且归该用户所有,则为真 -p file 如果文件为一个命名管道,则为真 -r file 如果文件可读,则为真 -s file 如果文件的长度不为零,则为真 -S file 如果文件为一个套接字特殊文件,则为真 -t fd 如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真 -u file 如果设置了文件的 SUID 位,则为真 -w file 如果文件可写,则为真 -x file 如果文件可执行,则为真
-h file 是否连接文件
-L file 是否连接文件
lyb@lyb-virtual-machine:~/work$ [ -f example.sh ] lyb@lyb-virtual-machine:~/work$ echo $? 0 lyb@lyb-virtual-machine:~/work$ [ -f example2.sh ] lyb@lyb-virtual-machine:~/work$ echo $? 1 lyb@lyb-virtual-machine:~/work$ [ -d example2.sh ] lyb@lyb-virtual-machine:~/work$ echo $? 1
*条件表达式两侧均应留空格
逻辑语句,与 c++ 含义一样
逻辑与 && // 前面的条件成立才会执行后面的
逻辑或 ||
逻辑非 !
cmd1 && cmd2 #若 cmd1 执行完毕且正确执行($?=0),则开始执行 cmd2,否则不执行cmd2 cmd1 || cmd2 #若 cmd1 执行完毕且正确执行($?=0),则 cmd2 不执行,否则执行cmd2
lyb@lyb-virtual-machine:~/work$ [ -f example.sh ] && echo "文件存在" 文件存在
字符串比较运算符
= // 是否相同
!= // 是否不同
-z // 是否为空
lyb@lyb-virtual-machine:~/work$ [ dfd = dfd ] lyb@lyb-virtual-machine:~/work$ echo $? 0 lyb@lyb-virtual-machine:~/work$ [ dfd = dfdw ] lyb@lyb-virtual-machine:~/work$ echo $? 1
if [ -z STRING ] # “STRING” 的长度为零则为真
整数比较运算符
-eq // ==
-ne // !=
-gt // >
-lt // <
-le // <=
-ge // >=
= // 特定条件下是赋值,如 numer=27,注意前后不能带空格
lyb@lyb-virtual-machine:~/work$ [ 10 -eq 9 ] lyb@lyb-virtual-machine:~/work$ echo $? 1
lyb@lyb-virtual-machine:~/work$ number=27 lyb@lyb-virtual-machine:~/work$ echo $number 27
if 条件测试语句
#!/bin/bash read -p "Enter your score(0-100):" GRADE if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then echo "$GRADE is Excellent" elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then echo "$GRADE is Pass" else echo "$GRADE is Fail" fi
for 条件循环语句
#!/bin/bash read -p "Enter the users password:" PASSWD # users.txt 中存放用户名,每行一个 for UNAME in `cat users.txt` do
# id uname // 查看用户信息,用户不存在时返回非0 id $UNAME &> /dev/null if [ $? -eq 0 ]; then echo "Already exists" else useradd $UNAME &> /dev/null
# 设置用户密码 echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null if [ $? -eq 0 ]; then echo "$UNAME create success" else echo "$UNAME create failure" fi fi done
#遍历数组
type_name=(error warning style performance portability information) for value in "${type_name[@]}" do echo ${value} done
while 条件循环语句
#!/bin/bash PRICE=$(expr $RANDOM % 1000) TIMES=0 echo "商品价格为0-999,猜猜看是多少?" while true do read -p "输入猜测的价格:" INT let TIMES++ if [ $INT -eq $PRICE ]; then echo "回答正确,价格是: $PRICE" echo "总共猜测次数: $TIMES" exit 0 elif [ $INT -gt $PRICE ]; then echo "太高了" else echo "太低了" fi done
case 条件测试语句
#!/bin/bash read -p "请输入一个字符,按Enter确认:" KEY case "$KEY" in [a-z] | [A-Z]) echo "您输入的是 字母" ;; [0-9]) echo "您输入的是 数字" ;; *) echo "$KEY 不是单个字母或数字" esac
带颜色输出、人机交互
-e :表示带格式,
-n:不换行
echo -en "\033[1;32m info: \033[0m" echo "parameters list: $*"
参数 -e
#!/bin/sh -e
如果携带参数 -e 一旦某个命令执行后返回非0($? 的值),脚本自动退出
常用脚本
// 复制 bbb.txt 中以 / 开头的文件到指定目录,如果是链接文件,则找到真实文件复制
#!/bin/bash
for filepath in `cat bbb.txt`
do
if [[ ${filepath:0:1} = "/" ]] ; then
if [[ -L $filepath ]] ; then
while [ -h $filepath ]
do
b=`ls -ld $filepath|awk '{print $NF}'`
c=`ls -ld $filepath|awk '{print $(NF-2)}'`
[[ $b =~ ^/ ]] && filepath=$b || filepath=`dirname $c`/$b
done
cp -f $filepath /home/ceph-service/LIB
else
cp -f $filepath /home/ceph-service/LIB
fi
# else
#echo $filepath
fi
done
睡眠
sleep 1s 睡眠1秒
sleep 1m 睡眠1分
sleep 1h 睡眠1小时
函数
#!/bin/bash basepath=$(cd `dirname $0`; pwd) logpath=` awk -F '=' '/\[base\]/{a=1}a==1&&$1~/logpath/{print $2;exit}' $basepath/kmsd.conf` logpath=`eval echo $logpath` echo "ip: $logpath" master_ip=` awk -F '=' '/\[base\]/{a=1}a==1&&$1~/ip/{print $2;exit}' $basepath/kmsd.conf` master_ip=`eval echo $master_ip` echo "ip: $master_ip" master_port=` awk -F '=' '/\[base\]/{a=1}a==1&&$1~/port/{print $2;exit}' $basepath/kmsd.conf` master_port=`eval echo $master_port` echo "port: $master_port" process_name="kmstools" kill_process(){ pids=`ps -ef | grep "$process_name" | grep -v "$0" | grep -v "grep" | awk '{print $2}'` echo "pid list:"$pids for pid in $pids do kill -9 $pid echo "killed $pid" done } send_email(){ if [ $1 != $2 ];then if [ true == $2 ];then echo "send email succeed" else echo "send email failed" fi fi } date >> $logpath echo "kmsd start" >> $logpath echo "kmsd start" file_name=$0 if [ `pgrep -f ${file_name} | wc -l` -gt 2 ];then echo "${file_name} process existed, will be exit." >> $logpath echo "${file_name} process existed, will be exit." exit 1 fi password="123456" isconnect=true while true do nc -z $master_ip $master_port nc_ret=$? if [ 0 -eq $nc_ret ];then send_email $isconnect true echo "succeed" isconnect=true else send_email $isconnect false # 无论何种原因导致端口无法访问,直接暴力的Kill掉进程后重启,是否可行??? echo "failed" kill_process kmstools & isconnect=false fi sleep 1s done
递归遍历文件
#!/bin/bash dir=$1 function getdir() { for element in `ls $1` do fileName=$1"/"$element if [ -d $fileName ]; then getdir $fileName else fileType=`file $fileName | grep shared` if [ -z $fileType ]; then continue fi findSoFile=`ldd $fileName | grep gweed` if [ -z $findSoFile ]; then continue fi echo $fileName fi done } getdir $dir
------------------------------------------