shell脚本命令

在很多时候,尤其是自动化部署,运维层面,或者工程构建的工程化过程中,我们经常会用到很多shell脚本来帮我们执行很多进程。

新建一个sh文件

新建一个test.sh文件,在里面写入你想要执行的脚本。例如:

echo "输出一段内容"

echo 命令

  • -n 不要输出衍生的新行

  • -e 启用反斜线转义解释

  • -E 禁用反斜线转义解释(默认)

保存之后一定要改变权限,使脚本具有执行权限,然后再执行脚本

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

shell语法

shell变量

定义变量

定义变量时,变量名不加美元符号

your_name="xiaxia"

注意:

  • 变量名和等号之间不能有空格

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

  • 不能使用标点符号。

  • 不能使用bash里的关键字(可用help命令查看保留关键字)

除了显式地直接赋值,还可以用语句给变量赋值,如:

for file in `ls /etc`
# 或
for file in $(ls /etc)

使用变量

只需要在定义过的变量前面加上$即可, 变量外面的{}加不加都行,只是为了辅助识别变量, 推荐加上{}

your_name="qinjx"
echo $your_name
echo ${your_name}

只读变量

myUrl="http://www.google.com"
readonly myUrl

删除变量

unset命令删除变量

unset variable_name

变量类型

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

  • 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

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

shell字符串

shell中字符串使用单引号''、双引号""或者什么都不用都可以。

单引号有一些限制,比如不能使用变量,推荐使用双引号

字符串拼接

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2  $greeting_3

获取字符串长度

string="abcd"
echo ${#string} #输出 4

提取子字符串

以下实例从字符串第 2 个字符开始截取 4 个字符:

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

shell数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

定义数组

数组名=(值1 值2 ... 值n)
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[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

shell注释

  • 单行注释:以 # 开头的行就是注释,会被解释器忽略。

  • 多行注释:shell多行注释有多种方法,不同的方法性能上有一定差异。

    使用:<<字符 注释内容 字符

      :<<EOF
      注释内容...
      注释内容...
      注释内容...
      EOF
    
      # EOF 也可以使用其他符号:
      :<<'
      注释内容...
      注释内容...
      注释内容...
      '
      :<<!
      注释内容...
      注释内容...
      注释内容...
      !

shell传参

echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

执行过程与结果

$ chmod +x test.sh 
$ ./test.sh 1 2 3

Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

几个特殊字符处理参数

参数 | 说明 | ------- | --- $# | 传递到脚本的参数个数 $* | 以一个单字符串显示所有向脚本传递的参数。如$*"括起来的情况、以"$1 $2$n"的形式输出所有参数。 $$ | 脚本运行的当前进程ID号 $! | 后台运行的最后一个进程的ID号 $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。如$@"括起来的情况、以$1 $2$n 的形式输出所有参数。 $- | 显示Shell使用的当前选项,与set命令功能相同。 $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

关于传参的高级用法详细教程请戳这里传送门

shell 运算符

详细教程请戳这里传送门

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awkexprexpr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

val=`expr 2 + 2`
echo "两数之和为 : $val"

# 两数之和为 : 4

注意事项:

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。这个坑当时踩过,原因找了很久

  • 完整的表达式要被 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

shell支持以下算术运算符

  • +

  • -

  • *

  • /

  • %

  • =

  • ==

  • !=

关系运算符 运算符 | 说明| 举例 |:----:|----|---- -eq |检测两个数是否相等,相等返回 true。 |$a -eq $b 返回 false。 -ne |检测两个数是否不相等,不相等返回 true。 | $a -ne $b 返回 true。 -gt |检测左边的数是否大于右边的,如果是,则返回 true。 | $a -gt $b 返回 false。 -lt |检测左边的数是否小于右边的,如果是,则返回 true。 | $a -lt $b 返回 true。 -ge |检测左边的数是否大于等于右边的,如果是,则返回 true。| $a -ge $b 返回 false。 -le |检测左边的数是否小于等于右边的,如果是,则返回 true。| $a -le $b 返回 true。

运算符全称,方便记忆

  • eq (equal的缩写),表示等于为真

  • ne (not equal的缩写),表示不等于为真

  • gt (greater than的缩写),表示大于为真

  • ge (greater&equal的缩写),表示大于等于为真

  • lt (lower than的缩写),表示小于为真

  • le (lower&equal的缩写),表示小于等于为真

布尔运算符

  • !: 非运算

  • -o:或运算

  • -a: 与运算

逻辑运算符

  • &&

  • ||

字符串运算符

文件测试运算符

shell函数

shell还可以定义函数,超出我的意料之外,

[ function ] funname [()]
{
    action;
    [return int;]
}
funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"

函数参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...

注意:

  • $10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用`${n}来获取参数。

shell 命令

echo 输出

echo "It is a test"

# 换行显示
echo -e "OK! \n" # -e 开启转义 
echo "It is a test"

# 不换行
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"

# 显示结果定向至文件
echo "It is a test" > myfile

# 显示命令执行结果 
# 这里使用的是反引号 `, 而不是单引号 '。
echo `date`
# Thu Jul 24 10:08:46 CST 2014

参考

  • 使用 printf 的脚本比使用 echo 移植性好。

  • printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

printf  format-string  [arguments...]

$ echo "Hello, Shell"
# Hello, Shell
$ printf "Hello, Shell\n"
# Hello, Shell

test 检查条件

test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

# 两个数相等!

shell流程控制

和Java、PHP等语言不一样,sh的流程控制不可为空,参考文档

if-else-if-else

if [ condition1 ]
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

特别说明: condition1需要用中括号包裹,并且与中括号之间一定要有空格,不然会有预发错误

for循环

for i in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

while 语句

int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

case

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

跳出循环

Shell使用两个命令来实现该功能:break和continue。

shell 输入/输出重定向

shell include 文件包含

文档

# 注意点号(.)和文件名中间有一空格
. filename   
# 或
source filename

Last updated