• 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 0

    Shell 命令学习

    Posted by 撒得一地 on 2016年5月5日 in Linux笔记
    国外稳定加速器推荐    Express | Vypr

    Shell脚本是非常强的大一个脚本语言,但是不用会手生,所以在此记录Shell脚本的相应关键点,也做查字典用^_^变量。

    变量

    变量定义

    先来简单的看一下变量定义的规则

    1. Shell中,使用变量之前不需要事先声明,只是通过使用它们来创建它们;
    2. 在默认情况下,所有变量都被看做是字符串,并以字符串来存储;
    3. Shell变量是区分大小写的;
    4. 在赋值变量的时候等号两端不能有空格-_-

    定义了变量之后,一定要加上$符号才能使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #! /bin/bash
    
    VAR1=HELLO
    VAR2=MY NAME
    VAR3="MY AGE"
    VAR4 = IS
    
    echo VAR1 #error 能输出 但不是输出该变量
    echo $VAR1 #ok 正常读取变量并打印
    echo $VAR2 #error 定义变量的值 用空格隔开了
    echo $VAR3 #ok 作为一整个字符串
    echo $VAR4 #error 变量定义的时候等号两端有空格
    

    输出的结果为

    ./test.sh: line 2: NAME: command not found
    ./test.sh: line 4: VAR4: command not found
    VAR1
    HELLO
    
    MY AGE
    

    关于shell脚本的执行:shell基本一般是以.sh为后缀,然后在*unix系统下一般都是直接使用./[当前shell文件名] 的方式来执行,也可以使用全部经/[shell文件名]的方式来执行,并且需要注意的是 被执行的shell文件一定是有含有可执行权限了的,可以使用chmod命令来修改

    还有另一个点就是在调用变量的时候 ,如果在双引号中直接使用$name任然可以识别,但是如果在单引号是就无法适用$name的方式来调用变量

    read读取输入值

    这个功能就像java中的readline来读取,使用方法为

    1
    2
    3
    4
    5
    6
    7
    
    #! /bin/bash
    
    echo "whats your name?"
    read NAME  #在这里读取输入值到NAME变量中 ,这里如果不输入会停留在屏幕上
    echo "webcome back" $NAME
    
    exit 0
    

    可以看到熟悉的结果为

    whats your name?
    tom
    webcome back tom
    

    环境变量

    Shell脚本还提供能一些实用的环境变量

    1. $HOME:为当前用户所在的目录
    2. $PATH:当前用户所能方法的PATH变量
    3. $#:传递参数额个数 类似java中的args.length
    4. $$:Shell脚本的进程号,脚本程序通?;嵊盟瓷梢桓鑫ㄒ坏牧偈蔽募?。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #! /bin/bash
    
    echo "当前用户所在的目录为" $HOME
    echo "当前的执行目录为" $(pwd)  #这个是访问当前的脚本的目录很实用
    echo "当前用户所能访问的PATH为" $PATH
    echo "当前参数的参数个数为" $#  #这儿参数的格式是使用空格隔开的哦
    echo "当前Shell脚本的进程号为" $$
    
    exit 0
    

    可以到看的结果是

    yans-MacBook-Pro:Downloads yanyl$ ./hi.sh  hello world
    当前用户所在的目录为 /Users/yanyl
    当前的执行目录为 /Users/yanyl/Downloads
    当前用户所能访问的PATH为 /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/yanyl/Program/apache-maven-3.2.5/bin:/Users/yanyl/Program/scala-2.10.4//bin
    当前参数的参数个数为 2
    当前Shell脚本的进程号为 43746
    

    假如需要进入当前目录的父目录,可以使用$(dirname $(pwd))

    参数变量

    刚刚看到可以使用read关键字可以来读取输入变量,但是我们可能更加常用的是参数变量,也就是$#的个数,它的规则如下

    1. $#表示参数变量的个数
    2. $0表示当前的脚本名称
    3. $1,$2…$n表示依次能读取到的变量 但是如果参数变量不够,$i会被赋值为空
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #! /bin/bash
    
    echo "当前输入的参数变量的长度为" $#
    echo "当前执行的Shell脚本为" $0
    echo "当前输入的第一个参数为" $1
    echo "当前输入的第二个参数为" $2
    echo "当前的输入的第三个参数为" $3 #现在如果只传2个参数 这里将不会报错
    
    exit 0
    

    可以看到的结果为

    yans-MacBook-Pro:Downloads yanyl$ ./hi.sh  hello world
    当前输入的参数变量的长度为 2
    当前执行的Shell脚本为 ./hi.sh
    当前输入的第一个参数为 hello
    当前输入的第二个参数为 world
    当前的输入的第三个参数为
    

    可以看到在Shell脚本中去读取参数变量还是很方便的,这样配合下面的条件判断以及循环就可以做很多事情了

    读取返回码

    一般的程序/命令在执行结束时都会返回一个 返回码,比如

    • javasystem.exit(-1)
    • pythonsys.exit(-1)
    • 还有上面Shell脚本中的最后一行exit 0

    如果你不显式指定返回码,一般默认为0,表示正常退出,但是有时候显式的指定返回码是一个好习惯哦

    这些程序在Shell中执行的,可以使用$?来读取上一个程序执行下来的脚本码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #! /bin/bash
    
    du -s #执行的返回码一般为0
    echo du -s的返回码为 $?
    
    duu -s #这个命令故意输错
    echo duu -s的返回码为 $?
    
    exit 0
    

    可以看到正确的结果为

    28494656    .
    du -s的返回码为 0
    ./hi.sh: line 6: duu: command not found
    duu -s的返回码为 127
    
    

    返回码配上if判断,就可以使用shell脚本自由得在各个语言以及命令中穿梭啦^_^

    数学运算

    在上一小节中说道,Shell中变量一般都是当字符串来处理,那我遇到数字运算该咋办呢??

    可以先看

    1
    2
    3
    4
    5
    6
    7
    8
    
    #! /bin/bash
    
    a=1+2
    b=$a+3
    echo $a
    echo $b
    
    exit 0
    

    结果却看到

    1+2
    1+2+3
    

    那在Shell中解决这个问题大概有这么几种方法

    let关键字

    1
    2
    3
    4
    5
    6
    7
    8
    
    #! /bin/bash
    
    let a=1+2
    let b=$a+3
    echo $a
    echo $b
    
    exit 0
    

    输出的结果为

    3
    6
    

    这个关键词大致需要注意以下几个点:

    • let只支持整数运算
    • let后面的运算部分有bash关键字时,需加双引号
    • 幂次方可以使用**符号

    使用(())

    1
    2
    3
    4
    5
    6
    7
    8
    
    #! /bin/bash
    
    ((a=1+2))
    ((b=$a+3))
    echo $a
    echo $b
    
    exit 0
    

    结果还是正确的

    3
    6
    

    (())的用法与let完全相同

    使用$[]

    上面的效果需要这么写

    1
    2
    
    a=$[1+2]
    b=$[$a+3]
    

    其余与上面两种限制大致相同

    使用expr

    关于这个方式是这么写的

    1
    2
    
    a=`expr 1 + 2`
    b=`expr $a \* 3`  #需要转义
    

    需要额外注意的有:

    • 运算符两端需要加空格 一定要记住。。。很容易失误
    • 对于|、&、<、<=、>=、>、*运算符号需要加上\进行转义

    使用bc

    这个终于是可以用于浮点数的运算了

    1
    2
    3
    4
    5
    6
    7
    8
    
    #! /bin/bash
    
    a=3.1415926
    b=`echo "$a*2"|bc`
    echo $a
    echo $b
    
    exit 0
    

    可以看到结果

    3.1415926
    6.2831852
    

    据说这里还有一个scale来设置精度,但是我设置了感觉木有效果-_-

    条件判断

    if 语法

    Shell脚本中有两种书写if判断的语法

    • 使用test 关键字

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      #! /bin/bash
      
      # if test expression1 operation expression2
      if test 5 -gt 4;  #这个最后的结尾可以加上:或者;
      then
          echo "ok,5>4"
      else
          echo "oh,no"
      fi #这个结束符号必须得加
      
      exit 0
      

      输出为

      ok,5>4
      
    • 使用[]关键字

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      #! /bin/bash
      
      # if [ expression1 operation expression2 ]
      if [ 5 -lt 4 ];  #注意[和]两端必须留空格 同时表达式两端都需要有空格
      then
          echo "ok,5>4"
      else
          echo "oh,no"
      fi
      
      exit 0
      

      输出为

      oh,no
      

    如果还更加复杂的判断你可以使用elif继续增加条件表达式,但是别忘了加then

    判断表达式

    Shell中有三种判断表达式

    字符串比较

    字符串比较 结果
    string1 = string2 如果两个字符串相同,也可用==结果就为真
    string1 != string2 如果两个字符串不同,结果就为真
    -n string 如果字符串不为空,则结果为真
    -z string 如果字符串为一个空串(null),则结果为真

    这里需要注意下,-n 和 -z string比较时必须用双引号(“”)将变量引起来

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    #! /bin/bash
    
    a=5
    
    if [ -n "$a"  ]  #注意要空括号来包住哦
    then
        echo exists
    else
        echo null
    fi
    
    if [ -n "$c"  ]
    then
        echo exists
    else
        echo null
    fi
    
    exit 0
    

    结果为

    exists
    null
    

    算术比较

    算术比较 结果
    expression1 -eq expression2 如果两个表达式相等,则结果为真
    expression1 -ne expression2 如果两个表达式不等,则结果为真
    expression1 -gt expression2 如果expression1 大于expression2 ,则为真
    expression1 -ge expression2 如果expression1 大于等于expression2 ,则为真
    expression1 -lt expression2 如果expression1 小于expression2 ,则为真
    expression1 -le expression2 如果expression1 小于等于expression2 ,则为真
    !expression 表达式为假,则结果就为真;反之亦然

    关于上面比较符号的快速记法如下:eq=equal,gt=great than,lt=less than,然后组合拼凑即可,如果觉得这样还是很难记,就可以像我一样,将这些符号记录下来,需要的时候来查表-_-

     

    文件条件测试

    文件条件测试 结果
    -d file 如果文件是一个目录,则为真
    -f file 如果文件是一个普通文件,则为真;也可以用来测试文件是否存在
    -r file 如果文件可读,则结果为真
    -s file 如果文件大小不为0,则结果为真
    -w file 如果文件可写,则结果为真
    -x file 如果文件可执行,则结果为真

    这,真的是一个利民的测试

    循环结构

    for 循环

    先来看一种经典C语法版的for

    1
    2
    3
    4
    5
    6
    7
    
    #! /bin/bash
    
    for ((i=0;i<5;i++))
    do
        echo $i
    done
    exit 0
    
    

    看输出,

    0
    1
    2
    3
    4
    

    还支持在外部控制步长

    1
    2
    3
    4
    5
    6
    7
    8
    
    #! /bin/bash
    
    for ((i=0;i<5;))
    do
        echo $i
        i=$[$i+2]
    done
    exit 0
    
    0
    2
    4
    

    是不是感觉基本功能都有呀,就是写某些东西写起来奇怪点
    是不是有一种莫名的熟悉感

    另一种就是类似foreach的情况了,他的格式是这样的

    1
    2
    3
    4
    
    for variable in values
    do
        statements
    done
    
    

    其中values 可能有的情况为:

    1. 使用linux命令输出的行作为迭代的输入:ls,seq,cat之类均可,其实就可以完成很强大的文件读取功能

      1
      2
      3
      4
      5
      6
      7
      
      #! /bin/bash
      
      for i in `head -n 5 words.dit`;do  #words.dit 这是一个通用词表 每行一个词
          echo $i
      done
      
      exit 0
      

      可以看到通用词典中前5个词

      阿
      阿巴丹
      阿巴岛
      阿巴鸟
      阿巴伊达
      
    2. 使用$*可以来表示遍历传入的参数列表

      1
      2
      3
      4
      5
      6
      7
      
      #! /bin/bash
      
      for i in $*;do
          echo $i
      done
      
      exit 0
      

      来看个结果

      yans-MacBook-Pro:Downloads yanyl$ ./hi.sh  my name is tom
      my
      name
      is
      tom
      
    3. 还可以使用带空格的字符串 来进行按空格分隔输出

      1
      2
      3
      4
      5
      6
      7
      8
      
      #! /bin/bash
      
      a="yello red green"
      for i in $a;do
          echo $i
      done
      
      exit 0
      

      这样在一定程度上可以看成一个简易的数组

    这里需要注意的是包含条件以及循环逻辑是双重括号,以及开始结果的doDone

    while 循环

    另一个常用的就是while循环了

    他的结构是

    1
    2
    3
    4
    
    while condition
    do
        statements
    done
    

    这个也是蛮好理解的,可以来看一个demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    #! /bin/bash
    
    echo "please ent your password:"
    read pwd
    
    while [ "$pwd"x != "root"x  ] #这里加x是为了防止啥也不输入直接回车产生的报错
    do
        echo "error,please try again:"
        read pwd
    done
    echo "welcome here"
    
    exit 0
    

    看一下结果

    please ent your password:
    sha
    error,please try again:
    
    error,please try again:
    root
    welcome here
    

    很有意思的一个哈~

    until语句

    这个语句与while的结构完全一样,只是使用了until关键字来代替了while,然后在条件为true的时候停止,正好与while相反

    函数

    Shell这么叼,能没有函数吗

    1
    2
    3
    4
    
    [function] functon_name()
    {
        statements
    }
    

    上面是定义函数的结构,大致有以下几个要点

    1. 前面的function关键字可有可无,不过感觉还是加上去比较好,这样在代码里面比较好辨识
    2. 函数名后面的括号中不能带参数 取的参数是用过$1,$2…$n这样的方式来取的
    3. 调用的时候直接写函数名 不需要加括号
    4. 如果想传递参数的话 直接在调用后来加上参数列表 用空格隔开 (就是Shell的传参一样)
    5. 使用local关键字来定义函数体里面的局部变量
    6. 所以在函数调用必须在函数定义之后

    先看一个小的demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #! /bin/bash
    
    function sayhi()
    {
        echo hi $1
    }
    
    sayhi tom #前面的sayhi是函数的调用 后面的tom是传参
    
    exit 0
    

    可以看到输出

    hi tom
    

    函数的返回值

    关于Shell的返回值方式有两种

    1. 输出给主程序,他的结构为:

      1
      2
      3
      4
      5
      6
      
      function function_name()
      {
      	echo $something  #通过输出的方式来返回值
      }
      
      a=`function_name`  这种方式接收返回值
      

      看到的demo可以是这样的

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      Press ENTER or type command to continue
      #! /bin/bash
      
      function sum()
      {
          echo $[$1+$2]
      }
      
      a=`sum 1 2`
      
      echo the sum is $a
      exit 0
      

      最终输出结果为

      the sum is 3
      
    2. 使用return作为返回码来返回值

      1
      2
      3
      4
      5
      6
      7
      
      function function_name()
      {
      	return $ret #这里进行返回码的返回
      }
      
      function_name
      $? #在这里接收返回值
      

      一样再来一个demo

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      #! /bin/bash
      
      function sum()
      {
          return $[$1+$2]
      }
      
      sum 1 2
      echo the sum is $?
      
      exit 0
      

      可以看到输出为

      the sum is 3
      

    case语句

    这里的case的与传统的switch有点像,但是又像scala中的match模式匹配的强大,

    他的结构是这样的

    1
    2
    3
    4
    5
    
    case variable in
        pattern [ | pattern] ...) statements;;
        pattern [ | pattern] ...) statements;;
        ...
    esac
    

    来看这个强大的demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    #! /bin/bash
    
    function match()
    {
        case $1 in
            root ) echo this is password ;;
            h* ) echo hi $1 ;; #使用通配符
            yes | YES ) echo agree with me ;; #可以进行或操作
            * ) echo everything is here;;  #你可以理解为switch中的default
        esac
    }
    
    match root
    match hello
    match YES
    match Yes
    exit 0
    

    来看一下结果

    this is password
    hi hello
    agree with me
    everything is here
    

    注意,这里一旦匹配中了一个之后就马上会停止匹配

    外部命令/文件/语言的调用

    Shell的另一个强大之处就是可以无缝的和外部的命令,文件,语言结合,去调用组织他们

    1. 外部命令:一般情况下可以直接写外部命令,如果要赋值的话得使用``括起来
    2. 外部文件:比如资源配置文件,profile文件之类的,可以直接使用source关键字的来执行
    3. 外部语言:比如java,python可以直接使用他们的java调用jar,java文件,也可以直接使用关键字来执行python文件

    总结

    1. Shell很好很强大,得学习?。?!
    2. 注意变量的字符串格式以及需要数学运算时的语法
    3. 注意变量赋值时等号两端一定不能有空格以及再取值时一定要加$
    4. 平常的控制结束符号别忘了,比如fi,doen,esac
    5. 忘了的时候来查查这个文件

     

    原文://kubicode.me/2015/11/04/Linux/Shell-Command-List/

    上一篇:

    下一篇:

    相关推荐

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注

    1 + 5 = ?

    网站地图|广东快乐10分开奖直播

    Copyright © 2015-2019 广东快乐10分开奖直播 All rights reserved.
    闽ICP备15015576号-1,版权所有?psz.

  • 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 北京赛车pk10现场 世界杯足球比分 pk10两期免费计划app 新疆时时彩票中奖号码 3d试机号30期彩宝网 北京快乐8外围 世爵娱乐平台 重庆时时彩五星基本图 福利彩票3d走势图 澳客网app 新疆时时彩玩法大全 时时彩缩水网页版 500彩票网 北京pk10冠军杀1码 竞彩篮球大小分怎么算 新疆时时彩三星和值走势图彩经网