shell 学习

来源:互联网 发布:有趣的app软件 编辑:程序博客网 时间:2024/06/05 19:04
Shell 特性:
     history 保存在 ~/.bash_hostory,保留1000条:定义在
          echo $HISTSIZE
     !!: 上一条命令
     !$: 上一条命令的最后一个参数
     !950: 第950条命令
     !c: 历史中最近的以 c 开头的命令
     tab: 命令补全
     alias: 别名   unalias 
     *,?: 通配符  正则表达式
     |: 管道符
     >,>>: 重定向跟追加,开启 noclobber 之后,覆盖需要 >|
     -<<delimiter 以 delimiter 为分隔符,将 两个 delimiter 之间的输入,输出到指定地方
     2>: 错误重定向   2&1>: 整齐跟错误重定向
     set -C : 开启 -C 选项,防止重定向时覆盖文件
     set -u : u 指的是 nounset ,表示 当使用未定义变量时,输出错误信息,并强制退出
     set -r : 启动 shell 的限制模式,限制模式下,有一些命令不能使用。例如:cd , 改变一些重要的环境变量 PATH SHELL 等,输出重定向。。。
     set -b : 启动 norify 选项,就是在 后台运行的进程结束之后自动提示。
     sleep,fg,bg,jobs: fg后面加个数字ID
     shift : 左移一位数组
     getopts "ab:" option : 查看 变量中 以 - 开头的选项,是否在 a,b 中,若是,则 $option 就为此值,否则值为 ?
     
Shell 变量:
     env: 查看系统变量
     set: 系统跟自定义变量
     变量中带有特殊字符,需要用单引号 : b='ls /tmp'
     变量中引用命令,用反引号 : myvim=`which vim`
     变量之间的连接,用双引号 : c="$a"12
     export : 变量全局声明
     local : 变量局部定义
     unset d : 删除一个变量的值

     ${color:=blue} : 如果 color 没有赋值,则调用之后 color 的值为 blue
     ${color:-blue} : 如果 color 没有赋值,则调用之后 color 的值为 undef
     ${color:?blue} ${color?blue} : 测试变量 color 是否被赋值,若没有被赋值则报错
     readonly color : 设置 color 为只读,赋值就报错  扩展:declare 和 typeset
          declare -r : 设置为只读;declare -i :设置为整型数;declare -a : 定义为数组;declare -x : 定义为环境变量,相当于 export ; 

     间接变量引用:eval tempvar=\$$variable1 ; tempvar = ${ !variable1 }
