添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Zsh/Bash startup files loading order (.bashrc, .zshrc etc.)

+----------------|-----------|-----------|------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------|-----------|-----------|------+
|/etc/profile    |   A       |           |      |
+----------------|-----------|-----------|------+
|/etc/bash.bashrc|           |    A      |      |
+----------------|-----------|-----------|------+
|~/.bashrc       |           |    B      |      |
+----------------|-----------|-----------|------+
|~/.bash_profile |   B1      |           |      |
+----------------|-----------|-----------|------+
|~/.bash_login   |   B2      |           |      |
+----------------|-----------|-----------|------+
|~/.profile      |   B3      |           |      |
+----------------|-----------|-----------|------+
|BASH_ENV        |           |           |  A   |
+----------------|-----------|-----------|------+
|                |           |           |      |
+----------------|-----------|-----------|------+
|                |           |           |      |
+----------------|-----------|-----------|------+
|~/.bash_logout  |    C      |           |      |
+----------------|-----------|-----------|------+

对于 zsh

+----------------|-----------|-----------|------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------|-----------|-----------|------+
|/etc/zshenv     |    A      |    A      |  A   |
+----------------|-----------|-----------|------+
|~/.zshenv       |    B      |    B      |  B   |
+----------------|-----------|-----------|------+
|/etc/zprofile   |    C      |           |      |
+----------------|-----------|-----------|------+
|~/.zprofile     |    D      |           |      |
+----------------|-----------|-----------|------+
|/etc/zshrc      |    E      |    C      |      |
+----------------|-----------|-----------|------+
|~/.zshrc        |    F      |    D      |      |
+----------------|-----------|-----------|------+
|/etc/zlogin     |    G      |           |      |
+----------------|-----------|-----------|------+
|~/.zlogin       |    H      |           |      |
+----------------|-----------|-----------|------+
|                |           |           |      |
+----------------|-----------|-----------|------+
|                |           |           |      |
+----------------|-----------|-----------|------+
|~/.zlogout      |    I      |           |      |
+----------------|-----------|-----------|------+
|/etc/zlogout    |    J      |           |      |
+----------------|-----------|-----------|------+

用分号或换行符. 即:

cmd1; cmd2

