因为大部分的工作都是重复的,使用脚本会极大地提升自身工作效率。实际工作中有很长时间在使用shell做一些操作,平时也会写一些脚本简化自己的操作,但是基本都是命令的罗列,也就是顺序式编程,很低级。因此决定系统地学习一下shell编程更加提升自我效率。

运行shell脚本的两种方式

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

  • 作为可执行程序

    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本

    ./的意思是在当前目录寻找test.sh文件,如果不加的话就回去PATH中找,通常都是找不到的。

  • 作为解释器参数

    /bin/sh test.sh
    /bin/php test.php

    这种方式运行的脚本,不需要在第一行指定解释器信息(#!/bin/bash),写了也没用。

Shell 变量

定义变量 =

变量定义要满足如下规则:

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。

使用变量 ${}

在变量名前加上$符号即可。特殊情况下需要在变量名外加上{}

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

这样做是为了识别变量边界。推荐做法~

只读变量 readonly

#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
myUrl="http://www.github.com"

运行脚本得到如下结果:

/bin/sh: NAME: This variable is read only.

删除变量 unset

变量被删除后不能再次使用,将读不到任何相关值,不能删除只读变量。

变量类型

  1. 局部变量:

    局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

  2. 环境变量 (/etc/profile.bash_profile/etc/bashrc/etc/profile.d):

    通常是放在以上文件中的变量,也可以使用export自己定义,但是只有写入文件的变量可以在当前shell断开后接着使用。

  3. shell变量

    shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。

Shell 字符串

单引号 ‘’
  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号””
  • 双引号里可以有变量
  • 双引号里可以出现转义字符
字符串相关函数
  • 获取字符串长度: ${#string}

  • 提取子字符串: ${string:1:4} 从哪个字符开始截,截几位

    string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo
  • 查找子字符串:

    string="runoob is a great site"
    echo `expr index "$string" io`  # 输出 4

Shell 数组

bash仅支持一维数组。

定义数组
array_name=(value0 value1 value2 value3)

#或者

array_name=(
value0
value1
value2
value3
)

#单独定义分量

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

## 可以不使用连续的下标,而且下标的范围没有限制。
读取数组
# 一般格式 ${数组名[下标]}

valuen=${array_name[n]}

# 使用 @ 符号可以获取数组中的所有元素
echo ${array_name[@]}


# 获取数组的长度
length=${#array_name[@]}
#或者
length=${#array_name[*]}

#单个元素长度
${#array_name[n]}
注释
:<<EOF
注释内容...
注释内容...
注释内容...
EOF

# EOF可以用其他内容代替
:<<!
注释内容...
注释内容...
注释内容...
!

实践Demo

向其他机器拷贝文件
#!/bin/bash

echo "ready to cp $@ to all nodes >>>>>>>>>"

if [ $# -lt 1 ];then
    echo "need files!"
    exit -1
fi

for file in $@;do
    if [ ! -f $file  ]; then
        echo "$file is not a file!"
        exit -1
    fi
done

for i in notestorage026 notestorage027 notestorage028 notestorage029 notestorage030;do
    echo "start handle files for $i"
    for file in $@;do
            echo "start scp $file to $i"
            scp $file $i:/disk1/cloudstorage/
            echo "scp $file to $i done"
    done
done
启动其他机器的脚本
#!/bin/bash

for i in notestorage026 notestorage027 notestorage028 notestorage029 notestorage030;do
    echo "start init $i"
    ssh -T $i <<'ENDSSH'  
    cd /disk1/cloudstorage
    sh deploy-storeserver.sh

    #cd /disk1/cloudstorage/ServerCommons
    #sh my_deploy.sh
ENDSSH
    echo "deploy $i done"

done

参考

  1. https://www.runoob.com/linux/linux-shell-variable.html
  2. https://blog.csdn.net/Apollon_krj/article/details/70148022


编程   linux      linux

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!