阅读 11

Shell脚本

Hello world

shell脚本和一般程序并没有太多的差别,脚本文件基本形态,以#开头表示注释,直到行末,先来个Hello world吧

#!/bin/sh             # 声明shell脚本解释器,没有声明则使用默认的shell解释器,不同的shell解释器语法有一定的区别,所以都要加上此句
a = "hello world"     # 变量不需要定义,无数据类型
echo $a               # 输出 hello world
echo "output ${a}abc" # 输出 output hello worldabc (如果变量后面还有字符则用{}括起来,$表示取变量的值)
复制代码

保存为test文件,使用命令行执行./test,输出为output hello worldabc

系统变量

条件表达式

语法规则

if语句

if [表达式]         # 表达试多个组合情况下和C一样,前面已经成立的后面就不再执行
then
[语句组]
elif [表达式]       # else if
then
[语句组]
else
[语句组]
fi
复制代码

for语句

for 变量 in 值的范围(可用通配符,命令的输出等)
do
[语句组]
done

例:
a=2
for a in 1 2 3 "ab"c   # 循环体执行4次
do
echo $a
done
输出为:123abc
复制代码

while语句

while [表达式]
do
[语句组]
done
复制代码

until语句

until [表达式]   # 表达式为真时退出循环
do
[语句组]
done
复制代码

case语句

case 变量 in 
情况1[|情况2...]) 语句组 ;;    # ;;表示break 
情况3[|情况4...]) 语句组 ;;
...
*) 语句组 ;;                  # 相当于default
esac

例:
#!/bin/sh
read a   # 等待输入
case "$a" in
y|yes) echo "yes" ;;
n|no) echo "no" ;;
*) echo "default"
esac
复制代码

函数

定义:函数名() (没有返回值类型、参数,写在调用前面)

#!/bin/sh
fun(){
    echo $1
    echo $2
    return 0
}

echo "call fun"
a = fun aa bb
echo $a

理论输出(获取返回值可能出错):call fun aa bb 0
复制代码

获取返回值后函数中的echo可能不会显示,全被捕获到返回值中(待验证) 函数中声明局部变量在变量前加local

fun(){
    local a
    a = 10
    ...
}
复制代码

break命令

用于跳出循环(for while until),可以带一个参数,表示跳出循环的层数

for [表达式]
do
    [语句组]
    if [表达式]
    then
        beeak;    # ;可有可无
    fi
done
复制代码

:命令

空操作,相当于true或汇编中的nop(),但效率高,用于while : (也就是我们C中常用的while(true))

continue命令

用法和C相同(结束本次循环继续下一个)

.命令

代表当前目录,例如执行当前目录下的test文件 ./test

eval命令

将表达式得到的结果以shell的形式再执行一次

#!/bin/sh
foo = 10
x = foo
y = '$'$x
echo $y

输出:$foo

#!/bin/sh
foo = 10
x = foo
eval y = '$'$x     # 等效于y = $(($x)) (应该是y = eval '$'$x吧,待验证)
echo $y

输出:10
复制代码

exec命令

执行另一个shell程序,执行完不会再返回,exec命令后面的语句不会被执行

#!/bin/sh
exec echo "execute"
echo "next"    # 不会被执行
复制代码

exit命令

退出程序,可带一个参数,0表示正常退出

export命令

导出,相当于C中.h文件的变量声明,给不同的文件使用 export1文件

#!/bin/sh
foo = "aaa"
export foo
./export2
复制代码

export2文件

#!/bin/sh
echo "$foo"
复制代码

输出:aaa

set命令

设置参数到s1、s2、s3...

#!/bin/sh
echo $(data)    # data获取系统时间
set $(data)
echo $2         # $2中保存着月份
复制代码

unset命令

删除变量

#!/bin/sh
foo = "aaa"
unset foo
echo $foo       # 输出为空
复制代码

declare命令

Linux declare命令用于声明 shell 变量。

shell定义字典

declare -A dic
dic=([key1]="value1" [key2]="value2" [key3]="value3")
复制代码

打印指定key的value

echo ${dic["key1"]}
复制代码

打印所有key值

echo ${!dic[*]}
复制代码

打印所有value

echo ${dic[*]}
复制代码

字典添加一个新元素

dic+=([key4]="value4"复制代码

遍历key值

for key in $(echo ${!dic[*]})
do
    echo "$key : ${dic[$key]}"
done
复制代码

shell定义数组

list=("value1" "value2" "value3")
复制代码

打印指定下标

echo ${list[1]}
复制代码

打印所有下标

echo ${!list[*]}
复制代码

打印数组下标

echo ${list[*]}
复制代码

数组增加一个元素

list=("${list[@]}" "value3")
复制代码

按序号遍历

for i in "${!arr[@]}"; do 
    printf "%s\t%s\n" "$i" "${arr[$i]}"
done
复制代码

按数据遍历

for NUM in ${ARR[*]}
do
    echo $NUM
done
复制代码

按照某一格式切割保存到数组

按照逗号切割字符串,将逗号转为空格,因为shell定界符默认是空格

array=${var//,/ }
复制代码

其中IFS保存的是shell定界符

OLD_IFS="$IFS"
IFS=","
array=($var)
IFS="$OLD_IFS"
复制代码

遍历数组

for element in ${arr[@]}
do
    ...
done
复制代码

if[X$1 = X];then

是用来测试命令列上有没有参数。

$1 可以换成指定变量,判断变量是否有值。

if[$? -ne 0];then

$?是最近执行的命令的退出状态;

按惯例,0表示成功,其他任何表示失败。

此语句检测最近执行的命令返回状态是否成功。

rm

删除文件或目录

-r, -R, --recursive

以递归方式删除目录及其内容

-f, --force

忽略不存在的文件,永远不会提示

/

删除(取消链接)文件。

打印或设置系统日期和时间

`date +%s`
复制代码

expr

评估表达式

sed

用于过滤和转换文本的流编辑器

-i[SUFFIX], --in-place[=SUFFIX]

在指定位置编辑文件(如果提供扩展,则进行备份)

-e, --expression, -f, or --file

在指定文件插入指定表达式

-n, --quiet, --silent

suppress automatic printing of pattern space

检测三种不同的操作系统类型(GNU / Linux,Mac OS X,Windows NT)

在你的bash脚本中,使用#!/ usr / bin / env bash而不是#!/ bin / sh来防止/ bin / sh导致的问题链接到不同平台的不同默认shell,否则会出现意外运算符等错误。

Mac OS X 10.6.8(Snow Leopard)没有expr程序,除非你安装了,所以我只使用uname。

#!/usr/bin/env bash

if [ "$(uname)" == "Darwin" ]; then
    # Do something under Mac OS X platform        
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
    # Do something under GNU/Linux platform
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then
    # Do something under 32 bits Windows NT platform
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
    # Do something under 64 bits Windows NT platform
fi
复制代码

cp -R

复制文件和目录

-R, -r, --recursive

递归复制目录

关注下面的标签,发现更多相似文章
评论