Shell 环境变量:
    系统级别:
     /etc/profile : /etc/profile.d/*.sh
     /etc/bashrc :
          1) /etc/profile.d/*.sh
          2) PS1='[\u@\h-\t \w(W)]\$ '
          3) umask 修改
               umask.sh : umask 0012
      用户级别:
     .bash_history : 记录历史命令
     .bash_logout : 退出的时候所做的事
     .bash_profile : 用户自己环境变量配置文件
     .bashrc : root用户用到的别名
     
     去除当前环境变量 unset APPSPATH
     设置环境变量 export APPSPATH=....
     了解的环境变量: PWD(当前工作目录) , OLDPWD(旧工作目录) , PATH , HOME(当前用户家目录) , SHELL(当前shell) , USER(当前用户 ) , UID(当前用户 ID) , PPID(父进程 ID) , PS1(一级提示符) , PS2(二级提示符) , IFS(域分隔符)


Shell 基本用法之 cut :
     cat /etc/passwd | cut -d ':' -f 1 | head -n5  (以:分割的第一段数据的前5条)
     head -n2 /etc/passwd | cut -c2  (截取第二个字符)
     head -n2 /etc/passwd | cut -c1-5   (截取第1-5个字符)

Shell 基本用法之 paste:
     paste [option] 文件1 文件2
     paste -d@ file1 file2 : -d 为设置新的分隔域,默认是空格和tab键
     paste -d: -s file1 file2 : 将每个文件粘贴成一行
     ls | paste -d"" - - - - - : 将 ls 的结果按照每行 5 个文件排列显示

Shell 基本用法之 sort :
     head -n5 /etc/passwd | sort : 升序
     head -n5 /etc/passwd | sort -t: -k3 -n : 使用纯数字以第三个字段来排序
     head -n5 /etc/passwd | sort -t: -k3,5 -r : 从第三到第五字段之间的字符串进行反向排序
     cut -d : -f1 /etc/passwd | sort -n -u : -nu 会把字符串都看成0 ,并且去重
    
Shell 基本用法之 wc:
     wc -l 1.txt 2.txt : 列出有几行
     wc -w (word)   : 输出以空格为分割的多少个字
     echo "12345" | wc -m : 输出多少字符

Shell 基本用法之 uniq 和 tee:
     uniq +文件 : 去重,但是 uniq 只对连续的相同行进行判断
     sort +文件 | uniq -c : -c是可以计算重复的行数
     uniq -d 只显示有重复的记录,其中每个重复记录只显示一次,uniq -u 只显示没有重复的记录
    
     echo "1213" | tee +文件 : 重定向并且把结果显示在屏幕上
     tee -a +文件: a 指的是追加,append
      
Shell 基本用法之 join:
     join [option] 文件1 文件2 :针对的是两个已经排序过的文件进行内容合并
     join -t : 文件1 文件2;join -i 比较域的时候,忽略大小写
     join -a : 显示共同域连接的结果;-v : 不显示连接的结果
     join -o1.1 2.2 1.2 : 改变显示的格式为,第一个文件的第一个域,第二个文件的第二个域,第一个文件的第二个域  这三个域

Shell 基本用法之 tr和 split:
     head -n2 /etc/passwd | tr '[a-z]' '[A-Z]' : 把小写转化为大写
     -d : 删除某个字符; -s : 去除重复的字符
     tr -d A-Z <file ; tr -d 0-9 <file; tr -d "[\n]" <file
     tr -s "[\n]" <file ; tr -s "[\012]" <file
     
     split -b500 passwd : 将文件以500bytes 为一个文件分割,默认不指定目标文件,则会产生xaa,xab,xac... 文件来显示
     split -l 10 +文件: 将文件以10行为单位来进行分割
     split -b 500 + 文件 123: 指定目标文件名,则会以123aa,123ab,123ac...来显示
     
Shell 基本用法之 grep :  grep [option] "匹配内容" 输入文件
     grep :
          1) . -c : 打印符合要求的行数
          2) . -n : 输出行号
          3) . --color : 显示颜色
          4) . -v : 打印不符合要求的行
          5) . -A+数字 : 显示符合要求的行以及下面n行
          6) . -B+数字 : 显示符合要求的行以及上面n行
          7) . -C+数字 : 显示符合要求的行以及上下各n行
          8) . -rh : 访问目录 grep -rh "iptables" /etc/*
          9) . --include : 包含某个文件
                    把一个目录下,过滤所有*.php 文档中含有eval 的行
                    grep -r --include="*.php" 'eval' /data/
     egrep = grep -E

Shell 基本用法之 sed :  sed 内容定位行  "sed 命令" 输入文件
     sed '10'p -n 1.txt : 加上-n 打印出符合规则的行
     sed -n '/root/'p 1.txt : 打印包含特殊字符的行
     -r : sed 不能识别 +| {} () 等符号,需要脱义字符\或者-r 
          sed -n -r '/ro+/'p 1.txt
          sed -n '/ro\+/'p 1.txt
     -e : 实现多个任务,也可以用 ; 来实现
          sed -e '/root/p' -e '/body/p' -n 1.txt
     d : 删除指定行
          sed '/root/d' 1.txt ; sed '1d' 1.txt ; sed '1,10d' 1.txt
     s : 替换
          sed '1,2s/ot/to/g' 1.txt
     替换两个字符串的位置,其中\3\2\1分别代表三个()的内容
          head -n2 1.txt | sed -r 's/(root)(.*)(bash)/\3\2\1/'
     a:指定行后面添加
          sed '2,4a abcd' xx.txt 在2到4行添加 abcd
     -i : 直接修改文件
          sed -i 's/ot/to/g' 1.txt

Shell 基本用法之 awk:  awk -F : '/pattern/ {print}' 输入文件  |  awk 'BEGIN {FS=","}{print} {END }' 输入文件
     1. awk -F ':' '{print $1}' 1.txt
     2. awk -F ':' '{OFS="#"} {print $1,$2,$3,$4}' 1.txt 就是 
               awk -F ':' '{print $1#$2#$3#$4}' 1.txt
     3. awk '/oo/' 1.txt  : 匹配oo
     4. awk -F ':' '$1 ~/oo/' 1.txt  : 在第一段匹配oo
     5. 条件操作符 ==,>,<,!=,>=,<=
          第三段为0 : awk -F ':' '$3=="0"' 1.txt
          第三段大于等于500 : awk -F ':' '$3>=500' 1.txt
          第七段不是'/sbin/nologin' : awk -F ':' '$7!="/sbin/nologin"' 1.txt
          
     6. awk 内置变量NF (段数) NR (行数)
          head -n3 1.txt | awk -F ':' '{print NF}'
     7. 数学计算:
          awk -F ':' '{OFS=":"}{$7=$3+$4; print $0}' 1.txt
     8. awk -F ':' '{(tot=tot+$3)}; END {print tot}' 1.txt
     9. awk -F ':' '{if ($1=="root") print $0}' 1.txt

shell 结合 awk 进行输出
for i in `seq 1 5`
do
cat 1.txt | awk -F ':' '{print "'"$i"'"}' | awk '{print $i}'
done

前一个  $i 被 “‘”  跟 “’” 包含,之后一个 $i 可以直接被识别
Shell 基本语法:
1) #!/bin/bash 指定用bash 来运行
2) if 语句
     if condition ; then
          command
     fi
     
     if condition ; then
          command
     else
          command
     fi

     
     if condition ; then
          command
     elif condition; then
          command
     else
          command
     fi
 [ 条件 ] 
     -d : 是否为目录
     -f :  是否为普通文件
     -l :  是否为连接文件
     -e : 是否存在
     -n : 是否不为0
     -z : 是否为0
     -r (-w -x):是否有权限
     
3) for , while , until , select
    for
     for i in `seq 1 5` do
          echo $i
     done

     for file in $( * )  显示当前目录下所有文件
     for arg in "$*"  显示传递的参数
     for (( i = 1; i <= 5; i++ )) 类C风格 for 循环
     
    while
     while condition; do
          command
     done

: 的用法:
1)、
     死循环:
     while : do   (: 为永真)
          command
          sleep 3
     done
2)、
    清空一个文件: 1.>file ; 2. :>file
3)、
     : $var : 其中 : 与变量 $ 之间有空格,此处 : 的作用就是展开参数,变量替换,让Shell 不会去执行 $var 变量的值

     continue; break; exit;

     while [[ $signal -eq 3 ]]  ; while (( signal == 3 ))

    until
     until expression
     do
          command
     done
     
    select
     select color in "red" "blue"
     do
          break
     done
     自动生成菜单,其中 $? 为 PS3 的默认值

4) date 命令
     1) 2015-08-25 : date +%Y-%m-%d
     2) 15-08-25 : date +%y-%m-%d
     3) date +%F
     4) 21:45:15 : date +%H:%M:%S
     5) 21:45:15 : date +%T
     6) 时间戳 : date +%s
     7) date -d @1440510413
     8) 一天后 : date -d "+1day"
     9) 一天前 : date -d "-1day"
     10) 一月前 : date -d "-1month"
     11) 一分钟前 : date -d "-1min"
     12) 星期 : date +%w(%W) 小写表示周几,大写表示本年的第几周

5) 数学运算
     sum = $[$a+$b] (+-*/)
     小数:echo "scale=2;10/3" | bc    输出3.33

     数字进制表示:0123 , 8#123 ; 0x123 , 16#123
  
     expr 命令:expr arg1 | arg2 (逻辑运算); expr arg1 + arg2 (算术运算)
     
     bc 运算:echo "scale=5; $var1 ^ 2 " | bc 其中 scale 指的是小数位数

