Bash Shell脚本进阶

时间:2021-10-17 21:45:19

引言

shell脚本中会有一些命令行中不常用的命令,但是在脚本中却非常有用的命令。还有在脚本中有一些常用的功能,有的是自己项目中见到的,有的是网上搜到的,慢慢积累。

Misc

echo -n "please enter a count:"  #加-n表示输出不换行
mkdir -p /home/user/{test,test1,test2} #一次创建多个目录

set命令

用于设置shell特性参数的,通过它可以改变shell运行时的一些特性。

set -x #在脚本运行时先输出脚本的内容
set -u #遇到未定义的变量时,显示错误

参考链接:Bash 脚本 set 命令教程

获取各种名字

parent_dir=$(dirname $(readlink -f $0)) #获取当前脚本所在目录
me=`basename $0` #获取当前脚本的名字
current_user=$(id -un) #获取当前用户名

输出带颜色的字符

输出各种标志性信息特别有用。

function echo_green()  
{  
  COLOR='\033[01;32m'   # green color 
  RESET='\033[00;00m'   # normal color 
  MESSAGE=${@:-"${RESET}"} echo -ne "${COLOR}${MESSAGE}${RESET}" } echo_green "A green message" 

其中,32m表示绿色, 31m表示红色,34m表示蓝色,33m表示黄色。

处理命令行参数

使用shift命令,这个命令的作用是位置参数左移,shift 1就会是$2变为$1,因此可以一直左移来持续判断$1的方式来处理命令行参数,这样参数谁先谁后就没什么影响了。

while [ $# -gt 0 ]; do  
    case $1 in  
    '--option_a' )  
        # TODO 处理--option_a相关的参数 

        # 1)如果--option_a是一个布尔型的参数,那么,直接设置相关的变量,然后shift 1以便处理后面的参数 
        # 2)如果--option_a后面需要跟上一个输入值,那么$2就是相应的输入值,拿到$2后shift 2以便处理后面的参数。 
    '--enable_logging')  
        enable_logging=1  
        shift 1
    ;; #注意:这里必须是两个分号 
    '--file')  
        file=$2;  
        shift 
    ;;  
    'help' | '-h' | '--help')  
        printHelpAndExit
    ;;  
    *)  
        info "Invalid operation $1";  
        printHelpAndExit;;  
    esac  
done 

字符串处理

#去掉前缀
path="target/doc.txt"
echo ${path*/}

#去掉后缀得到文件名
file=foo.tar.gz
echo ${file%.tar.gz}

记录脚本运行了多久

starttime=$(date +%s)  
# some time consuming command 
endtime=$(date +%s)  
timediff=$(( $endtime - $starttime )) 

timediff中国保存了两个时间差,以秒为单位。

登录远程主机进行操作

我们常会有需要在几个主机间操作的需求,比如在本地主机登录到另外一个主机然后执行一些命令。而我们一般般是使用ssh命令,但是在脚本中自动运行我们还是会遇到一些问题,比如怎么输入密码,当然在第一次输入密码后我们可以把公钥加入到远端主机的信任列表来免密码登录。而输入密码我们会使用到expect,如果没有安装就需要先安装。

#!/bin/bash
#将本机加入指定远程主机的信任列表
username="abc"
ipaddress="192.168.0.22"
password="abc123"
ssh_dir="${HOME}/.ssh"

#在指定文件生成公私钥
if [ ! -f ${ssh_dir}/id_rsa.pub ]; then
    ssh-keygen -t rsa -f ${ssh_dir}/id_rsa -q -N ""
    echo "create ${ssh_dir}/id_rsa.pub"
fi

#将以.pub结尾的公钥复制到服务器的~/.ssh/authorized_keys列表中
expect -c " set timeout -1 spawn ssh-copy-id -i ${ssh_dir}/id_rsa.pub -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${username}@${ipaddress} expect { \"password:\" {send \"$password\r\"; exp_continue} }"

在上面脚本执行后,执行ssh就不需要密码了,而通过ssh就可以在远程主机上执行一些命令了。

#简单执行几个命令,可以通过将命令写在双引号里面。
ssh user@remoteNode "cd /home ; ls"
#比较多的时候可以写成一个脚本
ssh user@remoteNode -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null < test.sh

其实以上的功能有一些工具可以实现了,比如python的一些库,所以当脚本比较复杂时,可以考虑使用python这种比较高级的语言以及它丰富的库,避免重复造*。