《linux shell 脚本编程攻略 (第2版)》 第一章 “小试牛刀” 笔记

主要命令:let, cat, 变量字符串处理, 数学计算, 管道|, 重定向, $, expr, bc, echo, $#, $*, $0, eval, tr, printf, read, tput, 循环语句, 条件语句, 分隔符IFS

  • 文本行#!/bin/bash中的#!读作 shebang (也可读做 hashbangpound-bang参考维基

  • 终端打印除了echo命令还可以用printf(语法规则同C语言类似),如printf "%s %f\n" swf 1234输出 swf 1234.000000

  • 变量替换在单引号中无效

  • 打印彩色字体echo -e "\e[1;31m This is red text \e[0m"\e[1;31m将颜色设为红色(;前的数字表示背景颜色,;后的表示字体颜色),\e[0m将颜色重新置回

  • 查询某程序运行时环境变量cat /proc/进程ID/environca (pgrep gedit查看程序gedit的PID,或使用ps aux | grep gedit查看)

  • tr将输出重新格式化 cat /proc/84354/environ | tr '\0' '\n'

  • 获取字符串长度var=wenfeng; echo ${#var}(助记:#是number sign),获取当前使用的SHELL echo $0echo $SHELL

  • ${parameter:+expression} 如果parameter有值且不为空,则使用expression的值。prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1; } (eval`可将多个参数整合成一个参数)

  • 显示/修改Bash提示字符串echo $PS1/PS1="wefeng"

  • shell数学运算

    1. let 变量名前不需要用$,如let result=no1+no2; echo $result
    2. (())result=$(( no1 + 50 ))result=$ (( $no1 + 50 ))
    3. []result=$[ no1 + no2]result=$[ $no1 + 5 ]
    4. exprresult=反引号expr 3 + 4反引号result=$(expr $no1 + 5)
    5. bc命令(支持浮点数echo "scale=2;3/8" | bc 设置小数位数为2; echo "obase=2;$no" | bc将数字转化为2进制; echo "obase=10;ibase=2;$no" | bc 将二进制转化为十进制
  • 重定向

    1. stderr转换成stdout重定向 cmd 2>&1 stdout.txt 或者 cmd &> output.txt
    2. command | tee FILE1 FILE2 接收来自stdin的数据,将副本写入FILE1和FILE2,同时也将副本左后后续命令的stdin
    3. cmd - 将stdin作为命令参数
  • 脚本内部文件块重定向此处有代码

  • 自定义文件描述符 exec 3<input.txt exec 5>>output.txt此处有代码

  • 数组array_var=(s w f), echo ${array_var[0]}打印一个元素, echo ${#array_var[*]}打印数组长度,echo ${!array_var[*]}打印出数组索引列表,echo ${array_var[*]} 打印出所有元素

  • 关联数组(相当于字典)先声明declare -A ass_array,再赋值ass_array=([index1]=val1 [index2]=val2) 或者 ass_array[index3]=val3 其他操作同上,只是索引不再是数字了

  • 当用alias设置了别名命令后,当不想用这个别名是,可对其进行转义即 \command

  • 获取当前终端行数/列数/终端名 tput lines/tput cols/tput longname; tput sc存储光标位置, tput rc恢复光标位置 tput ed清除从当前光标位置到行尾之间的所有内容 (下面实现一个计时器)此处有代码

  • 通过stty实现 输入密码时不应显示输入内容(也可直接read -s启动slient模式,但stty更通用)此处有代码

  • date +%s 打印timestamp (从1970年1月1日0点开始的秒数)即POSIX时间; date "+%d %B %Y" 按格式输出

  • 调试脚本此处有代码

    1. bash -x script.shsh -x script.sh
    2. set -xset +x(执行命令后会显示该指令及其参数);set -v当命令进行读取时显示输入,set +v进制打印输入 详细介绍
    3. 将shebang从#!/bin/bash 改成 #!/bin/bash -xv 也可(./script.sh运行)
    4. 自定义格式显示调试信息,新建如下脚本,然后命令行键入 [root@share codes]# _DEBUG=on sh debug.sh (:告诉shell不进行任何操作)
  • 函数和参数

    1. $@ 被扩展成 $1 $2 $3
    2. $* 被扩展成$1c$2c$3(c是IFS的第一个字符, IFS即internal field seprator, env | grep IFSset | grep IFS查看)
    3. $? 获取命令或函数的返回值
    4. "$@" 比 "$*" 更常用,后者会把所有参数当作单个字符串处理
    5. 递归 F() { echo $1; F hello; sleep 1; },这是 fork bomb :(){ :|:& };: (可通过修改/etc/security/limits.conf或命令ulimit来限制生成的最大进程数)维基扩展
    6. 导出函数 export -f fname 可将函数的作用域扩展到子进程中
    7. 向命令传递参数的方式command -p -v -k 1 file或者command -pv -k1 file或者command -pvk 1 file或者command file -pvk 1
  • 存储命令的输出此处有代码

    1. $( ) 通过子shell方式, 如 output=$(ls | cat -n) 子shell里面的变化如cd XX等不会反应到主shell中
    2. 反引用方式(通过反引号)
    3. 可将子shell或反引用放入以个双引号中,以保留空格和换行符(\n)
  • read -n 5 -s -t 2 -d ":" -p "Enter your password:" var 从输入中以无回显的方式读取5个字符并存入变量var中,且需要在2秒内输入,以:作为输入行的结束符,终端会有"Enter your password:"的提示

  • true作为/bin中的一个二进制文件来实现的,即表示每执行一次便会生成一个进程,若不想则可以通过内建的:命令(其总会返回0)此处有代码

  • 字段分隔符 IFS 此处有代码

  • 循环语句 for in do done, while do done, until do done 连写成一行时,do前要用;

  • 比较语句 if then fi, if then else if then else fi 连写成一行时,then前用;

    1. [ condition ] && action[ condition ] || action
    2. 算数比较 -eq, -ne, -lt, -ge, -le; [ $var1 -ne 0 -a $var2 -gt 2 ](AND条件用-a,OR条件用-o),也可分开用类似[ ] && [ ]
    3. 文件系统相关测试 -f, -d, -e, -b, -w, -r, -x, -L (用[ ])
    4. 字符串比较 [[ ]] (-z, -n , ==, !=)