Skip to content

Latest commit

 

History

History
637 lines (518 loc) · 14.7 KB

linux_bash_crash.md

File metadata and controls

637 lines (518 loc) · 14.7 KB

Bash

Common

  • ;
    • bash在解析字符的时候,对待“;”跟看见回车是一样的行为
  • [ ... ]
    • 其实就是个shell test命令的另一种写法
    • 命令加参数要用空格分隔, 所以 [ ... ] 需要加空格
  • [[ ... ]]
    • a Bash extension , bash, zsh, yash support it
    • bash built-in, and cannot be used in a #!/bin/sh script
    • benefits
      • == and != perform pattern matching, so the right-hand side can be a glob pattern
        $ [[ abc = *bc ]] ; echo $?
        0
      • =~ performs regular expression matching. Captured groups are stored in the BASH_REMATCH array.
      • boolean operators && and ||
      • no word splitting, so it's not strictly necessary to quote your variables.
    • drawback:
      • your script is now bash-specific.
  • (...)
    • indicate a subshell
    • What's inside is a list of commands (just like outside parentheses)
    • These commands are executed in a separate subprocess,
      • so any redirection, assignment, etc. performed inside the parentheses has NO EFFECT outside the parentheses.
    • With a leading dollar sign, $(…) is a command substitution
    • the output from the command is used as part of the command line
  • ((...))
    • double parentheses surround an arithmetic instruction
    • mostly used for assignments and in conditionals. This only exists in ksh/bash/zsh, not in plain sh.
    • The same syntax is used in arithmetic expressions $((…)), which expand to the integer value of the expression.
  • list
    • 若干shell命令组成的序列, 使用 管道;&&&|| 这些符号串联起来
  • 一切皆表达式
    • shell在执行任何东西(注意是任何东西,不仅是命令)的时候都会有一个 return status
    • 0-255
      • 0为真(true)
      • 非0为假(false)
    • echo $? 来查看上一个执行命令的返回值
  • !
    • 对表达式求反
  • bash 通配符
    • ? 单个字符
    • * 任意数量的字符
    • [...] 类似正则表达式中的[]
  • $ 变量
    • $0 获得自己执行命令的进程名称
    • $n 第n个参数
    • $# 参数个数
    • $*, $@ holds list of all arguments passed to the script
    • $? 上一个命令的返回值
    • 所以上述所有取值都可以写成${x}的方式

if

if list; then list; elif list; then list; ... else list; fi

等价于

if list
then 
  list
elif list
then 
  list
... 
else 
  list
fi
  • if 后面跟的就是个shell命令
    • return status 作为 condition (0 is true)
    • if cd mydir; then ...
  • if语法中 后面最常用的命令就是 []
    • if [ $ret -eq 0 ] ...
    • 等价于 if test $ret -eq 0 ...

while / until

while list-1
do
    list-2
done

until list-1
do
    list-2
done
  • while list-1; do list-2; done
  • until list-1; do list-2; done

case

case EXPRESSION in

  PATTERN_1)
    STATEMENTS
    ;;

  PATTERN_2)
    STATEMENTS
    ;;

  PATTERN_N)
    STATEMENTS
    ;;

  *)
    STATEMENTS
    ;;
esac

for loop

for VARIABLE in LIST
do
    command1
    command2
done
  • while LIST could be
    1. for VARIABLE in 1 2 3 4 5 .. N
    2. for VARIABLE in file1 file2 file3
    3. for OUTPUT in $(Linux-Or-Unix-Command-Here)
    4. for i in {1..5}
      • bash3.0+

C-sytle syntax

for (( initializer; condition; step ))
do
  shell_COMMANDS
done

e.g.

for (( c=1; c<=5; c++ ))
do
   echo "Welcome $c times"
done

select

select i in a b c d
do
    echo $i
done

提供给了我们一个构建交互式菜单程序的方式

$ ./select.sh
1) a
2) b
3) c
4) d
#?


