shell


变量的定义:
    1.=左右不要有空格
    2.如果内容有空格,需要使用单引号括起来
    3.双引号支持转义 $开头的变量会
    a=1
    b=severiruby
    d="hello from testerhome"
    e='hello from "大家伙"'
    f=`ls`
变量的使用:
    echo:是向屏幕输出
    echo $a
    单引号:括起来的内容包括$x,都会被当成字符串
    双引号:括起来的内容中的$x,会被引用
    反引号:反引号里面的内容会被当成一个命令去执行
        a=`ls`
        echo $a 输出:输入当前目录的显示的文件
        array=(`ls`) 将当前目录下的文件赋值一个变量
        echo ${array[@]} 输出:当前目录下的所有显示的文件
    ;(分号)表示一行命令的结束即放在多行执行
    例如:
        a=123
        echo 'this is $a' 输出是:this is $a
        echo "this is $a" 输出是:this is 123
打印没有定义的变量:
    例如:a=123
        echo ${a}_1  输出:123_1    
预定义变量:
    echo $PWD:打印当前目录的路径
    echo $UESR:打印的用户
    echo $HOME:打印当前的家目录
    echo $PATH:打印当前的环境变量
which:只会在当前的环境变量里面去查找
数组:一个连续的内存段,或者可以理解为一个集合
    数组的定义:用小括号括起来,用空格分隔开
    array=(1 2 3 4 5)
    echo ${array[@]} 取出所有的值,@加上双引号还是被当做数组来处理
    echo ${array[*]} 取出所有的值,*加上双引号会被当成字符串来处理
    echo ${array[2]} 取出下标为2的值 
特殊字符:
    1.反斜杠:   转义字符
    2.$(()),对变量进行操作,例如加减乘除
        a=1;b=3
        echo $((a+b))
    3.$(ls) 表示ls执行后的结果,与``反引号类似,不过可以嵌套
    4.``反引号,代表命令的输出
    5.(()) 是整数扩展,把里面的变量当做整数去处理
        a=1;b=2
        (($a>$b));echo $? 输出结果为:1 1>2结果是错误的,所以显示1
        (($a<$b));echo $? 输出结果为:0 1<2结果是正确的,所以显示0
        $?:表示上个语句的执行结果
        在bash里面0代正确,1代表错误的
        array=(`seq 1 10`) 创建1到10的数组
数字变量操作:
    a=1
    echo $(($a+1))或者
    ((a+=1))
    echo $a
