运维开发网

Advanced Bash-Shell Guide(Version 10) 学习笔记一

运维开发网 https://www.qedev.com 2020-02-15 11:03 出处:网络 作者:蒋文华
Advanced Bash-Shell Scripts 作为学习shell的必备书籍,他面向读者没有脚本编写的经验,里面包含了大量的脚本,通俗易懂。这篇是开篇,后续还会继续写,请大家关注。

我喜欢的一句话

the only way to really learn scripting is to write scripts

学习脚本的唯一方法就是写脚本

更好的命令行参数检测

    E_WRONGARGS=85 # Non-numerical argument (bad argument format).

    41 #

    42 # case "$1" in

    43 # "" ) lines=50;;

    44 # *[!0-9]*) echo "Usage: `basename $0` lines-to-cleanup";  

    参数中间没有数字,无效参数

    45 # exit $E_WRONGARGS;;

    46 # * ) lines=$1;;

    47 # esac

更有效的目录检测

    3 # cd /var/log || {

    64 # echo "Cannot change to necessary directory." >&2

    65 # exit $E_XCD;

    66 # }

    #!/bin/sh invokes the default shell interpreter, which

    defaults to /bin/bash on a Linux machine.

    #!/bin/bash 叫做sha-bang  magic number

测试调用的参数数量是否正确

    1 E_WRONG_ARGS=85

    2 script_parameters="-a -h -m -z"

    3 # -a = all, -h = help, etc.

    4

    5 if [ $# -ne $Number_of_expected_args ]

    6 then

    7 echo "Usage: `basename $0` $script_parameters"

    8 # `basename $0` is the script's filename.

    9 exit $E_WRONG_ARGS

    10 fi

调用脚本

    bash scriptname

    chmod 555 scriptname (gives everyone read/execute permission) [9]

    or

    chmod +rx scriptname (gives everyone read/execute permission)

    chmod u+rx scriptname (gives only the script owner read/execute permission)

    ./scriptname

    1 #!/bin/rm

    2 # Self-deleting script.

    echo "This line will never print (betcha!)."

    这是一个自杀的脚本

    # Nothing much seems to happen when you run this...

    except that the file disappears.

将文档改成#!/bin/more 并且添加可执行权限

结果就是自列表文档 类似cat XX | more

特殊字符

# 注释 ,行开头#注释,不被执行,取消语法检测

    在引号和逃逸符里面不是注释

        

    6 echo ${PATH#*:} # Parameter substitution, not a comment.

    7 echo $(( 2#101011 )) # Base conversion, not a comment.

; 命令分隔符

    1 echo hello; echo there

;;     case选项分隔符

    1 case "$variable" in

    2 abc) echo "\$variable = abc" ;;

. 相当于source 刷新配置文件,重新加载

   作为文件名称的一部分,隐藏文件

    

   相当于当前目录,..相当于上级目录

    在正则表达式中匹配单个字符

"    部分引用或弱引用,抑制大部分的特殊字符

'    强引用,抑制所有的特殊字符

,    链接一串算数操作,只返回最后的结果

    1 let "t2 = ((a = 9, 15 / 3))"

    2 # Set "a = 9" and "t2 = 15 / 3"

    链接字符串

    1 for file in /{,usr/}bin/*calc

    2 # ^ Find all executable files ending in "calc"

    3 #+ in /bin and /usr/bin directories.

\    逃逸字符,表达字符字面值的意思

/     文件路径分隔符

`    输出命令结果给变量

:    不做任何事,占位符

    :>将文件长度改为0,并且不改变权限,不在则创建

    : > data.xxx # File "data.xxx" now empty.

    Same effect as cat /dev/null >data.xxx

    也可作为域分隔符 在/etcpasswd中

    

! 转换退出状态或者测试的感觉

    change the sense of equal ( = ) to not-equal ( != )

    也可调用命令历史

*    通配

    在正则中匹配0个或多个字符

    在算数中 单个表示乘号 两个表示阶乘

?    在双括号中,?作为三元操作符

    (( var0 = var1<98?9:21 ))

    在通配和正则中代表单个字符

$    变量

    跟变量名表示变量的值

    在正则中表示一行的结尾

$@    $*  位置参数

$?    退出状态的变量

$$ 表示当前脚本的进程ID

()    命令组,括号中的命令是子shell,对外面不可见

    数组初始化

        1 Array=(element1 element2 element3)

{}    命令扩展

    8 cp file22.{txt,backup}

    9 # Copies "file22.txt" to "file22.backup"

    ----

    echo {file1,file2}\ :{\ A," B",' C'}

    file1 : A file1 : B file1 : C file2 : A file2 : B

    file2 : C

    ----

    echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z

    ----

    8 base64_charset=( {A..Z} {a..z} {0..9} + / = )

    9 # Initializing an array, using extended brace expansion.

    表示代码块

    对脚本其他地方可见,非子shell

    1 a=123

    2 { a=321; }

    3 echo "a = $a" # a = 321 (value inside code block)

    也可作为占位符

    ls . | xargs -i -t cp ./{} $1

    

[]    表示测试

    数组元素

        1 Array[1]=slot_1

        2 echo ${Array[1]}

    表示字符范围    

$(())    整数表达式

    1 a=3

    2 b=7

    3

    4 echo $(($a+$b)) # 10

> &> >& >> < <>      重定向操作符

    < > 作为ASCII码比较

\<,\>    单词锚定

|     管道

    Passes the output (stdout) of a previous command to the input (stdin) of the next one

    管道作为子shell运行,因此不能修改父shell的变量

>|     强制重定向

||    逻辑或

&    后台运行job

&&    逻辑与

^    行头部匹配

    

    备份当前目录最近24小时内修改的文件

    1 #!/bin/bash

    2

    3 # Backs up all files in current directory modified within last 24 hours

    4 #+ in a "tarball" (tarred and gzipped file).

    5

    6 BACKUPFILE=backup-$(date +%m-%d-%Y)

    7 # Embeds date in backup filename.

    8 # Thanks, Joshua Tschida, for the idea.

    9 archive=${1:-$BACKUPFILE}

    10 # If no backup-archive filename specified on command-line,

    11 #+ it will default to "backup-MM-DD-YYYY.tar.gz."

    12

    13 tar cvf - `find . -mtime -1 -type f -print` > $archive.tar

    14 gzip $archive.tar

    15 echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."

    16

    17

    18 # Stephane Chazelas points out that the above code will fail

    19 #+ if there are too many files found

    20 #+ or if any filenames contain blank characters.

    21

    22 # He suggests the following alternatives:

    23 # -------------------------------------------------------------------

    24 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"

    25 # using the GNU version of "find".

    26

    27

    28 # find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;

    29 # portable to other UNIX flavors, but much slower.

    30 # -------------------------------------------------------------------

    31

    32

    33 exit 0

0

精彩评论

暂无评论...
验证码 换一张
取 消