#!/bin/bash
select i in a b c d
do
    case $i in
        a)
        echo "Your choice is a"
        ;;
        b)
        echo "Your choice is b"
        ;;
        c)
        echo "Your choice is c"
        ;;
        d)
        echo "Your choice is d"
        ;;
        *)
        echo "Wrong choice! exit!"
        exit
        ;;
    esac
done

continue / break

内建命令,并不是关键字

built-in commands

  • source, or .
    • 读取文件的内容,并在当前bash环境下将其内容当命令执行
  • read
    • 从 标准输入读取输字符串到一个变量中
      • read -p "Login: " username
    • 读取到数组中
      • read -a test
  • mapfile
    • 将一个文本文件直接变成一个数组,每行作为数组的一个元素
  • readarray
    • 同上
    • 如果内建命令放到管道环境中执行,那么bash会给它创建一个subshell进行处理。于是创建的数组实际上与父进程没有关系
  • printf
    • 进行格式化输出
  • getopts
    • 命令行参数处理

Execution

  • 优先级
    • alias
    • keyword
    • function
    • built-in commands (cd, pwd, etc...)
    • hash (用hash命令可以查看 hash情况)
    • external commands
  • you can use type to check whether a command is built-in, external, alias, or etc.
    $ type pwd
    pwd is a shell builtin
    $ type docker
    docker is /usr/local/bin/docker
    $ type myfind
    myfind is a shell function from /Users/xxx/.myProfile
  • 脚本的退出
    • built-in command exit , 人为指定退出的返回码是多少
    • 如果不使用exit 指定,使用最后执行命令的返回码
  • 调试
    • -v 可视模式, 执行bash程序的时候将要执行的内容也打印出来
    • -x 跟踪模式(xtrace), 跟踪各种语法的调用,并打印出每个命令的输出结果
    • -n 检查bash的语法错误, 不会真正执行bash脚本
    • -e 脚本命令执行错误的时候直接退出

环境变量

  • env
    • 查看当前bash已经定义的环境变量
  • aaa=100
    • 这是个一般变量,不能被子进程继承
  • export
    • 可以将一个一般变量转成环境变量
    • export aaa

常用环境变量

  • 进程信息
    • HOSTNAME
    • HOSTTYPE
    • OLDPWD / PWD
    • HOME
    • SHELL
    • BASHPID
    • UID / EUID
    • GROUPS 用户组
    • PPID 父进程PID
  • RANDOM
    • 得到一个0-32767的随机数
      echo $RANDOM
      24746
  • ulimit
    • 查看和设置bash环境中的资源限制
    • ulimit -a

redirection

  • shell在产生一个新进程后,新进程的前三个文件描述符都默认指向三个相关文件
    • 0 stdin
    • 1 stdout
    • 2 stderr
  • stdin redirection
    • 可以读取其他终端输入
    • cat < /dev/pts/3
  • stdout redirection
    • >
  • stderr redirection
    • 2>
  • 常见用法
    • 只看报错信息
      • xxx > /dev/null
    • 只看正确输出
      • xxx 2> /dev/null
    • 所有输出都不看
      • xxx &> /dev/null
      • or xxx >& /dev/null
      • short-cut to > /dev/null 2>&1, but not support by Dash, POSIX Shells, and Ksh, e.g. /bin/sh
    • 将标准报错输出,重定向到和标准输出相同的地方
      • xxx 2>&1
      • &1 表示 引用 fd 1
    • 从描述符3读取
      • 3<
  • To understand "redirecting to /dev/null"
    • redirect both stdin and stderr to /dev/null
      • CMD 1> /dev/null 2> /dev/null
    • Enhancement 1: You can replace 1> with just >. This is because 1 is the default stdout and you can ignore mentioning defaults.
      • CMD > /dev/null 2> /dev/null
    • Enhancement 2: You can replace the 2nd file redirect (> /dev/null) with a file descriptor duplication (>& 1). This is because /dev/null is already pointed to by stdout 1.
      • CMD > /dev/null 2>& 1
    • Enhancement 3: This is such a common operation, that many shells have a shortened form of this as a single &> operator.
      • CMD &> /dev/null

