• 【转】shell脚本常用命令


    原文传送门:http://blog.csdn.net/lionfire/article/details/6634254

    Shell脚本是Linux开发工作中常用的工具,但是我一直没有找到一个适合自己的简明扼要的HandBook。在工作过程中整理了一下,贴在这里已备查看。

    Shell中的特殊符号

    •  $  美元符号。用来表示变量的值。如变量NAME的值为Mike,则使用$NAME就可以得到“Mike”这个值。
    • #  井号。除了做为超级用户的提示符之外,还可以在脚本中做为注释的开头字母,每一行语句中,从#号开始的部分就不执行了。
    •  “”  双引号。shell不会将一对双引号之间的文本中的大多数特殊字符进行解释,如#不再是注释的开头,它只表示一个井号“#”。但$仍然保持特殊含义。(在双引号中的$加变量名,即:$PARAM_NAME,依然会转换成变量的值。)
      • 双引号对于某些特殊符号是不起作用的, 例如:”,$,\,`(反引号)
      • 双引号和单引号不能嵌套。即:echo ‘””’  输出””,  echo “’’” 输出’’
    •  ‘’  单引号。shell不会将一对单引号之间的任何字符做特殊解释。(在双引号中的$加变量名,即:$PARAM_NAME,不会转换成变量的值。)
      • 例如:echo ‘$HOME’    (结果:$HOME)
    • ``  倒引号。命令替换。在倒引号内部的shell命令首先被执行,其结果输出代替用倒引号括起来的文本,不过特殊字符会被shell解释。
    • \  斜杠。用来去掉在shell解释中字符的特殊含义。在文本中,跟在\后面的一个字符不会被shell特殊解释,但其余的不受影响。
    •  []中括号, 主要是用来测试条件的,通常放在if语句的后面。注意,表判断时中括号内侧需要有空格,且if与中括号之间需有空格。如if [ "$a" == "abc" ]
    • {}大括号,主要是和$符号配合,作为字符串连接来使用
      • echo ${HOME}ismydir   (结果:/home/xiongguoanismydir)

    2           预定义的变量

    2.1          特殊变量

    • $      shell变量名的开始,如$var
    • |      管道,将标准输出转到下一个命令的标准输入
    • $#     记录传递给Shell的自变量个数
    • #      注释开始
    • &      在后台执行一个进程
    • ?     匹配一个字符
    • *      匹配0到多个字符(与DOS不同,可在文件名中间使用,并且含.)
    • $-     使用set及执行时传递给shell的标志位  (这是个啥意思?)
    • $!     最后一个子进程的进程号 
    • $?     取最近一次命令执行后的退出状态(返回码)
    • $*     传递给shell script的参数
    • $@     所有参数,个别的用双引号括起来
    • $0     当前shell的名字
    • $n     位置参数,如f a b c,其中,f为函数名或shell脚本名,则$0表示f,$1表示第一个参数a
    • $$     进程标识号(Process Identifier Number, PID)
    • >      输出重定向
    • <      输入重定向
    • >>    输出重定向(追加方式)
    • []      列出字符变化范围,如[a-z]

    2.2          代值变量

    • * 任意字符串 
    • ? 一个任意字符 
    • [abc] a, b, c三者中之一 
    • [a-n] 从a到n的任一字符 

    2.3          特殊字符的表达

    • \b 退回  
    • \c 打印一行时没有换行符 这个我们经常会用到
    • \f 换页
    • \r 回车
    • \t 制表
    • \v 垂直制表
    • \\ 反斜线本身

    2.4          其他字符

    • 分号; 表示一行结束
    •  圆括号() 表示在新的子shell中执行括号内的命令(这样可以不改变当前shell的状态。)但是圆括号在单/双引号内失去作用,只作为普通字符。
    • 花括号{}
      • 分割命令的用法
      • 与圆括号相似,但是:1. 花括号内的命令在当前shell中执行;2.花括号必须作为命令的第一个字符出现。
      • 引用变量的用法
      • 在$后面,表示变量名的开始和结束,如var='abc',则${var}.txt表示abc.txt。
    • 方括号 相当与test命令,用来执行测试条件,通常用在需要判断条件的语句后面,例如:if,while等等。

    3           设置变量

    • 格式:VARNAME=value (i.e. PARAM=’hello’) 注意:1. 等号的前后不能有空格 2.如果变量的值是一个命令的执行结果,请加上反引号(`)。

    4           引用变量

    • $VARNAME
      •  e.i.  echo $HOME   (结果:/home/xiongguoan)
    • 变量默认值
      • 在引用一个变量的时候可以设定默认值。如果在此之前,该变量已经设定了值,则此默认值无效。如果此时变量没有被设定值,则使用此默认值(但是没有改变此变量的值)。
      • echo Hello ${UNAME:-there}     #其中there是UNAME的默认值
      • 其他关于默认值与判读变量的方法:

    利用大括号表示变量替换

    表示形式

    说明

    ${VARIABLE}

    基本变量替换。大括号限定变量名的开始和结束

    ${VARIABLE:-DEFAULT}

    如果VARIABLE没有值,则这种表示形式返回DEFAULT的值

    ${VARIABLE:=DEFAULT}

    如果VARIABLE没有值,则这种表达形式返回DEFAULT的值。另外,如果VARIABLE没有设置,则把DEFAULT的值赋予它

    ${VARIABLE:+VALUE}

    如果VARIABLE被设置,则这种表示形式返回VALUE;否则,返回一个空串

    ${# VARIABLE}

    这种表示形式返回VARIABLE值的长度,除非VARIABLE是* 或者@在为*或者@的特殊情况下,则返回$@所表示的元素的个数。要记住,$ @保存传给该脚本的参数清单

    ${VARIABLE:?MESSAGE}

    如果VARIABLE没有值,则这种表示形式返回MESSAGE的值。Shell也显示出VARIABLE的名字,所以这种形式对捕获得错误很有用

    注意:

    使用${VALIABLE:?MESSAGE},如果发现此变量此时没有值,则脚本停止运行并显示行号和变量名称。 主要用于调试。  

    5           位置变量

    • 使用$1,$2,$3…$9,${10},${11}…来代表输入的参数。其中$0代表被执行的命令或者脚本的名字。$1,$2…代表输入的第1,2…个参数
      • 例子:
    # cat count.sh#!/bin/sh
    A=$1             # 将位置$1的数值读入,并赋给变量A
    B=$2             # 将位置$2的数值读入,并赋给变量B
    C=$[$A+$B]       # 将变量A与B的值相加,将结果赋给C
    echo $C          # 显示C的数值
    结果:
    # ./count.sh  3  6
    9
    # ./count.sh 34  28
    62
    • $#代表参数的数量 ;#@代表“$1"、"$2"、"$3"之意,每个变量是独立的;$* 代表"$1c$2$3",其中c为分隔字符,默认为空格键,所以本例中代表"$1 $2 $3"之意。

     6           运算符和优先级

     Shell运算符和它们的优先级顺序

    级别

    运算符

    说明

    13

    -, +

    单目负、单目正

    12

    !, ~

    逻辑非、按位取反或补码

    11

    * , / , %

    乘、除、取模

    10

    +, -

    加、减

    9

    << , >>

    按位左移、按位右移

    8

    < =, > =,  < , >

    小于或等于、大于或等于、小于、大于

    7

    = = , ! =

    等于、不等于

    6

    &

    按位与

    5

    ^

    按位异或

    4

     |

    按位或

    3

    &&

    逻辑与

    2

    | |

    逻辑或

    1

    =, + =, - =, * =, /=, % =, & =, ^ =, | =, << =, >> =

    赋值、运算且赋值

     7           source / export / let / unset

    • source: 正常情况下,脚本中执行的参数设置只能影响到shell脚本本身的执行环境,不能影响到调用此shell的脚本。使用source命令执行脚本,可以让脚本影响到父shell的环境(即调用此shell的当前shell)。例如:source env.sh
    • export: 在bash下,使用export建立环境变量后,会影响到子shell脚本和当前shell的环境变量
    • unset: 删除环境变量
    #export newval=1
    #echo $newval
    1
    #unset newval
    #echo $newval
    (ß此处为空行,newval已经被删除)
    
    • let: 在bash中只用此命令可以建立一个临时的变量,此变量不会影响到子shell

    8           shell中的表达式

    • shell 输出重定向
      •   管道  |

    就管道符前的命令的输出作为管道符后的命令的输入。 

    ls | grep ‘.txt’   将ls的输出作为grep 的输入。 grep从输入中找出所有包含.txt的行。 

      •   输出  >

    将右尖括号前的命令的输入重定向到尖括号后的文件中。 

    例如:ls *.sh > list.txt  将当前目录下所有末尾名为sh的文件的列表写入到list.txt 

      •   输入 <

    将左箭头后面的文件作为左箭头前的命令的输入。

    例如:grep “a” < test.sh  将test.sh中找到所有包含a的行 

      •   错误输出重定向

    默认bash有3个标准输入输出设备。

    0 标准输入 1 标准输出 2错误输出 

    如果执行脚本的时候发生错误,会输出到2上。

    例如:./test.sh  2> /dev/null    #/dev/null相当于垃圾回收站。这条命令的意思是,将错误输出信息丢弃,不显示在屏幕上。

    /test.sh > a.log 2>&1  //将标准输出和错误输出信息写入到a.log文件中。 该命令也可写为 /test.sh  &>a.log

    • tee

    将此命令的输入分叉,一支输出到屏幕一支可以重定向到其他位置。

    例如: ./test.sh | tee >a.txt 2>&1

    运行test.sh,通过tee输出到a.txt,同时屏幕上可以看到输出。并且将错误输出重定向到标准输出( 2>&1 )

    • cpio
      •   文件或目录打包

    find . -name '*.sh' | cpio -o > shell.cpio   将当前目录及其子目录下的sh文件打包成一个文件库为shell.cpio。 

    ls *.sh | cpio -o > shell.cpio   将当前目录下的sh文件(不含子目录)打包成一个文件库为shell.cpio。 

      •   压缩

    文件打包完成后,即可用Unix中的compress命令(/usr/bin下)压缩打包文件。对一般的文本文件,压缩率较高,可达81%。

    例如:compress shell.cpio则将文件库压缩为shell.cpio.Z(自动添加.Z并删除shell.cpio )。 

      •   解压

    uncompress shell.cpio.Z则自动还原为shell.cpio。 

      •   解包展开

    将按原目录结构解包展开到当前所在目录下。若以相对路径打包的,当解包展开时,也是以相对路径存放展开的文件数据;若以绝对路径打包的,当解包展开时,也是以绝对路径存放展开的文件数据。因此注意若为相对路径,应先进入相应的目录下再展开。

    cd /u1
     cpio –id < shell.cpio 解压到当期目录。 
     cpio –iud < shell.cpio 则文件若存在将被覆盖,即强制覆盖。
     cpio –id < shell.cpio env.sh 解压缩env.sh
      •   显示包内的文件
    cpio –it < shell.cpio  
    • exec

    将此命令后的参数作为命令在当前的shell中执行,当前的shell或者脚本不再执行。

    例如: exec ls 当前进程替换为ls,执行结束后就退出了。

    例如:在a.sh 中包含exec b.sh 则当a.sh 执行到此句后,被b.sh替换,a.sh中此句后的语句不会再被执行。 

    • fork

    将此命令的参数,新建一个进程来执行 

    例如:在a.sh 中包含fork b.sh 则当a.sh 执行到此句后,被b.sh替换,a.sh中此句后的语句继续执行。b.sh在新的进程中同时执行。 

    • expr

    格式:expr argument operator argument一般用于整数的运算(operator前后必须有空格)。 例如:

    #newval=1
    #echo $newval
    1
    #newval=`expr $newval + 1`
    #echo $newval
    2
    #newval=$newval+1
    #echo $newval
    2+1
    
    •  test

    测试,通常用在需要判断的语句后面,例如:if,while,等等。很多时候可以和中括号[]互换。

    i=1
    if test”$ i” == “1”
    then
    echo true
    else
    echo false
    fi 
    
    •  exit

    退出当前的shell,执行结果可以在shell中用$?查看

    例如:exit 2

    • read

    从标准输入读取数据。

    $ read var1 var2 var3 
    Hello my friends 
    $ echo $var1 $var2 $var3 
    Hello my friends 
    $ echo $var1 
    Hello 
    $ read -p "Please input a string" str
    hello_world
    $echo $str
    hello_world
    • shift

    每次调用的时候,将参数列表中的第一个参数去掉。这样可以循环得到第一个参数。

    #cat t.sh
    sum=0
    until [ $# -eq 0 ]
    do
    echo $*
    sum=`expr $sum + $1`
    shift
    done
    echo result is: $sum 
    #./t.sh 1 2 3
    1 2 3
    2 3
    3      

    附件一:Linux 易被遗漏的命令解析

    • grep
      •   grep ‘string’ filename
    grep ‘list’ mytxt.txt 在mytxt.txt中寻找包含list字符串的所有行
      •   “-v” : 相反的。 即不包含字符串。
    grep –v ‘list’ mytxt.txt
    cat mytxt | grep ‘list’ 将cat mytxt作为源, 从中查找包含list字符串的行
    • find
    -atime n : 指查找系统中最后n*24小时访问的文件;
    -ctime n : 指查找系统中最后n*24小时被改变状态的文件;
    -mtime n : 指查找系统中最后n*24小时被修改的文件。
    find ./ -name "*.txt" -exec grep "bin" {} \; 在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行
    find ./ -name "*.txt" -exec rm {} \;  在当前目录下(包含子目录),删除所有txt文件
    • du

    显示文件的大小

    #du *.txt
    1230   myfile1.txt
    456    myfile2.txt
    • awk
    #last -n 5
    root  pts/1  192.168.0.1  Tue  Feb  10  11:21  still  logged in
    root  pts/1  192.168.0.1  Tue  Feb  10  00:46  02:28  (01:41)
    root  tty1           Fri  Sep  5   14:09  14:10  (00:01)
    
    #last -n 5 | awk '{print $1 "\t" $3}'
    root  pts/1  192.168.0.1
    root  pts/1  192.168.0.1
    root  tty1   Fri
    
    NF表示每一行($0)拥有的字段总数
    NR表示目前awk所处理的是“第几行”数据
    FS表示目前的分隔符,默认是空格键
    
    #last -n 5 | awk '{print $1 "\t lines: " NR "\t Columes: " NF}'
    root  lines:1  columes:10
    root  lines:2  columes:10
    root  lines:3  columes:9
    
    #cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t" $3}'
    root:x:0:0:root:/root:/bin/bash  #这是因为读入第一行的时候,变量$1,$2...默认是以空格键为分隔的,定义的FS只能在第二行后开始生效。可改为:awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'
    bin  1
    daemon  2
    ...
    
    如果有一个文件pay.txt,内容为:
    Name  1st  2nd  3rd
    VBird  1100  1100  1100
    DMTsai  2200  2200  2200
    Bird2  3300  3300  3300
    
    #cat pay.txt | awk '{if(NR==1) printf "%10s  %10s  %10s  %10s  %10s\n", $1, $2, $3, $4, "Total"} NR>2{total=$2 + $3 + $4 printf "%10s  %10s  %10s  %10s  %10.2f\n", $1, $2, $3, $4, total}'
    Name  1st  2nd  3rd  4th
    VBird  1100  1100  1100  3300
    DMTsai  2200  2200  2200  6600
    Bird2  3300  3300  3300  9900
    
    • 前后台运行

     ./test.sh &  将某个程序在后台启动起来,只需要在命令的最后加上 & 符号。

    当按下^z的时候,当前的应用程序就会切换到后台,但是此时的状态是停止的状态。

      •   使用jobs命令可以看到当前在后台运行的程序的列表。
    #jobs
    [1]+ stopped top
    [2]+stopped find | grep *.txt > a.log
      •   使用bg命令可以将某个后台程序继续运行。
    #bg %2
    #jobs
    [1]+ stopped top
    [2]+ Running find | grep *.txt > a.log
      •   将后台运行的程序切回到前台
    #fg %2   //将find 命令切回到前台
    
    • shell的执行选项

    -n 测试shell script语法结构,只读取shell script但不执行 
    -x 进入跟踪方式,显示所执行的每一条命令,用于调度 
    -a Tag all variables for export 
    -c "string" 从strings中读取命令 
    -e 非交互方式 
    -f 关闭shell文件名产生功能 
    -h locate and remember functions as defind 
    -i 交互方式 
    -k 从环境变量中读取命令的参数 
    -r 限制方式 
    -s 从标准输入读取命令 
    -t 执行命令后退出(shell exits) 
    -u 在替换中如使用未定义变量为错误 
    -v verbose,显示shell输入行

    • alias

    alias abc=ls   建立别名,  abc为命令ls的别名

    • xargs

    执行本命令的第一个参数,并将xargs的输入作为被执行命令的参数

    例如:find . -name '*.c' | xargs cat   将本目录及其子目录下所有的C文件使用cat命令显示其内容。

    附件二:Bash中影响环境变量的命令

    Shell有若干以变量为工作对象的命令,其中有些命令似乎重复了。例如,可以用declare、export和typeset命令来创建全局(或转出)的变量。typeset命令是declare的同义词。

    • Declare 命令

     语法:declare [options] [name [= value]]

    用于显示或设置变量。

    declare命令使用四个选项:

    -f   只显示函数名

    -r   创建只读变量。只读变量不能被赋予新值或取消设置,除非使用declare或者typeset命令

    -x   创建转出(exported)变量

    -i   创建整数变量。如果我们想给一个整数变量赋予文本值,实际上是赋予0使用+ 代替-,可以颠倒选项的含义。

    如果没有使用参数,则declare显示当前已定义变量和函数的列表。让我们关注一下-r选项:

    $ declare  –r  title=" paradise Lost"
    $ title = " Xenogenesis"
    bash: title: read-only variable
    $ declare title= " Xenogenesis"
    $ echo $title
    Xecogenesis
    $ typeset title = " The Longing Ring”
    $ echo $title
    The Longing Ring
    

    这个示例表明,只有declare或typeset命令可以修改只读变量的值。

    •  export命令

    语法:

     export [options] [name [= value]]

    用于创建传给子Shell的变量。

    export命令使用四个选项:

    --   表明选项结束。所有后续参数都是实参

    -f   表明在“名-值”对中的名字是函数名

    -n   把全局变量转换成局部变量。换句话说,命名的变量不再传给子Shell

    -p   显示全局变量列表

     如果没有用参数,则假定是一个-p参数,并且显示出全局变量的列表: 

    $ export
    declare –x ENV = "/home/medined/ . bashrc"
    declare –x HISTFILESIZE = "1000"
    …
    declare –xi numPages = "314"
    declare –xr title = "The Longing Ring"
    declare –xri numChapters = "32"
    

    这种显示的一个有趣的特性是,它告诉我们哪些变量只能是整数、是只读的,或者二者皆可。

    •  let命令

     语法:let expression

    用于求整数表达式的值。

     let命令计算整数表达式的值。它通常用来增加计数器变量的值。 

    • local 命令 

    语法:       local [name [= value]]

    用于创建不能传给子Shell的变量。这个命令仅在过程内部有效。 

    简单说来,local命令创建的变量不能被子Shell存取。因此,只能在函数内部使用local命令。我们可以在命令行或脚本中使用“变量=值”这种形式的赋值命令。如果使用local时不带实参,那么当前已定义的局部变量列表就送往标准输出显示。 

    # ! /bin/bash
    count=1
    for element in $@
    do
       echo " $element is element $count"
       let count+=1
    done
    
    下面是这个脚本运行结果示例:
    
    $ chmod + x let
    $ . /let one two three
    one is element 1
    two is element 2
    three is element 3 
    
    注意:如果我们习惯在表达式中使用空格,那么要用双引号把表达式括起来,如:
    let "count + =1"
    否则会导致语句错误。
    
    • readonly命令

     语法:       readonly [options] [name[ = value]]

    用于显示或者设置只读变量。

    Readonly命令使用两个选项:

    --    表明选项结束。所有后续参数都是实参

    -f    创建只读函数 

    如果没有用参数,则readonly显示当前已定义的只读变量和函数的列表。 

    • set命令 

    语法:       set [--abefhkmnptuvxidCHP] [-o option] [name [= value]]

    用于设置或者重置各种Shell选项。

    set 命令可实现很多不同的功能——并非其中所有的功能都与变量有关。由于本节的其他命令重复了通过set命令可用的那些变量选项,所以这里对set命令不做详细说明。

    • shift命令 

    语法  shift [n]

    用于移动位置变量。 

    shift命令调整位置变量,使$3的值赋予$2,而$2的值赋予$1。当执行shift命令时,这种波动作用影响到所定义的各个位置变量。往往使用shift命令来检查过程参数的特定值——如为选项设置标志变量时。

    • typeset命令 

    语法:typeset [options] [name [= value]]

    用于显示或者设置变量。 

    typeset 命令是declare命令的同义词。 

    • unset命令 

    语法:unset [options] name [name …]

    用于取消变量定义。

    unset命令使用两个选项:

    --  表明选项结束,所有后续参数都是实参

    -f  创建只读函数 

    unset命令从Shell环境中删除指定的变量和函数。注意,不能取消对PATH、IFS、PPID、PS1、PS2、UID和EUID的设置。如果我们取消RANDOM、SECONDS、LINENO或HISTCMD等变量的设置,它们就失去特有属性。

  • 相关阅读:
    Android Studio 使用 Gradle 打包 Jar
    图片相关
    判断SIM卡状态,获取SIM卡信息
    SwipeRefreshLayout完美添加及完善上拉加载功能
    环境变量配置文件,本地登录前提示信息/etc/issue
    变量声明declare,简单运算符运算,变量测试与内容替换
    变量:用户自定义变量(本地变量),环境变量,位置参数变量,预定义变量
    多命令顺序执行,dd命令,管道|,grep,通配符,其他特殊符号
    历史命令~/.bash_history,查看所有别名alias,命令执行顺序,命令行常用快捷键,输入输出重定向,wc统计字节单词行数
    查看当前支持的shell,echo -e相关转义符,一个简单shell脚本,dos2unix命令把windows格式转为Linux格式
  • 原文地址:https://www.cnblogs.com/sunada2005/p/2986082.html
Copyright © 2020-2023  润新知