6)字符串
     计算字符串的长度: ${#string} ; expr length "$string"   其中 $string 的值中没有空格,就可以省略 ""
     获取字符串的索引:expr index "$string" job 如果 job 都在字符串 string 中,返回 j 的位置索引;如果 job 中只有一个字母在字符串 string 中,就返回那个字母所在的索引位置;如果 o 对应的索引位置在 j 的前面,就返回 o 对应的位置索引
     匹配字符串最长长度:expr match "$string" "$substring" 指的是从 string 字符串的开头处开始匹配 substring ,获取到最大匹配长度,如果没有匹配到,就返回 0 ,例子: expr match "$string" small 
     抽取字符串的子串:
          从左往右 :#{ string:position } ; #{ string:position:length } 从 0 开始计数; expr substr "$string" 1 8 从 1 开始计数
          从右往左:#{ string: -position } ; #{ string:-position } ; #{ string:(position) } 其中第一种 : 与 - 之间有空格表示的跟第三种一样,从右往左 position 个字符,第二种没有空格表示 抽取整个字符串
          用正则表达式抽取:
               抽取开头:expr match "$string" '\($substring\)' ; expr "$string" : '\($substring\)' 其中后者冒号前后都有空格
               抽取结尾:expr match "$string" '.*\($substring\)' ; expr "$string" : '.*\($substring\)' 其中后者冒号前后都有空格
     删除字符串子串:
          删除开头:${ string#substring } 删除 string 开头匹配 substring 的最短子串; ${ string##substring } 删除 string 开头匹配 substring 的最长子串
          删除结尾:${ string%substring } 删除 string 结尾匹配 substring 的最短子串; ${ string%%substring } 删除 string 结尾匹配 substring 的最长子串
     替换字符串子串:${ string/substring/replacement } 替换第一次匹配 substring 的子串 ; ${ string//substring/replacement } 替换所有匹配 substring 的子串
          替换开头:${ string/#substring/replacement } 替换开头处匹配 substring 的子串 ; ${ string/%substring/replacement } 替换结尾处匹配 substring 的子串

7) 交互
     read -p "Please input a number :" x

8) sh -x xx.sh查看执行过程

9)  case 语法
     case 变量 in 
     value1)
          command
          ;;
     value2)
          command
          ;;
     *)
          command
          ;;
     esac

