zoukankan      html  css  js  c++  java
  • 学习bash

    工作8年,前6年基本是Windows环境下,也就是个鼠标党;两年前换工作开始用linux,也就开始了领略了命令行的强大,无论是直接在命令行组合命令,也还写几行简单的shell脚本,其能完成的功能往往令人难以置信。

    如果说我工作中第一次感觉“哇”是08年左右开始使用perl处理文本 - 发现脚本原来可以如此强大,自动化那么多工作;那么第二次就应当是使用bash - 原来不用写脚本也能如此强大。(尤其对原Windows下鼠标+菜单党来讲)

    这两天比较系统的看了下bash reference manual,记录一下。

    一、命令行交互

    这里包括两个部分,一个是readline支持的命令行编辑功能,有不同的编辑style:emacs和vi模式:

    • set -o emacs
    • set -o vi

    用vi模式的话,使用vi一些常用的命令,编辑起来自然方便,但是需要先escape一下进入操作模式。但是对于平时99%的工作,一些常用的快捷键已经足够满足了:

    • C-a, C-e:移动到行首,行尾
    • Alt->, Alt-<-:前移,后移一个单词 (最好自己定义成右alt,额,好像是我的右alt键坏掉了。。。)
    • C-b, C-f:前移,后移一个字符
    • C-l:清空屏幕
    • C-w:删除前一个单词
    • Alt-d:删除后一个单词
    • C-d:删除当前字符
    • C-y:粘贴前次删除内容

    这些快快捷键是readline的默认定义,一般在/etc/inputrc可以找到系统全局定义,然后个人可以定义:~/.inputrc

    另一部分是历史管理,下面是一些要点:

    • 控制历史的一些变量:HISTSIZE,HISTFILE,HISTFILESIZE
    • 设置HISTTIMEFORMAT='%F %T '在历史中显示命令运行时间
    • C-r:查找历史并运行
    • history expansion
      • !! - 上一条命令
      • !preceding - 上一条以preceding开始的命令
      • !$ - 上一个命令的最后一个参数
      • !n - 第n个命令
      • !-n - 倒数第n个命令

    二、语法

    1. 五种quoting

    • A:转义,保持字符原意,如果在行末,则表示续行
    • 'string':single quoted string,不进行转义,变量expansion
    • “string”:double quoted string,进行转义,变量expansion
    • $'string':访问一些特殊字符,如$'a', $' '
    • $"string":locale specific translation, translated according to the current locale

    2. 注释

    以#开头的行均为注释,除了第一行:

    #!/bin/bash

    3. 控制结构

    • 简单命令:cmd
    • pipeline: cmd1 | cmd2
    • 命令序列:
      • cmd1; cmd2: 顺序执行两条命令
      • cmd1& cmd2:并行执行两条命令,其中cmd1在后台执行
      • cmd1 && cmd2: 如果cmd1成功了,执行cmd2
      • cmd1 || cmd2:如果cmd1失败了,执行cmd2
    • 循环控制
      • until test-commands; do consequent-commands; done
      • while test-commands; do consequent-commands; done
      • for name [ [in [words …] ] ; ] do commands; done
      • for (( expr1 ; expr2 ; expr3 )) ; do commands ; done - 例子:for ((i=1; $i < 100; i++)); do echo $i; done
    • 条件控制
      • if
        if的测试表达式有三种情况:-x表示文件或者变量测试;(==, !=, >, <)表示字符串测试;(-gt, -lt, -eq, -ne, -ge)等表示数字测试。
      • if后测试的表达式可以有三种:
        • [[ expression ]]
        • [ expression ]
        • test expression
      • if test-commands; then
          consequent-commands;
        [elif more-test-commands; then
          more-consequents;]
        [else alternate-consequents;]
        fi
      • case
        case word in [ [(] pattern [| pattern]…) command-list ;;]… esac
        
        echo -n "Enter the name of an animal: "
        read ANIMAL
        echo -n "The $ANIMAL has "
        case $ANIMAL in
          horse | dog | cat) echo -n "four";;
          man | kangaroo ) echo -n "two";;
          *) echo -n "an unknown number of";;
        esac
        echo " legs."
      • select
        select name [in words …]; do commands; done
        
        select fname in *;
        do
            echo you picked $fname ($REPLY)
            break;
        done
    • 命令组合
      • 新起shell:( list )
      • 当前shell:{ list; }

    4. 函数

    语法
    name () compound-command [ redirections ]
    or
    function name [()] compound-command [ redirections ]
    
    定义
    function reverse() {
        echo $3-$2-$1
    }
    
    调用
    echo `reverse hello world thanks`

    5. 参数

    参数有脚本的参数、函数的参数,都是用$1-$9等来访问, $0表示脚本或者函数名字,这些叫做positional parameters,还有一些特殊的参数:$*, $@, $#, $?, $-等等

    6. Shell expansion

    • brace expansion: echo a{b, c, d}e
    • tilde expansion: cd ~; cd ~user/bin
    • shell parameter expansion: ${parameter}, , ${parameter:-word}.${parameter:=word}
    • command expansion: $(cmd) or `cmd`
    • arithmetic expansion: $((1+2*6))
    • word splitting
    • filename expansion: *.txt
    • quote removal

    7. Redirection

    • >: write stdout to file
    • >>: append stdout to file
    • &>: write stdout and stderr to file
    • &>>: append stdout and stderr to file
    • tee: ls | tee ls.txt

    8. Variable & array

    # variable
    x=5
    echo $x
    
    #array:
    arr[0]=100
    echo ${arr[0]}
    
    #associate array:
    declare -A map
    map[hello]=world
    echo ${map[hello]}

    三、内建命令与变量

    builtin的命令,用help就可以全部打出来, 然后逐个help就可以看到大致介绍。

    有两个主要的设置命令:

    • set
    • shopt

    控制bash的各种行为模式。

    但有个eval命令我有点搞不清楚:

    $ help eval
    eval: eval [arg ...]
    Execute arguments as a shell command.

    Combine ARGs into a single string, use the result as input to the shell,
    and execute the resulting commands.

    Exit Status:
    Returns exit status of command or success if command is null.

    这个,与没有eval,直接run命令有什么区别呢?搜了一下,发现这么个例子:

    for i in 2 3 4; do
     eval a$i=2
     eval echo "$a$i" 
    done

    动态组合变量名字并赋值,这个在shell里直接是做不到的。

    另外,三类比较常用的命令:

    • 别名:alias, unalias
    • job控制:jobs, fg, bg, kill, C-z
    • 目录管理:dirs, popd, pushd

    内置的变量,主要用来控制行为,或者暴露信息,臂长常用的有PATH, PS1, PS2, PWD, HOSTNAME, HISTFILE, IFS, CDPATH(这个貌似可以好好利用一下)

    四、常用非内建命令

    这里指的是非bash内置命令,但是linux内置的,或者另外安装的一些常用命令,非常有效,这里列几个自己用的比较多的:

    du
    df
    strace
    lsof
    ps aux
    netstat
    grep
    find
    wget
    curl
    tr
    ssh
    sort
    uniq
    awk
    wc

    cut
    top
    free
    vim
    p4
    perl -pei

  • 相关阅读:
    代码风格
    C语言带返回值的宏
    设计模式之PIMPL模式
    打印控制之VT100
    C语言实现反射
    C语言实现函数override
    [BZOJ3669] [NOI2004] 魔法森林 LCT维护最小生成树
    [BZOJ4826] [HNOI2017] 影魔 单调栈 主席树
    [BZOJ2054]疯狂的馒头 并查集
    [BZOJ5305] [HAOI2018] 苹果树 数学 组合计数
  • 原文地址:https://www.cnblogs.com/baiyanhuang/p/3149239.html
Copyright © 2011-2022 走看看