BASH脚本语法汇集

特殊字符

#        注释.
;        命令分隔符,可以在同一行上写两个或两个以上的命令.
;;        终止case选项.
.        "点"命令等价于source命令.
         "点"作为文件名的一部分. 如果点放在文件名的开头的话, 那么这个文件将会成为隐藏文件,
         "点"字符匹配. "点"用来匹配任何的单个字符.
""       部分引用[双引号, 即"]. "STRING"将会阻止(解释)STRING中大部分特殊的字符.
''       全引用[单引号, 即']. 'STRING'将会阻止STRING中所有特殊字符的解释. 这是一种比使用"更强烈的形式.
,        逗号操作符. 逗号操作符链接了一系列的算术操作. 虽然里边所有的内容都被运行了,但只有最后一项被返回.
\        转义符[反斜线, 即\]. 一种对单字符的引用机制.
/        文件名路径分隔符[斜线, 即/],也可以用来作为除法算术操作符.
``       命令替换. 已逐渐被$()替代,后者更灵活,如可以嵌套等
:        空命令[冒号, 即:]. 也可以被认为与shell的内建命令true作用相同.
!        取反操作符[叹号, 即!].
*        通配符[星号, 即*]. *可以用来做文件名匹配,也可以用在正则表达式中, 用来匹配任意个数(包含0个)的字符.
         算术操作符. 在算术操作符的上下文中, *号表示乘法运算.
         如果要做求幂运算, 使用**, 这是求幂操作符.
?        测试操作符. 在一个特定的表达式中, ?用来测试一个条件的结果.
         在一个双括号结构中, ?就是C语言的三元操作符.
         在参数替换表达式中, ?用来测试一个变量是否被set了.
         通配符. ?在通配(globbing)中, 用来做匹配单个字符的"通配符".
$        变量替换(引用变量的内容).
         行结束符. 在正则表达式中, "$"表示行结束符.
${}      参数替换.
$*       位置参数
$@       同上.
$?       退出状态码变量. $?变量保存了一个命令, 一个函数, 或者是脚本本身的退出状态码.
$$       进程ID变量. 这个$$变量保存了它所在脚本的进程ID.
()       命令组.
{}       代码块,又被称为内部组, 这个结构事实上创建了一个匿名函数(一个没有名字的函数).
[]       条件测试.数组元素.用作正则表达式的一部分, 方括号描述一个匹配的字符范围.
[[]]     测试.
(())     整数扩展.
>
&>
>&
>>
<
<>       重定向.
<<       用在here document中的重定向.http://doc.linuxpk.com/doc/abs/here-docs.html#HEREDOCREF
<<<      用在here string中的重定向.
<
>        ASCII comparison.
\<
\>       正则表达式中的单词边界.
|        管道.
>|       强制重定向(即使设置了noclobber选项 -- 就是-C选项). 这将强制的覆盖一个现存文件.
||       或-逻辑操作.
&        后台运行命令.
&&       与-逻辑操作.
-        选项, 前缀.
         用于重定向stdin或stdout[破折号, 即-].
         先前的工作目录.
         减号. 减号属于算术操作.
=        等号. 赋值操作,"="也用来做字符串比较操作.
+        加号. 加法算术操作.某些命令内建命令使用+来打开特定的选项, 用-来禁用这些特定的选项.
%        取模. %也是一种模式匹配操作. 在BASH中,%number表示将后台编号为number的任务调度到前台执行。
~        home目录[波浪号, 即~].
~+       当前工作目录. 相当于$PWD内部变量.
~-       先前的工作目录. 相当于$OLDPWD内部变量.
=~       正则表达式匹配. 这个操作将会在version 3版本的Bash部分进行讲解.
^        行首. 在正则表达式中, "^"表示定位到文本行的行首.

文件测试

-e       文件存在.
-f       表示这个文件是一个一般文件.
-d       表示这是一个目录.
-b       表示这是一个块设备.
-c       表示这是一个字符设备.
-p       这个文件是一个管道
-s       文件大小不为零.
-L       这是一个符号链接
-S       表示这是一个socket
-t       文件(描述符)被关联到一个终端设备上.
         这个测试选项一般被用来检测脚本中的stdin([ -t 0 ]) 或者stdout([ -t 1 ])是否来自于一个终端.
-r       文件是否具有可读权限(指的是正在运行这个测试命令的用户是否具有读权限)
-w       文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有写权限)
-x       文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限)
-g       set-group-id(sgid)标记被设置到文件或目录上
-u       set-user-id (suid)标记被设置到文件上
-k       设置粘贴位
-O       判断你是否是文件的拥有者
-G       文件的group-id是否与你的相同
-N       从文件上一次被读取到现在为止, 文件是否被修改过
!        "非" -- 反转上边所有测试的结果(如果没给出条件, 那么返回真).

比较操作

  • 文件比较

    f1 -nt f2
        文件f1比文件f2新
    f1 -ot f2
        文件f1比文件f2旧
    f1 -ef f2
        文件f1和文件f2是相同文件的硬链接
    
  • 整数比较

    -eq        等于
    -ne        不等于
    -gt        大于
    -ge        大于等于
    -lt        小于
    -le        小于等于
    <          小于
    <=         小于等于
    >          大于
    >=         大于等于
    
  • 字符串比较

    =          等于
    ==         等于
    !=         不等号
    <          小于, 按照ASCII字符进行排序
    >          大于, 按照ASCII字符进行排序
    -z         字符串为"null", 意思就是字符串长度为零
    -n         字符串不为"null".
    -l         字符串长度
    
  • 逻辑操作

    -a         逻辑与
    -o         逻辑或
    !          逻辑非
    