字符串操作:
    s='hello from testerhome'
    echo ${s:6:3}
        第一个参数存储的字符串的变量
        第二个参数是从第几项开始,包括这一项
        第三个参数是从第几项结束,包括这一项
    ${#s}:计算字符串的长度
    去掉头部:
        echo ${s#hello}:删除字符串开头的“hello”,默认去掉后面空格
        echo "${s#hello}":加上双引号不会去掉后面的空格
        echo ${s#*o}:删除“o”以前的字符(包括本身),非贪婪匹配,值匹配到第一个
        echo ${s##*m}:贪婪匹配,删除字符串中所以有m之前的字符串(包括m本身)
    去掉尾部:
        echo ${s%h*}:从后面是删除,已"h"开头的后面的字符(包括其本身),非贪婪匹配
        echo ${s%%o*}:贪婪匹配,删除所有已"o"开头的后面的字符(包括其本身)
    替换:
        echo ${s/testerhome/severiruby} :用severiuby替换testerhome
        echo ${s/h/xxx}:将字符串中第一个h字符替换成xxx,非贪婪替换
        echo ${s//h/xxx}:
布尔变量:
    true
    false
    ❖ 命令执⾏返回值 $?
    ❖ 任何命令执⾏都会有⼀个返回值
    ❖ 0表⽰正确
    ❖ ⾮0表⽰错误
算数判断:
       [ 2 –eq 2 ] 相等
    ❖ [ 2 –ne 2 ] 不等
    ❖ [ 3 –gt 1 ] 大于
    ❖ [ 3 –ge 3 ] 大于等于
    ❖ [ 3 –lt 4 ] 小于
    ❖ [ 3 –le 3 ] 小于等于
    ❖ (())也可以表⽰算术⽐较。((10>=8)) ,((10==10))
字符串比较:
    a="test";b="hello test"
    [ $a = $b ] :如果两个字符串相等,则结果为真
    [ $a != $b ] : 如果两个字符串不相同,则结果为真
    [ -n "$a" ] : 如果字符串不是空,则结果为真
    [ -z "$a" ] : 如果字符串是空,则结果为真
逻辑判断:
    -a:与--只有一个为假,则结果为假
    -o:或--只要一个为真,则结果为真
    [ 2 -ge 1 -a 3 -ge 4 ];echo $?  表示:1大于等于1与3大于等于4,求“与”,结果为:假
    [ 2 -ge 1 -o 3 -ge 4 ];echo $? 表示:1大于等于1与3大于等于4,求“或”,结果为:真

    [[ 2 -ge 1 && 3 -ge 4 ]];echo $? 与
    [[ 2 -ge 1 || 3 -ge 4 ]];echo $? 或

    [ ! 2 -ge 1] 非 表示2不大于等于1,结果为假

    if 条件判断;
    then
    为真时执行的语句;
    else
    为假时执行的语句;
    fi
    if [ -e 1.txt ];then echo exist;else echo not exist;fi 如果1.txt是文件,那么输出exist;否则,输出not exist
    简写:
        ls 1.txt && echo exist || echo not exist 如果1.txt存在,输出exist;否则输出not exist
        [ -e test ] || echo exist && echo not exist 
            ||:表示当判断为false的时候执行
            &&:表示当判断为true的时候执行

    for 语法:
    for ((i=0;i<10;i++));
    do
    满足条件是执行的语句
    done    
    不满足条件是执行

    for循环:
        例子:
            数组:用小括号括起来
            array=(a b c d e)
            for ((i=0;i<${#array[*]};i++));do echo ${array[i]};done
    for遍历循环:
        例子:
          array=(a b c d e)  
          for x in ${array[*]};do echo $x;done
          遍历目录下的所有文件:
            for x in *;do echo $x;done
    while循环:
        i=0;
        while ((i<3));do
        echo $i;
        ((i=i+1));
        done
    while read line;do echo $line;done < 2
        循环读取文件2中字符
        read:读入一个标准输入
    read -p "enter:" x;echo 我刚刚输入了:$x
        -p:想当于input
    退出循环:
        break:直接跳出循环
            for x in *;do echo $x;if [ -d $x ];then break;fi;done
        continue:跳出本次循环,进入下次循环
            for x in *;do echo $x;if [ -f $x ];then $x is file;else continue;fi;done
    $$:获取当前的进程号
    (a=1;echo $a):小括号表示的子shell
    {a=1;echo $a}:大括号表示当前的语句块
    &;放在后台执行进程
    $!:获取后台的最后一个进程的进程号
    jobs:显示后台运行的进程
    fg:将从后台进程放到前台执行
    vim文件中的操作:
        set number 设置行号
        set nonu   取消行号
        gg  跳转到文件头部 (在esc模式下)
        GG  跳转到文件尾部 (在esc模式下)
        在文件中复制:
            在esc模式下,按住v,按上下左右进行选中要复制的内容,然后在按v,再按p进行复制
    >:表示将内容输出到某个文件,并且第二次输出,会覆盖上一次的内容
    >>:不会覆盖上一次的内容
        echo "hello testerhome" > 1.txt
    <:将某个文件中内容输入
        read x < 1.txt
    将错误信息输入到某个文件:
        ls ddd > a 2>&1:将错误信息写入到a,2>&1是固定的
Shell 输入与输出
    echo ,printf可以简单输出变量。
    > file 将输出重定向到另⼀个⽂件
    >> 表示追加 等价于tee -a
    < file 输⼊重定向
    | 表示管道,也就是前一个命令的输出传一个命令的输入
    echo "* ????":放入到引号中可以避免转义
Shell环境变量
    set 可以获得当前的所有变量,declare
    unset 可以释放变量
    env 可以获得可以传递给⼦进程的变量
    export aa=bbbb 把私有变量导出,等价于declare -x
Linux三剑客
    grep:基于正则表达式查找满足条件的行,即数据查找定位
    awk:根据定位到的数据行处理其中的分段, 即数据切片
    sed :根据定位到的数据行修改数据, 即数据修改

    grep:
        grep -i pattern file 忽略大小写
        grep -v pattern file 不显示匹配的行
        grep -o pattern file 精准匹配
        grep -E pattern file 使用扩展正则表达式
        grep pattern -r dir/ 递归搜索
        -A -B -C 后面都跟阿拉伯数字 
        -A是显示匹配后和它后面的n行。 
        -B是显示匹配行和它前面的n行。 
       -C是匹配行和它前后各n行。 
       总体来说,-C覆盖面最大。用它保险些。这3个开关都是关于匹配行的上下文的(context)。

      于是:grep -A 4 wikipedia 密码文件.txt 
      就是搜索密码文件,找到匹配“wikipedia”字串的行,显示该行后后面紧跟的4行。

    awk:
        awk 'BEGIN{}END{}' 开始和结束
        awk '/running/'    正则匹配
        awk '/aa/,/bb/'    区间选择
        awk '$2~/xxx/'     字段匹配
        awk 'NR==2'        去第二行
        awk 'NR>1'         去掉第一行
        awk内置变量:
            FS:字段分隔符
            OFS:输出数据的字段分隔符
            RS:记录分隔符即行分隔符
            ORS:输出字段的行分隔符
            NF:字段数
            NR: 记录数即行数
        awk的字段处理:
            -F 参数指定字段分隔符
            BEGIN{FS="-"} 也可以表示字段分隔符
            $0代表当前的记录
            $1代表第一个字段
            $2代表第N个字段
            $NF代表最后一个字段 
    一键搭建网站:
         python2 -m CGIHTTPServer 8000
         python3 -m http.server -cgi 8000
    脚本:
        #:表示注释
        $0:表示执行的程序,是相对于执行目录的路径
        $1,$2,$3分别表示第几个参数,默认shell只支持9个参数
        $@,$*表示所有的参数,不包含$0
        ${#*}和${#@}:表示参数的个数
        $@于$*的区别:
            $@:可以在函数直接传递参数,并不改变参数的排列
            $*:会把参数打散,相对顺序不变,但是参数的个数就变了
        函数:Function f(){...}
            Function可以省略,除了可以在脚本文件中使用函数外,换可以在shell中定义,这些定义会在本次shell结束后消失
            如果没有return,返回值是最后一句指令的返回值
        执行方式:
            chmod u+x xxx.sh   ./xxx.sh
            bash xxx.sh
            source xxx.sh
        bash -x :读取每一句,并执行,可以方便的看到执行的语句
        set -x:在当前shell中调试,set+x还原

    统计指定的进程的CPU100次:
        for i in {1..100};do top -d 1 -n 1 -p 2167 | grep 2167 | awk '{print $10}';done
    从PATH中,已冒号为记录行,修改每行最后一个
        cat $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed 's#/[^/]*$#jjjjj#g' 
    从shell服务器上的/tmp/nginx.log中找出所有404和500的报错数据,并去除其中的url
        grep -E  " 404|500 " /tmp/nginx.log 
        awk '$9~/404|500/{print}' nginx.log | sed 's# /[0-9a-z]*##g';
    获取访问量最高的ip:
        awk '{print $1}' /tmp/nginx.log | sort | uniq -c | sort -n | tail -10




Shell中的>/dev/null 2>&1 与 2>&1 >/dev/null 与&>/dev/null 的区别

>/dev/null 2>&1

//  实际上,应该等同于这样: 1>/dev/null 2>/dev/null ,默认情况下就是1,标准输出,所以一般都省略。 而&符号,后面接的是必须的文件描述符。不能写成2>1,这样就成了标准错误重定向到文件名为1的文件中了,而不是重定向标准错误到标准输出中。所以这里就是:标准输出重定向到了/dev/null,而标准错误又重定向到了标准输出,所以就成了标准输出和标准错误都重定向到了/dev/null

2>&1 >/dev/null

// 咋一看,这个跟上面那个有啥区别呢,不也是标准错误重定向到标准输出,而标准输出重定向到/dev/null么? 最后不应该都重定向/dev/null么? 我是这么理解的!一条指令同一时刻要么产生标准错误,要么产生标准输出。 当产出标准错误的时候,因这个标准错误重定向到了标准输出,而标准输出是输出到屏幕。这个时候标准输出还没有被重定向到/dev/null,于是在屏幕上打印了。当产生标准输出时,那么它就不是标准错误,2>&1无效,于是标准输出重定向dev/null,不打印到屏幕。所以最终结果将是:标准错误打印到屏幕,而标准输出不打印到屏幕。

&>/dev/null

// 这个就是,不管你是啥玩意儿文件描述符,通通重定向到/dev/null

shell curl 取得HTTP返回的状态码

curl -I -m 10 -o /dev/null -s -w %{http_code} www.baidu.com
  • -I 仅测试HTTP头
  • -m 10 最多查询10s
  • -o /dev/null 屏蔽原有输出信息
  • -s silent 模式,不输出任何东西
  • -w %{http_code} 控制额外输出
原文地址:https://www.cnblogs.com/an5456/p/11103986.html