zoukankan      html  css  js  c++  java
  • Bash速查表

    #!/usr/bin/env bash
    
    NAME="John"
    echo "Hello $NAME!"

    变量

    NAME="John"
    echo $NAME
    echo "$NAME"
    echo "${NAME}!"

    字符串引号

    NAME="John"
    echo "Hi $NAME"  #=> Hi John
    echo 'Hi $NAME'  #=> Hi $NAME

    条件执行

    git commit && git push
    git commit || echo "Commit failed"

    功能

    get_name() {
      echo "John"
    }
    
    echo "You are $(get_name)"

    Shell执行

    echo "I'm in $(pwd)"
    echo "I'm in `pwd`"
    # Same

    条件语句

    if [[ -z "$string" ]]; then
      echo "String is empty"
    elif [[ -n "$string" ]]; then
      echo "String is not empty"
    fi

    扩展

    echo {A,B}.js
    {A,B}    与...一样 A B
    {A,B}.js    与...一样 A.js B.js
    {1..5}    与...一样 1 2 3 4 5

    严格的模式

    set -euo pipefail
    IFS=$'
    	'

    参数扩展

    基本

    name="John"
    echo ${name}
    echo ${name/J/j}    #=> "john" (substitution)
    echo ${name:0:2}    #=> "Jo" (slicing)
    echo ${name::2}     #=> "Jo" (slicing)
    echo ${name::-1}    #=> "Joh" (slicing)
    echo ${name:(-1)}   #=> "n" (slicing from right)
    echo ${name:(-2):1} #=> "h" (slicing from right)
    echo ${food:-Cake}  #=> $food or "Cake"
    
    length=2
    echo ${name:0:length}  #=> "Jo"
    
    STR="/path/to/foo.cpp"
    echo ${STR%.cpp}    # /path/to/foo
    echo ${STR%.cpp}.o  # /path/to/foo.o
    
    echo ${STR##*.}     # cpp (extension)
    echo ${STR##*/}     # foo.cpp (basepath)
    
    echo ${STR#*/}      # path/to/foo.cpp
    echo ${STR##*/}     # foo.cpp
    
    echo ${STR/foo/bar} # /path/to/bar.cpp
    STR="Hello world"
    echo ${STR:6:5}   # "world"
    echo ${STR:-5:5}  # "world"
    SRC="/path/to/foo.cpp"
    BASE=${SRC##*/}   #=> "foo.cpp" (basepath)
    DIR=${SRC%$BASE}  #=> "/path/to/" (dirpath)

    代换

    ${FOO%suffix}    删除后缀
    ${FOO#prefix}    删除前缀
    ${FOO%%suffix}    删除长后缀
    ${FOO##prefix}    删除长前缀
    ${FOO/from/to}    替换第一场比赛
    ${FOO//from/to}    全部替换
    ${FOO/%from/to}    替换后缀
    ${FOO/#from/to}    替换前缀

    长度

    ${#FOO}    的长度 $FOO

    解释

    # Single line comment
    : '
    This is a
    multi line
    comment
    '

    ${FOO:0:3}    子串(位置,长度)
    ${FOO:-3:3}    来自右边的子串

    默认值

    ${FOO:-val}    $FOO,或者val如果没有设置
    ${FOO:=val}    设置$FOO到val如果没有设置
    ${FOO:+val}    val如果$FOO设置
    ${FOO:?message}    显示错误消息,如果$FOO未设置则退出

    循环

    循环基础

    for i in /etc/rc.*; do
      echo $i
    done

    for循环

    for ((i = 0 ; i < 100 ; i++)); do
      echo $i
    done
    for i in {1..5}; do
        echo "Welcome $i"
    done
    步长
    for i in {5..50..5}; do
        echo "Welcome $i"
    done

    死循环

    while true; do
      ···
    done

    行循环

    < file.txt | while read line; do
      echo $line
    done

    函数

    定义函数

    myfunc() {
        echo "hello $1"
    }
    # Same as above (alternate syntax)
    function myfunc() {
        echo "hello $1"
    }
    myfunc "John"

    参数

    $#    参数数量
    $*    所有参数
    $@    所有参数,从第一个开始
    $1    第一个参数

    返回

    myfunc() {
        local myresult='some value'
        echo $myresult
    }
    result="$(myfunc)"

    提出错误

    myfunc() {
      return 1
    }
    if myfunc; then
      echo "success"
    else
      echo "failure"
    fi

    条件

    条件

    [[ -z STRING ]]    空字符串
    [[ -n STRING ]]    不是空字符串
    [[ STRING == STRING ]]    等于
    [[ STRING != STRING ]]    不平等
    [[ NUM -eq NUM ]]    等于
    [[ NUM -ne NUM ]]    不相等
    [[ NUM -lt NUM ]]    少于
    [[ NUM -le NUM ]]    小于等于
    [[ NUM -gt NUM ]]    大于
    [[ NUM -ge NUM ]]    大于或等于
    [[ STRING =~ STRING ]]    正则表达式
    (( NUM < NUM ))   数字条件
    [[ -o noclobber ]]    如果启用了OPTIONNAME
    [[ ! EXPR ]]    非
    [[ X ]] && [[ Y ]]    与
    [[ X ]] || [[ Y ]]    或

    文件条件

    [ -e FILE ]]    存在
    [[ -r FILE ]]    可读
    [[ -h FILE ]]    符号链接
    [[ -d FILE ]]    目录
    [[ -w FILE ]]    可写
    [[ -s FILE ]]    大小> 0字节
    [[ -f FILE ]]    文件
    [[ -x FILE ]]    可执行文件
    [[ FILE1 -nt FILE2 ]]    1比2更新
    [[ FILE1 -ot FILE2 ]]    2比1更近
    [[ FILE1 -ef FILE2 ]]    相同的文件

    if ping -c 1 google.com; then
      echo "It appears you have a working internet connection"
    fi
    
    if grep -q 'foo' ~/.bash_history; then
      echo "You appear to have typed 'foo' in the past"
    fi
    
    # String
    if [[ -z "$string" ]]; then
      echo "String is empty"
    elif [[ -n "$string" ]]; then
      echo "String is not empty"
    fi
    # Combinations
    if [[ X ]] && [[ Y ]]; then
      ...
    fi
    # Equal
    if [[ "$A" == "$B" ]]
    # Regex
    if [[ "A" =~ "." ]]
    if (( $a < $b )); then
       echo "$a is smaller than $b"
    fi
    if [[ -e "file.txt" ]]; then
      echo "file exists"
    fi

    数组

    定义数组

    Fruits=('Apple' 'Banana' 'Orange')
    Fruits[0]="Apple"
    Fruits[1]="Banana"
    Fruits[2]="Orange"

    使用数组

    echo ${Fruits[0]}           # Element #0
    echo ${Fruits[@]}           # All elements, space-separated
    echo ${#Fruits[@]}          # Number of elements
    echo ${#Fruits}             # String length of the 1st element
    echo ${#Fruits[3]}          # String length of the Nth element
    echo ${Fruits[@]:3:2}       # Range (from position 3, length 2)

    操作

    Fruits=("${Fruits[@]}" "Watermelon")    # Push
    Fruits+=('Watermelon')                  # Also Push
    Fruits=( ${Fruits[@]/Ap*/} )            # Remove by regex match
    unset Fruits[2]                         # Remove one item
    Fruits=("${Fruits[@]}")                 # Duplicate
    Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
    lines=(`cat "logfile"`)                 # Read from file

    迭代

    for i in "${arrayName[@]}"; do
      echo $i
    done

    字典

    定义

    declare -A sounds
    sounds[dog]="bark"
    sounds[cow]="moo"
    sounds[bird]="tweet"
    sounds[wolf]="howl"

    使用词典

    echo ${sounds[dog]} # Dog's sound
    echo ${sounds[@]}   # All values
    echo ${!sounds[@]}  # All keys
    echo ${#sounds[@]}  # Number of elements
    unset sounds[dog]   # Delete dog

    迭代

    迭代value
    
    for val in "${sounds[@]}"; do
      echo $val
    done
    
    迭代键
    
    for key in "${!sounds[@]}"; do
      echo $key
    done

    选项

    选项

    set -o noclobber  # Avoid overlay files (echo "hi" > foo)
    set -o errexit    # Used to exit upon error, avoiding cascading errors
    set -o pipefail   # Unveils hidden failures
    set -o nounset    # Exposes unset variables

    全局选项

    set -o nullglob    # Non-matching globs are removed  ('*.foo' => '')
    set -o failglob    # Non-matching globs throw errors
    set -o nocaseglob  # Case insensitive globs
    set -o globdots    # Wildcards match dotfiles ("*.sh" => ".foo.sh")
    set -o globstar    # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')

    历史

    命令

    history    显示历史
    shopt -s histverify    不要立即执行扩展结果

    操作

    !!    再次执行最后一个命令
    !!:s/<FROM>/<TO>/    在最近的命令中替换第一次出现的<FROM>to<TO>
    !!:gs/<FROM>/<TO>/    在最近的命令中替换所有出现的<FROM>to<TO>
    !$:t    仅从最近命令的最后一个参数扩展basename
    !$:h    从最近命令的最后一个参数扩展目录
    !!并且!$可以替换为任何有效的扩展。

    展开

    !$    展开最近命令的最后一个参数
    !*    展开最近命令的所有参数
    !-n    展开n最近的命令
    !n    n在历史记录中展开命令
    !<command>    展开最近的命令调用 <command>
    !!:n    仅从n最近的命令扩展该令牌(命令是0;第一个参数是1)
    !^    从最近的命令扩展第一个参数
    !$    从最近的命令扩展最后一个标记
    !!:n-m    从最近的命令扩展标记范围
    !!:n-$    n从最近的命令扩展令牌到最后

    杂项

    数值计算

    $((a + 200))      # Add 200 to $a
    $((RANDOM%=200))  # Random number 0..200

    检查命令

    command -V cd
    #=> "cd is a function/alias/whatever"

    错误

    trap 'echo Error at about $LINENO' ERR
    要么
    
    traperr() {
      echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
    }
    
    set -o errtrace
    trap traperr ERR

    相对路径

    source "${0%/*}/../share/foo.sh"

    脚本目录

    DIR="${0%/*}"

    定界符

    cat <<END
    hello world
    END

    阅读输入

    echo -n "Proceed? [y/n]: "
    read ans
    echo $ans
    read -n 1 ans    # Just one character

    转到上一个目录

    pwd # /home/user/foo
    cd bar/
    pwd # /home/user/foo/bar
    cd -
    pwd # /home/user/foo

    子shell

    (cd somedir; echo "I'm now in $PWD")
    pwd # still in first directory

    重定向

    python hello.py > output.txt   # stdout to (file)
    python hello.py >> output.txt  # stdout to (file), append
    python hello.py 2> error.log   # stderr to (file)
    python hello.py 2>&1           # stderr to stdout
    python hello.py 2>/dev/null    # stderr to (null)
    python hello.py &>/dev/null    # stdout and stderr to (null)
    python hello.py < foo.txt      # feed foo.txt to stdin for python

    案例/开关

    case "$1" in
      start | up)
        vagrant up
        ;;
    
      *)
        echo "Usage: $0 {start|stop|ssh}"
        ;;
    esac

    打印

    printf "Hello %s, I'm %s" Sven Olga
    #=> "Hello Sven, I'm Olga

    获得选择

    while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
      -V | --version )
        echo $version
        exit
        ;;
      -s | --string )
        shift; string=$1
        ;;
      -f | --flag )
        flag=1
        ;;
    esac; shift; done
    if [[ "$1" == '--' ]]; then shift; fi

    特殊变量

    $?    退出上次任务的状态
    $!    最后一个后台任务的PID
    $$    shell的PID
  • 相关阅读:
    POJ 1741 Tree(树分治)
    HDU 2196 Computer(树形dp)
    2015沈阳区域赛Meeting(最短路 + 建图)
    make the fence great again(dp 二维)
    2017沈阳区域赛Infinite Fraction Path(BFS + 剪枝)
    bitset详解
    2016青岛区域赛.Coding Contest(费用流 + 概率计算转换为加法计算)
    2019上海网络赛B题(差分 + 离散化 or 差分 + 思维)
    poj-1664.放苹果.(递推)
    hdu-4738.Caocao's Bridges(图中权值最小的桥)
  • 原文地址:https://www.cnblogs.com/songyifan427/p/11003769.html
Copyright © 2011-2022 走看看