shell编程常用技巧与要点

按点列出,不需要逻辑(不定时更新)

  1. 末尾不换行
    echo -n 'roger'

  2. 有两种方法可以将命令输出赋给变量:

    • 反引号字符 ` `
    • $()格式
      技巧:在脚本中通过命令替换获得当前日期并用它来生成唯一文件名
      today=$(date +%y%m%d)
  3. 大段注释
    内联输入重定向符号是远小于号(<<)。除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致.
    如下运行将输出4,前面3行被注释

    #!/bin/bash
    :<< EOF
    echo 1
    echo 2
    echo 3
    EOF
    
    echo 4
    
  4. 数学运算
    一种更简单的方法来执行数学表达式。在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来。例如:

    var1=$[1 + 5]
    echo $var1
    

    bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制

  5. 浮点解决方案
    最常见的方案是用内建的bash计算器,叫作bc。浮点运算是由内建变量scale控制的。必须将这个值设置为你希望在计算结果中保留的小数位数,否则无法得到期望的结果。示例:

    $ bc -q
    3.44 / 5
    0
    scale=4
    3.44 / 5
    .6880
    quit
    $
    

    在脚本中使用

    # 采用形式
    # variable=$(echo "options; expression" | bc)
    var1=$(echo "scale=4; 3.44 / 5" | bc)
    

    当有大量运算的时候,最好的办法是使用内联输入重定向,它允许你直接在命令行中重定向数据。在shell脚本中,你可以将输出赋给一个变量。

    variable=$(bc << EOF
    options
    statements
    expressions
    EOF
    )
    

    EOF文本字符串标识了内联重定向数据的起止。记住,仍然需要命令替换符号将bc命令的输出赋给变量。在bash计算器中创建的变量只在bash计算器中有效,不能在shell脚本中使用。

  6. 查看退出状态码
    退出状态码在0~255的区间
    echo $?
    退出码:

    • 0 命令成功结束
    • 1 一般性未知错误
    • 2 不适合的shell命令
    • 126 命令不可执行
    • 127 没找到命令
    • 128 无效的退出参数
    • 128+x 与Linux信号x相关的严重错误
    • 130 通过Ctrl+C终止的命令
    • 255 正常范围之外的退出状态码

    exit命令允许你在脚本结束时指定一个退出状态码

  7. 使用结构化命令
    if-then语句, 有如下格式。

    判断命令是否执行成功

    if command
    then
      commands
    fi
    

    或者这种形式

    if command; then
      commands
    fi
    

    bash shell的if语句会运行if后面的那个命令。如果该命令的退出状态码(参见第11章)是0(该命令成功运行),位于then部分的命令就会被执行。如果该命令的退出状态码是其他值, then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令。fi语句用来表示if-then语句到此结束。

    if-then-else语句在语句中提供了另外一组命令。

    if command
    then
      commands
    else
      commands
    fi
    

    使用这个嵌套更易读:

    if command1
    then
      commands
    elif command2
    then
      more commands
    fi
    
  8. 测试方法
    (1) 使用test命令
    test命令可以判断三类条件:
     数值比较
     字符串比较
     文件比较

$ cat test6.sh

#!/bin/bash
#Testing the test command
my_variable=“Full”
if test $my_variable
then
echo “The $my_variable expression returns a True”
else
echo “The $my_variable expression returns a False”
fi

$ ./test6.sh

The Full expression returns a True

(2) 方括号定义了测试条件
无需在if-then语句中声明test命令。

if [ condition ]
then
  commands
fi

方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

  1. test命令的数值比较功能(只限制在整数中比较)
    n1 -eq n2 检查n1是否与n2相等
    n1 -ge n2 检查n1是否大于或等于n2
    n1 -gt n2 检查n1是否大于n2
    n1 -le n2 检查n1是否小于或等于n2
    n1 -lt n2 检查n1是否小于n2
    n1 -ne n2 检查n1是否不等于n2

  2. 字符串比较测试
    str1 = str2 检查str1是否和str2相同
    str1 != str2 检查str1是否和str2不同
    str1 \< str2 检查str1是否比str2小
    str1 \> str2 检查str1是否比str2大
    -n str1 检查str1的长度是否非0
    -z str1 检查str1的长度是否为0

在比较字符串的相等性时,比较测试会将所有的标点和大小写情况都考虑在内
大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件
名;

大于和小于顺序和sort命令所采用的不同。

在比较测试中,大写字母被认为是小于小写字母的。但sort命令恰好相反。当你将同样的字符串放进文件中并用sort命令排序时,小写字母会先出现。这是由各个命令使用的排序技术不同造成的。

比较测试中使用的是标准的ASCII顺序,根据每个字符的ASCII数值来决定排序结果。sort
命令使用的是系统的本地化语言设置中定义的排序顺序。对于英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前。

空的和未初始化的变量会对shell脚本测试造成灾难性的影响。如果不是很确定一个变量的
内容,最好在将其用于数值或字符串比较之前先通过-n-z来测试一下变量是否含有值

  1. 文件比较
    -d file 检查file是否存在并是一个目录
    -e file 检查file是否存在
    -f file 检查file是否存在并是一个文件
    -r file 检查file是否存在并可读
    -s file 检查file是否存在并非空
    -w file 检查file是否存在并可写
    -x file 检查file是否存在并可执行
    -O file 检查file是否存在并属当前用户所有
    -G file 检查file是否存在并且默认组与当前用户相同
    file1 -nt file2 检查file1是否比file2新
    file1 -ot file2 检查file1是否比file2旧

  2. 复合条件测试
    if-then语句允许你使用布尔逻辑来组合测试。有两种布尔运算符可用:
     [ condition1 ] && [ condition2 ]
     [ condition1 ] || [ condition2 ]

  3. if-then 的高级特性
    bash shell提供了两项可在if-then语句中使用的高级特性:
     用于数学表达式的双括号
     用于高级字符串处理功能的双方括号

双括号命令符号
val++ 后增
val-- 后减
++val 先增
--val 先减
! 逻辑求反
~ 位求反
** 幂运算
<< 左位移
>> 右位移
& 位布尔和
| 位布尔或
&& 逻辑和
|| 逻辑或

可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。
$ cat test23.sh

#!/bin/bash
#using double parenthesis
val1=10
if (( $val1 ** 2 > 90 ))
then
(( val2 = $val1 ** 2 ))
echo “The square of $val1 is $val2”
fi

$ ./test23.sh

The square of 10 is 100

注意,不需要将双括号中表达式里的大于号转义。这是双括号命令提供的另一个高级特性。

  1. 使用双方括号
    双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命
    令未提供的另一个特性——模式匹配
    $ cat test24.sh

#!/bin/bash
#using pattern matching
if [[ $USER == r* ]]
then
echo “Hello $USER”
else
echo “Sorry, I do not know you”
fi

$ ./test24.sh

Hello rich

在上面的脚本中,我们使用了双等号(==)。双等号将右边的字符串(r*)视为一个模式,并应用模式匹配规则。双方括号命令$USER环境变量进行匹配,看它是否以字母r开头。如果是的话,比较通过,shell会执行then部分的命令。

  1. case
case variable in
pattern1 | pattern2) 
  commands1;;
pattern3) 
  commands2;;
*) 
  default commands;;
esac

你可能感兴趣的:(编程,shell,shell,编程,技巧)