pipeline

  • |
    • command1 | command2
    • 将command1的stdout跟command2的stdin 通过管道(pipe)连接起来
  • |&
    • command1 |& command2
    • 将command1 stdout 和 stderr 都跟command2的和stdin连接起来
    • command1 2>&1 | command2 的简写方式

数组操作

  • 定义数组
    • declare -a array
  • 元素赋值
    • array[0] = 1000
  • 取值
    • ${array[0]}
    • ${array[*]} (get all)
    • ${#array[*]} (数组长度)
  • 定义一个关键数组
    • declare -A array

扩展

大括号扩展

$ {a,b,c,d}{1,2,3,4}
a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4

$ {a,c}.conf
a.conf c.conf

变量扩展

  • :- A or 1000

    • ${aaa:-1000}
  • := A or A=1000

    • ${aaa:=1000}
  • Slice

    • ${aaa:10:5}
      • aaa[10:15],[start:length]
    • ${aaa:10}
      • aaa[10:]
    • ${aaa: -5}
      • aaa[:-5] 注意负号 前面的空格
    • ${#aaa}
      • 变量值的长度
    • ${aaa#pattern}
      • remove pattern
      • 从左往右, 从头match 到第一个 ^pattern,删除pattern,取其后面的字串
    • ${aaa##pattern}
      • greedy version
      • keey base path
        $ aaa="/Volumes/WORK/WORK/test"
        $ echo ${aaa##*/}
        test
      • get file extension
        ${aaa##*.}
    • ${aaa%pattern}
      • also remove pattern, except it apply to the back of variable.
        $ FILE="xcache-1.3.0.tar.gz"
        $ echo "${FILE%.tar.gz}"
        xcache-1.3.0
      • remove file extension
        ${aaa%.*}
    • ${aaa%%pattern}
      • greedy version
  • 字符串替换

    • ${aaa/pattern/string}
      • pattern匹配到的第一个字符串替换成string
    • ${aaa//pattern/string}
      • 全局替换
  • 算数扩展

    • ((...))
      $ a=1
      $ ((a++))
      $ echo $a
      2
    • 支持 整数运算/位运算/关系运算/三元运算
    • 内建命令let
      • let i=i**2
      • (()) 的另一种写法

Bash Commands Notes

sort / uniq

  • uniq : report or filter out repeated lines
  • uniq 多 伴随着 sort 命令同时出现, 因为 uniq 只能去掉 相邻的重复line
  • 虽然 sort -u 自己就可以去掉重复, 但 uniq 有这更多的功能
  • uniq -c 打印重复的次数
    5 chocolate
    4 mint
    1 ranbow
    2 rocky
  • uniq -d
    • display only repeated lines
    chocolate
    mint
    rocky
  • uniq -u
    • display non-dup lines
    ranbow
  • combo...
    $ sort favFlavors.txt | uniq -c | sort -nr
    5 chocolate
    4 mint
    2 rocky
    1 ranbow

expansion

$ ls *.{json,py}
$ echo Day{1..7}
Day1 Day2 Day3 Day4 Day5 Day6 Day7

du (disk usage)

disk usage

su (switch user)

$ su testuser

To simulate a full login

$ su -[l] testuser

permission

$ ls -l
drwxr-xr-x  5  mebusy  staff   160 Aug  1  2022 go

drwxr-xr-x

  • the 1st character could be
    1. d : a directory
    2. - : a file
    3. l : a symbolic link
  • the following 9 characters are rwx permssions for owner, group, others (any user)

chmod

syntax:

chmod mode file
  • who
    • u : user
    • g : group
    • o : others
    • a : all
  • what
    • - : remove permission
    • + : grants permission
    • = : set a permission and remove others
  • which
    • r : read permission
    • w : write permission
    • x : execute permission

examples:

  • add write permission to group
    chmod g+w file.txt
  • remove write permission from all
    chmod a-w file.txt
    # or
    chmod -w file.txt
  • prevent others to access this file
    chmod o-rwx file.txt