代码改变世界

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
View Code

 递归遍历文件

#!/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 

 

 

------------------------------------------