10) Shell 数组
     a=(1,2,3,4)
     数组元素个数:echo ${#a[@]}
     读取单个元素:echo ${a[2]}
     打印整个数组:echo ${a[@]}  或者 echo ${a[*]}
     删除数组:unset a    unset a[1]
     数组分片:echo ${a[@]:0:3} 从下表0往后3个
     数组替换:echo ${a[@]/3/100} 将数组第三个换成100
11) 父子进程
     () 会产生一个子进程,() 中的变量不能被父进程使用,即使在 子进程中 用 export 命令将变量改为 环境变量
     () 中的子进程还可以进行后台运行, 这样可以一次性运行多个子进程 ,例子:一次搜索多个目录,排序,最后重定向到一个文件 ( grep -r "root" /etc/* | sort > part1 ) &
     子进程允许嵌套
     多个进程组合成一个作业,控制作业的命令: fg , bg , jobs (查看作业), disdown (删除作业表中的作业) , wait (等待后台进程结束之后,退出主进程) , kill
     fg : 
     %n          n 为后台作业的作业号
     %string   命令以 string 字符串开始的后台作业
     %?string  命令包含 string 字符串的后台作业
     %+ 或 %% 最近提交的后台作业
     %-          最近第二个提交的后台作业 
12) 信号
     kill -l : 列出所有的信号(64 种,其中 15 种为 SIGTERM)
     trap "echo ..." INT (接受 INT 也就是 CTL + C 中断信号):此处为接受到中断信号就打印 ,如果不做任何处理 , 即:trap "" INT TERM (对 INT 和 TERM 信号忽略)
13) 特殊
     echo -e "\033[44;37;5m Hello \033[0m World" 其中 \033 引导非常规字符序列;m 设置属性,然后结束非常规字符序列。数字为颜色搭配
     \033[2J          清除屏幕
     \033[0q          关闭所欲的键盘指示灯
     \033[1q          设置“滚动锁定”指示灯 ( Scroll Lock )
     \033[2q          设置“数值锁定”指示灯(Num Lock)
     \033[3q          设置“大写锁定”指示灯(Caps Lock)
     \033[10:15H     把关闭移动到第10行,15列
     \007               发蜂鸣声 beep
14) Linux 脚本安全
     使用shc 加密脚本
     下载 shc-3.8.6.tgz
     tar zxf shc-3.8.6.tgz
     cd shc-3.8.6
     make test
     make strings
     make install

     shc 使用:shc -v -f filename
     生成 .x 跟 .c 结尾的文件,其中 .x 是可执行文件,.c 是 C 语言文件

     关于Linux 病毒的相关知识,可以参考 http://wenku.baidu.com/link?url=kCvHvdRtVUpI5V0OXh3NLmNWHm4jgMJ5bpgkEr5WPgkfiU6jYOw1hq7aXMHRf5FcKfoHlFSiwxhmCuHOnZbNWblq9uflKDeIJXE8pNYsGX7
15) shell 脚本调试
     trap 命令:
     trap 'echo "a=$a,b=$b,c=$c"' DEBUG  在执行该脚本的时候每执行一行都会输出 a,b,c 的值
     trap 'echo "$var"' EXIT  在退出脚本的时候会输出 var 变量的值
     trap 'echo ....' ERR 在脚本出错的时候会 echo 一些东西
     
     set -n 或者 set -o noexec 脚本中添加这个可以测试脚本的语法错误,或者直接  sh -n 脚本名
     set -x ; sh -x 脚本名 逐步进行 shell 脚本运行
     脚本内置变量: LINENO 表示脚本的行号 ;FUNCNAME 数组变量,表示整个调用链上所有的函数名; PS4 设置 -x 选项的提示符,默认值是 "+" 符号
16) 实例
     1. Here-document 运用
     cat << CLOUD
     ....
     CLOUD
     在两个 CLOUD 中间可以随意输入

     mysql -u root -p <<EOF
     sql 语句
     EOF

     2.查找文本中 n 个出现频率最高的单词
     cat file | tr -cs "[a-z][A-Z]" "[\012*]" |    #其中 -c 为 保留以第一个字符集匹配的词,[\012] 指的是 换行,添上 * 的意思就是多个换行都去掉(-s)
     tr A-Z a-z |                                            #大写转化为小写
     sort |                                                     #排序   
     uniq -c |                                                #统计每个单词出现的次数
     sort -k1nr -k2 |                                     #按出现频率排序,再按字母顺序排序
     head -n "$send"                                    #显示前 n 行
     
     3.伪随机数
     num=$RANDOM
     let "dice=RANDOM % 10"
     num2=$(($RANDOM%10))
     num3=$[$RANDOM%10]
0 0