• Linux shell命令特殊符号


    原帖地址: http://www.2cto.com/os/201112/113097.html
           http://www.2cto.com/os/201305/209678.html

    1.简述

    ( > ) 重定向输出符号

    用法:命令>文件名

    特性:覆盖(当输入文件和输出文件是同一文件,文件内容被清空;不适合连续重定向)

    典型应用:

    ~$ cat a b >c  (合并文件)

    ~$ echo "hello world" > hello.txt  (输入内容到指定文件)

    ~$ ./test.sh > /dev/null (删除程序输入)

    ( >> ) 输出重定向

    用法:命令>>文件名

    特性:追加

    典型应用:

    ~$ cat hello.txt >> hello2.txt

    ~$ ./test.sh >> test.echo

    ( 2> ) 错误重定向

    用法:命令2>文件名

    特性:覆盖

    典型应用:

    ~$ ./test.sh >> test.error

    ( 2>> ) 错误重定向输出符号

    用法:命令2>>文件名

    特性:错误信息的追加

    典型应用:

    ~$ ./test.sh 2>>  test.error

    ( | ) 管道符号

    用法:命令1 | 命令2

    特性:上一个的命令输出作为下一个命令的输入

    典型应用:

    ~$ ps -ef | grep root

    ( * ) 匹配任意字符

    ( ? ) 匹配任意一个字符

    ( & ) 后台运行命令(守护程序)

    用法:命令1 &

    特性:关闭当前终端窗口,程序仍在运行

    典型应用:

    ~$ ./test.sh &

    ( && ) 连接多条命令

    用法:命令1 && 命令2

    特性:如果命令1执行成功,继续执行命令2;否则,不执行命令2.

    典型应用:

    ~$ apt-get update && apt-get dist-upgrade

    ( || ) 逻辑或

    用法:命令1 || 命令2

    特性:如果命令1执行成功,不执行命令2;否则,才执行命令2.

    ( !) 逻辑非

    特性:排除指定范围.

    ( [x-y] ) 指定范围

    ( # ) 注释

    ( "" ) 双引号

    特性:把它所包含的内容作为普通字符,但'' $ ``除外.

    ( '' ) 单引号

    特性:把它所包含的内容作为普通字符,无例外.

    ( `` ) 倒引号

    特性:执行它所包含的内容

    ( ) 转义字符

    用法; 符号

    特性:把符号的特定含义去掉,使其变成普通标点.

    ( $ ) 变量调用符号

    用法:$变量

    特性:调用变量,从而得到‘变量的值

    ( ; ) 命令分隔符

    用法:命令1 ; 命令2

    特性:一行语句中,顺次执行各命令

    ( () ) 整体执行

    ( {} ) 变量分离  


    2.详述

    LINUX Shell特殊字符的表示方法
     
    # 注释
    1. 表示注释 #注释
    2. 在引号中间和#等表示#本身
    3.echo ${PATH#*:} # 参数替换,不是一个注释
    4.echo $(( 2#101011 )) # 数制转换,不是一个注释
    echo "The # here does not begin a comment."
    echo 'The # here does not begin a comment.'
    echo The # here does not begin a comment.
    echo The # 这里开始一个注释.
    echo ${PATH#*:} # 参数替换, 不是一个注释.
    echo $(( 2#101011 )) # 数制转换, 不是一个注释.
    这里特别要注意第四个,一定要有空格,否则不认同是注释
    ; 分隔
    1.命令分隔,在一行中写多个命令 echo "aa" ; echo "bb"
    2.在条件中的if和then如果放在同一行,也用;分隔
     
    ;; case条件的结束
    1.命令分隔,在一行中写多个命令 echo "aa" ; echo "bb"
    2.在条件中的if和then如果放在同一行,也用;分隔
    echo hello; echo there
    if [ -x "$filename" ]; then    # 注意: "if"和"then"需要分隔. 
    echo "File $filename exists."; cp $filename $filename.bak
    else
    echo "File $filename not found."; touch $filename
    fi; echo "File test complete."
     
    . 命令相当于
    1.命令:source
    2.文件名的前缀,隐藏文件
    3.目录:.当前目录,..父目录
    4.正则表达式:匹配任意单个字符
    首先,先举例说明一下"."作为source使用的实例
    #!/bin/bash
    . data-file    # 加载一个数据文件.
    # 与"source data-file"效果相同, 但是更具可移植性.
    # 文件"data-file"必须存在于当前工作目录, 因为这个文件是使用'basename'来引用的. 
    echo "variable1 = $variable1"
    echo "variable3 = $variable3"
    let "sum = $variable2 + $variable4"
    echo "sum = $sum"
    exit 0
    上面是编写的include_file脚本,通过 . data-file引入,相当于c语言中的include data-file,我们看看data-file的内容
    # 这是需要被脚本加载的数据文件.
    # 这种文件可以包含变量, 函数, 等等.
    # 在脚本中可以通过'source'或者'.'命令来加载.                                             
    # 让我们初始化一些变量.
    variable1=22
    variable2=474
    variable3=5
    variable4=97
    message1="Hello, how are you?"
    message2="Enough for now. Goodbye."
    接下来我们看看脚本的执行结果:
    root@ubuntu:~/resource/study/shell_study# chmod 777 include_file 
    root@ubuntu:~/resource/study/shell_study# ls
    clear_log  data-file  include_file  show_self
    root@ubuntu:~/resource/study/shell_study# ./include_file 
    variable1 = 22
    variable3 = 5
    sum = 571
    上面的结果已经很有力的说明了我们想要的结论
    .作为隐藏文件时,建立隐藏文件的方法:touch .data-file
     
    .作为匹配字符说明如下:ab.  可以表示ab+任意字符,处理换行,并且必须是一个字符ab.不能表示ab
     
    "" 部分引用 支持通配符扩展
    "STRING"将会阻止(解释)STRING中大部分特殊的字符
     
    ' ‘ 全引用,不进行通配符扩展
    'STRING'将会阻止STRING中所有特殊字符的解释. 这是一种比使用"更强烈的形式
     
    转义
    X将会"转义"字符X. 这等价于"X", 也等价于'X'. 通常用来转义"和', 这样双引号和单引号就不会被解释成特殊含义了.
     
    / 目录分隔符
    分隔文件名不同的部分(比如 /home/bozo/projects/Makefile).也可以用来作为除法算术操作符.
     
    , 多个命令都被执行,但返回最后一个
    逗号操作符链接了一系列的算术操作. 虽然里边所有的内容都被运行了,但只有最后一项被返回.
    let "t2 = ((a = 9, 15 / 3))" # Set "a = 9" and "t2 = 15 / 3"
    逗号之前会运算,但是只有最后一项被返回
     
    ` 后置引用
    `command`结构可以将命令的输出赋值到一个变量中去. 
    cd $LOG_DIR
    if [ `pwd` != "$LOG_DIR" ]
    then
    echo "Can't change to $LOG_DIR"
    exit $E_XCD
    fi
    这里例子是最有力的的说明,在上一章中只不过没有到这个方法,这里pwd命令会返回当前路径,然后与LOG_DIR进行比较,同样你可以定义一个变量保存pwd返回的内容,比如:
    path=`pwd`
     
    : 操作符
    1.空操作,等价于"NOP" (no op, 一个什么也不干的命令). 
      1 :
      2 echo $?   # 0
    2.死循环: while :,可以被认为与shell的内建命令,与true作用相同.
     while :
     do
        operation-1
        operation-2
        ...
        operation-n
     done
       
     # 与下边相同:
     #    while true
     #    do
     #      ...
     #    done
    3.在if/then中表示什么都不做,引出分支
    if condition
    then :   # 什么都不做,引出分支. 
         else
    take-some-action
    fi
     
    4.设置默认参数 : ${username=`whoami`}
    : ${username=`whoami`}
    # ${username=`whoami`}   如果没有开头的":"的话, 将会给出一个错误, 除非"username"是一个命令或者内建命令
     
    5.变量替换 : ${HOSTNAME?} ${USER?} ${MAIL?}
    : ${HOSTNAME?} ${USER?} ${MAIL?}
    #  如果一个或多个必要的环境变量没被设置的话, 就打印错误信息. 
     
    6.在和 > (重定向操作符)结合使用时,把一个文件截断到0 长度,没有修改它的权限;如果文件在之前并不存在,那么就创建它.如: 
    : > data.xxx #文件"data.xxx"现在被清空了. 与 cat /dev/null >data.xxx 的作用相同 然而,这不会产生一个新的进程,因为":"是一个内建命令.
    在和>>重定向操作符结合使用时,将不会对想要附加的文件产生任何影响.
    如果文件不存在,将创建.
    7.可能用来作为注释行, 虽然我们不推荐这么做. 使用#来注释的话, 将关闭剩余行的错误检查, 所以可以在注释行中写任何东西. 然而, 使用:的话将不会这样.
     : This is a comment that generates an error, ( if [ $x -eq 3] ).
    8.":"还用来在/etc/passwd和$PATH变量中做分隔符.
    bash$ echo $PATH
    /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
     
    * 匹配0个或多个字符;数学乘法;**幂运算
    root@ubuntu:~/resource/study/shell_study# ls
    clear_log  data-file  include_file  show_self
    root@ubuntu:~/resource/study/shell_study# echo *
    clear_log data-file include_file show_self
     
    ? 匹配任意一个字符;但在((a>b?a:b))表示c语言中的三目运算
     (( t = a<45?7:11 ))   # C语言风格的三元操作.
     
    $ 字符
    1.取变量的值 echo $PATH
    var1=5
    var2=23skidoo
    echo $var1     # 5
    echo $var2     # 23skidoo
    2.正则表达式中表示行的结尾
    在正则表达式中, "$"表示行结束符,先分析一下下面的例子吧
    root@ubuntu:~/resource/study/shell_study# echo slfjalj$fdjgl
    slfjalj
    3.${} 参数替换 ${PAHT}
    #!/bin/bash
      2 # param-sub.sh
      3 
      4 #  一个变量是否被声明或设置,
      5 #+ 将会影响这个变量是否使用默认值, 
      6 #+ 即使这个变量值为空(null).
      7 
      8 username0=
      9 echo "username0 has been declared, but is set to null."
     10 echo "username0 = ${username0-`whoami`}"这里定义了username0且初始化是null,所以这里不会有输出,这里的“-”相当于“=”
     11 # 不会有输出.
     12 
     13 echo
     14 
     15 echo username1 has not been declared.
     16 echo "username1 = ${username1-`whoami`}"这里username1在上面没有定义并初始化为null,所以会显示
     17 # 将会输出默认值.
     18 
     19 username2=
     20 echo "username2 has been declared, but is set to null."
     21 echo "username2 = ${username2:-`whoami`}"这里上面初始化了username2并初始化为null,但是这里有个“:”
     22 #                            ^
     23 # 会输出, 因为:-会比-多一个条件测试.
     24 # 可以与上边的例子比较一下.
     25 
     26 
     27 #
     28 
     29 # 再来一个:
     30 
     31 variable=
     32 # 变量已经被声明, 但是设为空值. 
     33 
     34 echo "${variable-0}"    # (没有输出)
     35 echo "${variable:-1}"   # 1
     36 #               ^
     37 
     38 unset variable
     39 
     40 echo "${variable-2}"    # 2
     41 echo "${variable:-3}"   # 3
     42 
     43 exit 0
    我们也看看他的执行结果:
    root@ubuntu:~/resource/study/shell_study# chmod 777 para_sub 
    root@ubuntu:~/resource/study/shell_study# ls
    clear_log  data-file  include_file  para_sub  show_self
    root@ubuntu:~/resource/study/shell_study# ./para_sub 
    username0 has been declared, but is set to null.
    username0 = 
     
    username1 has not been declared.
    username1 = root
    username2 has been declared, but is set to null.
    username2 = root ^
     
    1
    2
    3
    4.$* 所有参数
    5.$# 参数个数
    6.$$ 进程的ID
    7.$? 进程的返回状态
     
    ( )字符
    1.命令组,在一个子Shell中运行 (a=3;echo $a) 其中定义的变量在后面不可用
    在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的. 父进程, 也就是脚本本身, 将不能够读取在子进程中创建的变量, 也就是在子shell中创建的变量.
      1 a=123
      2 ( a=321; )       
      3 
      4 echo "a = $a"   # a = 123
      5 # 在圆括号中a变量, 更像是一个局部变量. 
    2.数组初始化: array=(a,b,c)
    大括号扩展
      1 cat {file1,file2,file3} > combined_file
      2 # 把file1, file2, file3连接在一起, 并且重定向到combined_file中.
      3 
      4 
      5 cp file22.{txt,backup}
      6 # 拷贝"file22.txt"到"file22.b
     
    { } 代码块,即一个匿名函数,但其中定义的变量在后面依然可用
    #!/bin/bash
    # 从/etc/fstab中读行.
    File=/etc/fstab
    {
    read line1
    read line2
    read line3
    } < $File
     
    echo "First line in $File is:"
    echo "$line1"
    echo
    echo "Second line in $File is:"
    echo "$line2"
    echo
    echo "third line in $File is:"
    echo "$line3"
    exit 0
    执行结果:
    root@ubuntu:~/resource/study/shell_study# ./test1 
    First line in /etc/fstab is:
    # /etc/fstab: static file system information.
     
    Second line in /etc/fstab is:
    #
     
    third line in /etc/fstab is:
    # Use 'blkid -o value -s UUID' to print the universally unique identifier
    接下来看一个例子:
    #!/bin/bash
     
    echo "Just for a test:"
    echo `pwd`
    echo "Test end"
    } > "test-context"       # 把代码块中的所有输出都重定向到文件中.
     
    echo "Results of rpm test in test-context"
    exit 0
    看看运行结果:
    root@ubuntu:~/resource/study/shell_study# chmod 777 test2 
    root@ubuntu:~/resource/study/shell_study# ./test2 
    Results of rpm test in test-context
    root@ubuntu:~/resource/study/shell_study# ls
    clear_log  include_file  show_self  test2
    data-file  para_sub      test1      test-context
    root@ubuntu:~/resource/study/shell_study# cat test-context 
    Just for a test:
    /root/resource/study/shell_study
    Test end
    { } ; 用在find的-exec中 $find -name *.txt -exec cat {} ;
    [ ]
    1.测试 [-z $1]
    2.数组元素 a[1]='test'
    3.[[]]表示测试 使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如, &&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错.
    4.(( ))数学运算
    5.在正则表达式中表示范围 [a-z]
     
    < << > 重定向和进程替换 ls -al > a.txt
    scriptname >filename 重定向scriptname的输出到文件filename中. 如果filename存在的话, 那么将会被覆盖.
    command &>filename 重定向command的stdout和stderr到filename中.
    command >&2 重定向command的stdout到stderr中.
    scriptname >>filename 把scriptname的输出追加到文件filename中. 如果filename不存在的话, 将会被创建.
    [i]<>filename 打开文件filename用来读写, 并且分配文件描述符i给这个文件. 如果filename不存在, 这个文件将会被创建.
     
    > < 还用在ASCII比较 if [[ "$veg1" < "$veg2" ]]
    <,> 正则表达式中的单词边界.如:bash$grep '<the>' textfile
     
    | 管道
    分析前边命令的输出, 并将输出作为后边命令的输入. 这是一种产生命令链的好方法.
    echo ls -l | sh # 传递"echo ls -l"的输出到shell中,与一个简单的"ls -l"结果相同.
    cat *.lst | sort | uniq # 合并和排序所有的".lst"文件, 然后删除所有重复的行. 
    管道是进程间通讯的一个典型办法, 将一个进程的stdout放到另一个进程的stdin中. 标准的方法是将一个一般命令的输出, 比如cat或者echo, 传递到一个 "过滤命令"(在这个过滤命令中将处理输入)中, 然后得到结果.
    cat $filename1 $filename2 | grep $search_word
    当然输出的命令也可以传递到脚本中.
    #!/bin/bash
    # uppercase.sh : 修改输入, 全部转换为大写.
    tr 'a-z' 'A-Z'
    # 字符范围必须被""引用起来来阻止产生单字符的文件名.
    exit 0
    现在让我们输送ls -l的输出到一个脚本中.
    bash$ ls -l | ./uppercase.sh
    -RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
    -RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
    -RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE
     
    管道中的每个进程的stdout比须被下一个进程作为stdin来读入. 否则, 数据流会阻塞, 并且管道将产生一些非预期的行为.
    cat file1 file2 | ls -l | sort# 从"cat file1 file2"中的输出并没出现. 
    作为子进程的运行的管道, 不能够改变脚本的变量.
    variable="initial_value"
    echo "new_value" | read variable
    echo "variable = $variable" # variable = initial_value
    如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止. 这种行为被叫做broken pipe, 并且这种状态下将发送一个SIGPIPE 信号.
     
    >| 强制重定向(即使设置了noclobber 选项--就是-C 选项).这将强制的覆盖一个现存文件.
     
    || 逻辑或操作 ;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 false,继续执行下一个命令
     
    && 逻辑与;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 true,继续执行下一个命令
     
    & 后台运行
    看一个例子
    #!/bin/bash
    # background-loop.sh
    for i in 1 2 3 4 5 6 7 8 9 10            # 第一个循环.
    do
    echo
    echo -n "$i "
    done & # 在后台运行这个循环.
     
    # 在第2个循环之后, 将在某些时候执行. 
    echo   # 这个'echo'某些时候将不会显示. 
    for i in 11 12 13 14 15 16 17 18 19 20   # 第二个循环.
    do
    echo -n "$i "
    done  
    echo   # 这个'echo'某些时候将不会显示. 
    exit 0
    看一下结果:
    root@ubuntu:~/resource/study/shell_study# ./for_test 
     
    11 12 13 14 15 16 17 18 19 20 
    root@ubuntu:~/resource/study/shell_study# 
     
    -  在所有的命令内如果想使用选项参数的话,前边都要加上"-".
    1.参数选项
    2. 减号
    3. 重定向stdin和stdout:cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
    4.先前的工作目录 cd -
    5.注:使用-开头的文件名和变量名可能会出现一些问题
     
    + 一个命令或者过滤器的选项标记.
    ~ home目录
    ~+ 当前工作目录
    ~- 先前工作目录
    ^ 正则表达式中表示行首
    $IFS 用来做一些输入命令的分隔符, 默认情况下是空白
    其中命令的很多细节并没有研究的很彻底,以后见到用到具体的命令再具体分析吧
  • 相关阅读:
    gulp常用插件之gulp-plumber使用
    gulp常用插件之gulp-load-plugins使用
    gulp常用插件之yargs使用
    ql自动化测试之路-概述篇
    ql的python学习之路-day11
    ql的python学习之路-day10
    ql的python学习之路-day9
    python实现简易工资管理系统(Salary Manage)源码
    python控制台实现打印带颜色的字体
    ql的python学习之路-day8
  • 原文地址:https://www.cnblogs.com/zswbky/p/6717901.html
Copyright © 2020-2023  润新知