参数替换

  • 参数扩展

    ${parameter}        与$parameter相同, 在某些上下文中, ${parameter}很少会产生混淆.
    ${parameter-default}    如果变量parameter没声明, 那么就使用默认值.
    ${parameter:-default}    如果变量parameter没设置, 那么就使用默认值.
    ${parameter=default}    如果变量parameter没声明, 那么就把它的值设为default.
    ${parameter:=default}    如果变量parameter没设置, 那么就把它的值设为default.
    ${parameter+value}    如果变量parameter被声明了, 那么就使用value, 否则就使用null字符串.
    ${parameter:+value}    如果变量parameter被设置了, 那么就使用value, 否则就使用null字符串.
    ${parameter?err_msg}    如果parameter已经被声明, 那么就使用设置的值, 否则打印err_msg错误消息.
    ${parameter:?err_msg}    如果parameter已经被设置, 那么就使用设置的值, 否则打印err_msg错误消息.
    
  • 子串删除

    ${#var}            字符串长度(变量$var的字符个数). 对于array来说, ${#array}表示的是数组中第一个元素的长度.
    ${var#Pattern}        从变量$var的开头删除最短匹配$Pattern的子串.
    ${var##Pattern}        从变量$var的开头删除最长匹配$Pattern的子串.
    ${var%Pattern}        从变量$var的结尾删除最短匹配$Pattern的子串.
    ${var%%Pattern}        从变量$var的结尾删除最长匹配$Pattern的子串.
    
  • 子串替换

    ${var:pos}        变量var从位置pos开始扩展(译者注: 也就是pos之前的字符都丢弃).
    ${var:pos:len}        变量var从位置pos开始, 并扩展len个字符.
    ${var/Pat/Rep}        使用Rep来替换变量var中第一个匹配Pat的字符串.
    ${var//Pat/Rep}        使用Rep来替换变量var中的所有匹配Pat的字符串.
    ${var/#Pat/Rep}        如果变量var的前缀匹配Pat, 那么就使用Rep来替换匹配到Pat的字符串.
    ${var/%Pat/Rep}        如果变量var的后缀匹配Pat, 那么就使用Rep来替换匹配到Pat的字符串.
    
    ${!varprefix*}
    ${!varprefix@}        匹配所有之前声明过的, 并且以varprefix开头的变量.
    

进程替换

>(command)
<(command)

变量定义

declare用法

-r        只读
-i         整型
-a         数组
-f         函数
-x export    这句将会声明一个变量, 并作为这个脚本的环境变量被导出.
-x var=$value    允许在声明变量类型的同时给变量赋值.

控制结构

  • if结构

    if  command
    then
            command
    elif  command
    then
            command
    else
            command
    fi
    例:
    var=70;
    if (($var<60))
    then
        echo "too bad"
    elif (($var>90))
    then
        echo "very good"
    else
        echo "OK"
    fi
    
  • case结构

    case variable in
    value1)
            command1
            ;;
    value2)
            command2
            ;;
    *)
            command3
            ;;
    esac
    例:
    cat << ENDIT
            1)one
            2)two
    ENDIT
    read choice;
    case "$choice" in
    1)
            echo "one"
            ;;
    2)
            echo "two"
            ;;
    *)
            echo "Error"
            ;;
    esac
    
  • for结构

    for variable in world_list
    do
            command
    done
    例:
    for line in ~/*
    do
            echo $line;
    done
    
    for (( i=$loop; i != 0; i-- )); do
            echo "hello"
    done
    
  • while结构

    while command
    do
            command
    done
    例:
    var=1
    while ((var<=30))
    do
            echo $var
            let "var=var+1"
    done
    
  • 函数使用

    function() {
      ........
    }
    
    $1-9  1-9个参数
    $#    参数的数量
    $@    所有参数,但是所有参数都是一个字符串
    $*    所有参数,但每个参数都是一个单独元素
    
  • 运算命令
    loop=$(((31-16)/8))
    echo $loop
    用$(())命令可以进行数学计算

  • 重定向
    一般情况下重定向命令只会把内容重定向到一个地方,比如要么到标准输出,要么到文件。使用tee重定向可以将标准输出同时重定向到标准输出和文件中,但是不能得到标准错误输出的内容。下面的方式可以在标准输出上看到内容,同时将标准输出和错误输出都记录到文件中:

    #!/bin/sh
    cmd="/builds/tools/cnrdmk78.sh jsr > /dev/stdout 2>&1"
    eval $cmd | tee aaa
    

    第一句将标准输出和错误输出全部重新放到标准输出里面,这样就可以在屏幕上看到输出的内容。这里有2个需要注意的地方,首先是整个命令要放进一个变量里(因为要重定向2次),其次是不能用 >& 的方式而必须分开来写。

    第二句则执行上面的重定向命令,然后将输出放进aaa文件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容