# 符号及之后的行内容都是注释

  • 双引号的字符串则会进行变量替换
  • 单引号的字符串则不会进行变量替换
  • 默认情况下, 会自动添加换行
  • -n 参数: 忽略结尾的换行 -e 参数: 表示包含转义序列

  • 30 黑色
  • 31 红色
  • 37 白色
    echo "\e[1;31m Hello World\e[0m"
    
  • 40 黑色
  • 41 红色
  • 47 白色

    echo "\e[1;42m Hello World\e[0m"
    

    printf

    与 C 语言中的 printf 函数参数一样.

  • 默认情况下, 不会自动添加换行
  • 在 Bash 中, 每一个变量的值都是字符串, 无论你给变量赋值时有没有使用引号, 值都会以字符串的形式存储.

    有一些特殊的变量会被Shell环境和操作系统用来存储一些特别的值, 这类变量就称为 环境变量

    终端环境变量

    使用 env 命令查看.

    进行的环境变量

    cat /proc/$PID/environ
    

    上面返回的是变量的列表, 以 name=value 的形式来描述. 之间由 \0 分隔. 可将 \0 替换为 \n 就可使每一行显示了.

    cat /proc/$PID/environ | tr '\0' '\n'
    
    var=value
    

    注意, 它不同于

    var = value
    

    前者才是赋值, 后者是相等操作.

    引用变量的值

    ${var}

    注意, 如果包含在单引号里, 变量不会被扩展. 将依照原样显示.

    获取变量的长度

    length=${#var}
    

    获取当前的SHELL

    echo $0
    echo $SHELL
    

    检查是否 root 用户

    if [ $UID -ne 0 ]; then
    	echo "Non root user"
    	echo "root user"
    

    修改提示符字符串

    在文件 ~/.bashrc 中的某一行的 PS1 变量中设置的.

    Bash 中进行数学运算

    使用let时, 变量名之前不需要添加 $ , 例如:

    no1=4
    no2=5
    let result=no1+no2
    echo $result
    

    自加和自减,缩写

    let no1++
    let no1--
    let no1+=6
    let no1-=6
    

    使用 []

    result=$[ no1 + no2 ]
    result=$[ $no1 + 5 ]
    

    使用 (())

    这种变量名之前要加上 $

    result=$(( no1 + 50 ))
    

    使用 expr

    result=`expr 3 + 4`
    result=$(expr $no1 + 5)
    

    浮点运算 bc

    echo "4 * 0.45" | bc
    
    echo "scale=2; 3/8" | bc
    
    echo "obase=2; 1000" | bc
    

    obase : 输出进制 ibase : 输入进制

    文件描述符

    文件描述符是一种用于访问文件的抽象指示器. 存取文件离不开被称为 文件描述符 的特殊数字.

    0 : 标准输入 stdin /dev/stdin
    1 : 标准输出 stdout /dev/stdout
    2 : 标准错误 stderr /dev/stderr
    

    自定义文件描述符

    文件打开模式通常有3种

    < : 从文件中读取内容到 stdin
    > : 用于截断模式写入
    >> : 用于追加模式写入
    

    创建一个文件描述符进行读取:

    exec 3<input.txt
    

    这表示使用文件描述符3打开并读取文件.

    使用文件描述符

    cat <&3
    

    注意, 只能读取一次, 若要再次读取, 则要重新使用 exec 来分配文件描述符进行二次读取.

    exec 4>output.txt echo "ehllo" >&4
    exec 5>>output.txt
    echo "hello" >&5
    

    注意, 是使用 >&5

    > : 旧内容会被清空, 然后设置为新的内容. 这等同于 1>
    >> : 追加到旧内容尾部. 这等同于 1>>
    < : 用于从文件中读取内容到 stdin
    

    stderrstdout 分别重定向到一个文件:

    cmd 2>stderr.txt 1>stdout.txt
    

    stderrstdout 一起重定向:

    cmd 2>&1 output.txt
    

    忽略错误输出:

    cmd 2>/dev/null 1>output.txt
    

    同时重定向到文件和 stdout

    command | tee FILE2 FILE2
    

    注意, tee 只能读取 stdout 而不包括 stderr

    使用 stdin 作为命令行参数:

    cmd 1 | cmd2 | cmd3 -
    

    - 作为命令的文件名参数即可.

    多行文件重定向

    cat << EOF > log.txt
    这里是内容
    

    理解: stackoverflow.com

    这表示, 指示 shell 直接从当前源中读取输入, 直到有一行的内容仅包含 EOF 这个单词.

    命令的成功与否

    echo $?
    

    如果返回0, 表示上一个命令执行成功, 否则是失败.

    起始索引为0.

    array_var=(1 2 3 4 5 6)
    
    echo ${array_var[0]}
    

    打印数组所有值

    echo ${array_var[*]}
    echo ${array_var[@]}
    
    echo ${#array_var[*]}
    
    declare -A ass_array
    ass_array=([key1]=value [key2]=value2)
    ass_array[key1]=value1
    ass_array[key2]=value2
    
    echo ${ass_array[key]}
    

    列出数组索引

    echo ${! ass_array[*]}
    echo ${! ass_array[@]}
    
    alias new_command='command sequence'
    

    永久保存: 将内容写到 ~/.bashrc

    alias new_command=
    unalias new_command
    

    日期和时间

    纪元时或 Unix 时间: UTC 1970年1月1日 0时0分0秒起所流逝的秒数.

    打印纪元时

    date +%s
    

    从指定时间转换为纪元

    date --date "Thu Nov 18 08:07:21 IST 2010" +%s
    

    --date 用于提供日期字符串作为输入.

    获取星期几

    date --date "Jan 20 2001" +%A
    

    格式化日期

    格式化占位符列表

    date "+%d %B %Y"
    

    设置日期和时间

    date -s "格式化的日期字符串"
    
    bash -x script.sh
    

    在脚本内部, 进行部分调试

    set -x
    要调试的代码段
    set +x
    

    -x : 执行时显示命令和参数 +x : 禁止调试 -v : 当命令进行读取时显示输入 +v : 禁止打印输入

    function fname() {
    	statements;
    fname() {
    	statements;
    
    fname;
    fname arg1 arg2;
    
    function fname(){
    	echo $1,  $2 # 访问参数1, 参数2
        echo "$@" # 以列表的方式一次性打印所有参数
        echo "$*"; # 类似 $@, 但是参数被作为单个实体
        return 0; # 返回值
    
  • $1 是第一个参数
  • $2 是第二个参数
  • $n 是第n个参数
  • $@ 被扩展为”$1” “$2” “$3” 等
  • $* 被扩展成 “$1c$2c$3”, 其中c是IFS的第一个字符
  • $@ 用的比 $* 多, 因为 $* 将所有参数当作单个字符串, 因此它很少被使用
  • bash 支持递归调用

    函数也可以像环境变量一样用 export 导出, 如此一来, 函数的作用域就可以扩展到子进程中. 例如

    export -f fname
    

    读取命令返回值(状态)

    echo $?

    $? 会给出命令 cmd 的返回值. 这个返回值被称为退出状态.

    命令输出读入到变量

    # 这种方法称为子shell
    cmd_output=$(COMMANDS)
    # 这种方法称为 反引用
    cmd_output=`COMMANDS`
    

    子shell

    (cd /bin ; ls);

    第二行中的语句即为子shell, 它不会对当前shell有任何影响.所有改变仅限于子shell内.

    保留空格和换行

    利用子shell或反引用的方法将命令的输出读入到一个变量中, 可以将它放在双引号中, 即可保留空格和换行符.

    out=$(cat file.txt)
    out1="$(cat file.txt)"
    

    注, 像好这个没有效果. 我在 Ubuntu 16.04.2 LTS , GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu) 版本中测试没有效果. 有待处理.

    read 命令

    读取 N 个字符到变量

    read -n N var_name
    

    用无回显的方式读取密码

    read -s var
    

    显示提示信息

    read -p "enter input:" var
    

    在特定时限内读取

    read -t timeout var
    

    用特定的定界符作为输入行的结束

    read -d delim_char var
    

    true 的命令

    它是内建命令, 总是会返回为0的退出码.

    字段分隔符 IFS

    IFS 是存储定界符的环境变量, 它是当前 shell 环境使用的默认定界字符串.

    它的值, 默认为 空白字符

    #!/bin/bash
    data="1,2,3,4,5"
    oldIFS=$IFS
    IFS=,
    for item in $data;
      echo Item: $item
    IFS=$oldIFS
    
    ./hello.sh
    Item: 1
    Item: 2
    Item: 3
    Item: 4
    Item: 5
    

    for 循环

    for var in list;
    	commands;
    

    list 可以是字符串, 也可以是一个序列.

    {1..50}
    

    表示从1到50的数字列表.

    {a..z}
    

    for 的 c 风格

    for ((i=0;i<10;i+)) {
    	commands;
    

    while 循环

    while condition
    	commands;
    

    until 循环

    until condition;
    	commands;
    if condition;
    	commands;
    

    if .. elif .. else

    if condition;
    	commands;
    elif condition; then
    	commands;
    	commands;
    
    [ $var -eq 0 ]
    

    注意, 中括号与操作数之间要有空白.

  • -gt : 大于
  • -lt : 小于
  • -ge : 大于等于
  • -le : 小于等于
  • [ $var -ne 0 -a $var2 -gt 2 ] # 表示逻辑与, -a
    [ $var -ne 0 -o $var2 -gt 2 ] # 表示逻辑或, -o
    

    文件系统测试

    [ -f $file_var ] # 如果是正常的文件路或文件名
    [ -x $var ] # 如果给定的变量包含的文件可执行, 则返回真
    [ -d $var ] # 如果是目录
    [ -e $var ] # 如果文件存在
    [ -c $var ] # 如果是字符设备
    [ -b $var ] # 如果是块设备
    [ -w $var ] # 如果文件可写
    [ -r $var ] # 如果文件可读
    [ -L $var ] # 如果是符号链接
    

    字符串比较

    最好使用双中括号

    [[ $str1 = $str2 ]] # 如果相等
    [[ $str1 == $str2 ]] # 如果相等
    [[ $str1 != $str2 ]] # 如果不相等
    [[ $str > $str2 ]] # 大于
    [[ $str < $str2 ]] # 小于
    [[ -z $str1 ]] # 如果是空字符串
    [[ -n $str1 ]] # 如果是非空字符串
    
    [[ -n $str1 ]] && [[ -z $str2 ]]
    

    test 命令

    if [ $var -eq 0 ]; then
    	echo "True";
    

    与可以写为

    if test $var -eq 0; then
    	echo "True";
    
  • -s : 压缩多行空行为一行空行
  • -T : 显示制表符
  • -n : 显示行号
  • -b : 显示行号, 但不为空白行设置行号
  • find 命令

    find base_path -print0
    
  • -print0 表示以 ‘\0’ 作为文件名的界定符. 默认为换行符, 但当文件名包含换行符时, 这就有用了. 注意, 是连起来的 -print0
  • -name “*.txt” 正则匹配.
  • -iname “*.txt” 忽略大小写
  • find . \( -name "*.txt" -o -name "*.pdf" \) -print
    
    find . ! -name "*.txt" -print
    

    表示匹配所有不以 *.txt 结尾的文件名.

    基于目录深度

    默认情况下, find 会遍历所有子目录.可以添加选项来限定深度.

  • -maxdepth
  • -mindepth
  • 这两个参数应该是 find 的第三个参数, 否则可能会影响效率.

    根据文件类型搜索

  • -type d 目录类型
  • -type f 文件类型
  • -type l 符号链接类型
  • -type c 字符设备
  • -type b 块设备
  • -type s 套接字
  • -atime : 用户最近一次访问时间
  • -mtime : 文件内容最后一次修改时间
  • -ctime : 文件元数据最后一次改变的时间
  • 后接 +N 或 -N 单位是天. 负号表示是小于, 正号表示大于

  • -amin : 访问时间
  • -mmin : 修改时间
  • -cmin : 变化时间
  • 这些同上, 只是时间单位为分.

  • -size +2K : 表示大于 2KB 的文件
  • -size -2K : 表示小于 2KB 的文件
  • b : 512 字节
  • c : 字节
  • w : 2字
  • k : 1024 字节
  • M : 1024 K 字节
  • G : 1024 M 字节
  • -delete
  • -perm 664
  • -exec

    find . -type f -exec cat {} \;> outout.txt
    

    exec 不支持执行多命令, 但可以变换一个, 将命令写入脚本, 然后调用

    -exec ./commands.sh {} \;
    

    tr 命令

    tr [options] set1 set2
    
    tr -d '[set1]'
    
    tr -s ' '
    

    将多个空白压缩为一个.

    md5sum filename
    sh1sum filename
    

    crypt

    它是一个简单的加密工具, 从 stdin 接受一个文件以及口令作为输入, 然后将加密数据输出到 stdout

    crypt < input_file > output_file
    
    crypt -d < encrypted_file > output_file
    
    gpg -c filename
    
    gpg filename.gpg
    

    base64

    base64 filename > outputfile
    
    base64 -d file > outputfile
    
    filename=`mktemp`
    dirname=`mktemp -d`
    

    仅生成文件名, 而不是实际的文件

    tempfile=`mktemp -u`
    

    根据模板创建

    mktemp test.XXX
    

    它会生成 test.XXX 形式的临时文件.

    提取文件名和扩展名

    file_jpg="sample.jpg"
    fileName=${file_jpg%.*}
    suffixName=${file_jpg#*.}
    

    注意, 单个 % 是非贪婪操作, 想要贪婪式的, 则使用 %% 类似的, 还有 # 是非贪婪的, 而 ## 是贪婪的.

    在循环里的命令, 使用 & 时, 它就会直接向下再执行了, 而不会等待命令执行完成.这样子就可以利用多核

    #!/bin/bash
    PIDARRAY=()
    for file in File1.iso File2.iso
    	md5sum $file &
        PIDARRAY+=("$!")
    wait ${PIDARRAY[@]}
    

    注意, 还要用 wait 来等待多进程的退出.

    dd 命令

    dd if=/dev/zero of=data.file bs=1M count1
    

    不可删除的文件

    chattr +i file
    删除的时候, 它会提示
    rm: remove write-protected regular empty file 'file'?
    

    恢复为可删除

    chattr -i file
    

    diff 与文件补丁 patch

    diff -u version1.txt version2.txt > version.patch
    

    patch 命令可将修改应用于任意文件. 当应用于 version1.txt 时, 就可以得到 version2.txt , 当应用于 version2.txt 时, 就可以得到 version1.txt

    patch -p1 version1.txt < version.patch
    patch -p1 version1.txt < version.patch
    

    递归的形式来处理目录及文件

    diff -Naur dir2 dir2
    

    快速定位目录

    pushd 压入
    popd 弹出
    dirs 查看栈的内容
    cd - 返回上一次的目录
    

    它是一个处理LIFO的数据结构. 目录被存储在栈中, 然后 push 和 pop 进行切换.

    wc 命令

    wc -l file # 统计文件 file 的行数
    wc -w file # 单词数
    wc -c file # 字符数
    wc file # 行数, 单词数, 字符数
    wc file -L # 最长一行的长度
    

    可视化正则

    | 正则   | 描述                            |
    |--------|---------------------------------|
    | ^      | 行起始标记                      |
    | $      | 行结尾标记                      |
    | .      | 任意一个字符                    |
    | []     | 在 [] 中的任意一个字符          |
    | [^]    | 在 [^] 之外的任意一个字符       |
    | [-]    | 在 [-] 指定范围内的任意一个字符 |
    | ?      | 匹配之前的项1次或0次            |
    | +      | 匹配之前的项1次或多次           |
    | *      | 匹配之前的项0次或多次           |
    | ()     | 创建一个用于匹配的子串          |
    | {n}    | 匹配之前的项n次                 |
    | {n, }  | 匹配之前项至少n次               |
    | {n, m} | 匹配之前项n到m次                |
    | \      | 转义                            |
    | 一竖     | 匹配两边任意一项                        |
    

    cut 命令

    提取指定列

    cut -f 2,3 filename
    

    这列表只显示第2,3列

    排除指定列

    cut -f3 --complement filename
    

    这表示除第3列之外的所有列.

    指定界定符

    cut -d ";" filename
    

    指定字段的字符或字节范围

    cut -c1-5 filename
    

    表示只打印前1~5个字符.

    sed 命令

    stream editor

    替换字符串

    sed 's/pattern/replace_string/' file
    

    应用到文件

    sed -i 's/pattern/replace_string/' file
    

    默认情况下, sed 将在每一行的第一处符合的内容替换. 要全部则:

    sed 's/pattern/replace_string/g' file
    

    只在第N处开始替换

    sed 's/pattern/replace_string/2g' file
    

    除了 / 还可以:

    sed 's:text:replace:g'
    sed 's|text|replace|g'
    

    移除空白行

    sed '/^$/d' file
    
    awk '{BEGIN {print "start"} pattern {commands} END {print "end"}}' file
    

    处理流程:

  • 执行 BEGIN {commands} 语句块中的语句
  • 从文件或stdin 中读取一行, 然后执行 pattern {commands} , 重复这个过程, 直接文件全部被读取完.
  • 当读至输入流末尾时, 执行 END {commands} 语句块.
  • NR : 当前行号
  • NF : 当前行的字段数
  • $0 : 当前行的内容
  • $1 : 第一个字段的内容
  • $2 : 第二个字段的内容
  • 将外部变量传递给 awk

    awk -v VAR=$OUT_VAR '{print VAR}'
    

    设置字段界定符

    awk -F: '{print $1}'
    

    这样子, 就将字符界定符设置为 : 了.

    gnu awk

    length(string) : 返回字符串的长度
    

    paste 命令:列拼接

    cat 是按行拼接的.

    paste 则是按列来拼接的.

    逆序显示. cat 的逆单词.

    命令行下载工具

    指定多个下载

    wget URL1 URL2
    

    指定输出文件

    wget URL1 -O outputfile -o logfile
    
    wget -t 5 URL1
    

    为0时, 表示无限重试.

    wget --limit-rate 20k URL
    

    最大下载配额

    wget -Q 100m URL
    

    表示最大下载 100m 大小, 超过时就会停止.

    wget -c URL
    

    复制整个网站

    wget --mirror --covert-links URL
    

  •