Shell 学习笔记
慕课链接:https://coding.imooc.com/class/chapter/314.html
每次想直接执行脚本的时候,总存在某些地方不会写,然后查资料,就比较浪费时间
趁着复习周,给自己加餐下,找了个慕课的教程,以下就记录下自己觉得重点的内容

变量的相关使用
1 2 3 4 5 6 7 8 9 10 11 12 13
| $# 表示参数个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 表示所有参数,并且所有参数都是独立的
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
|
变量的删除/替换

可以看出来使用了匹配规则后I lov
匹配到了就被删除了,当然其他也是相同道理
字符串处理
expr 是从1开始计算;${string: position}是从0开始计算
1 2 3
| 获得字符串的长度:${#string}
获取子串在字符串中索引的位置:\`expr index $string $substring`
|


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #!/bin/bash #
function echo_len # 使用函数打印出string的长度 { echo "${#string}" # 可以加 “” } # 交互性 while true do read -p "Please input your choice." choice case $choice in 1) echo_len ;; q) exit ;; *) echo "error" ;; esac done
|
命令替换
方式有2个:也就是前面一直出现的 1. `command` 2. $(command)
- 获取该系统的所有用户 users=`/cat /etc/passwd | cut -d “:” -f 1`
- 根据系统时间计算今年 echo “This is $(date +%Y) year”
- 如果存在计算的话 echo “(((date +%j)/7))” 【使用$(())包住】
- 判断nginx进程是否存在
1 2 3 4 5 6
| #!/bin/bash # process_num = $(ps -ef | grep nginx | grep -v grep | wc -l) if [ $process_num -eq 0 ];then systemctl start nginx if
|
Expr数学运算
方式有2个:1. expr $num1 operator $num2 2. $(( $(num1) operator $(num2) ))
注意需要转译的情况以及空格的情况 例如 expr $num1 /> $num2
判断输入的是不是整数:expr $num1 + 1;echo $? 如果是0的话就是正确的没有报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #!/bin/bash #
read -p "Please input your num." num expr $num + 1 &> /dev/null # 不希望输入到终端 if [ $? -eq 0 ];then if [ `expr $num \> 0` -eq 1 ]; then echo "Yes" else exit fi else echo "Error" exit fi
|
Bc内建运算器
这里支持浮点数等运算: /usr/bin/bc
进入交互式的运算
如果想使用命令行进行计算的话:将运算传入进去
echo "23.3+35" | bc
echo "scale=4;23.3+35" | bc
1 2 3 4 5 6
| #!/bin/bash # read -p "Please input your num1." num1 read -p "Please input your num2." num2 echo "scale=4;$(num1)/$(num2)" | bc num3=`echo "scale=4;$(num1)/$(num2)" | bc`
|
函数使用
定义与使用
使用$1, $2, $3
进行传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #!/bin/bash #
function calcu { case $2 in +) echo "`expr $1 + $3`" -) echo "`expr $1 - $3`" \*) echo "`expr $1 \* $3`" } calcu $1 $2 $3
|
然后在终端输入sh calculate.sh 20 + 20
是能够直接赋值进去的
函数的返回值
- 使用return返回值:只能返回1-255的整数,通常用来判断状态
- 使用echo返回值:可以返回任何字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #!/bin/bash #
function is_nginx_running { this_pid=$$ ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ];then return 0 else return 1 }
is_nginx_running && echo "Nginx is running" || echo "Nginx is not running"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #!/bin/bash #
function get_users { users=`cat /etc/passwd | cut -d: -f1` echo $user }
user_list=`get_users` for u in $user_list do echo $u done
|
局部变量与全局变量
不做特殊说明,Shell的变量都是默认变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #!/bin/bash #
var1="Hello world" function test { var2=87 local var3=11 }
echo $var1 echo $var2 test echo $var1 echo $var2 # 调用了就生效了 echo $var3 # 说好了是local
|
文件查找
Find [路径] [选项] [操作]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| $ find /etc -name "*.conf"
$ find /etc -iname "*.conf"
$ find . -type f
$ find . -size +1M
$ find . -mtime -3
$ find . -type f -mindepth 2
$ find . -type f -maxdepth 2
$ find . -perm 777
$ find ./etc -name "*.conf" -exec rm -rf {} \;
|
find 在遍历磁盘
locate 在数据库进行查找
whereis查找二进制文件在哪里
which 仅查找二进制程序文件
文本处理三剑客
grep和egrep
1 2 3 4 5 6 7 8 9 10 11
| $ grep python_text file
$ grep -n python_text file
$ grep -iv python_text file
$ grep -E "python_text|Python" file
$ grep -F "py.*" file
$ grep -r "python"
|
sed
流编辑器,对标准输出或文件进行处理
1 2 3 4 5 6 7 8 9
| $ sed -n '/py.*/p' demo.txt
$ sed -n -e '/py.*/p' -e '/PY.*/p' demo.txt
$ sed -n -r '/python|PYTHON/' demo.txt
$ sed -n 's/love/like/g;p' demo.txt
$ sed -n -i 's/love/like/g;p' demo.txt
|
1 2 3 4 5 6 7 8 9 10 11 12
|
$ sed -n "17p" /etc/passwd
$ sed -n "17,20p" /etc/passwd
$ sed -n "/bash/p" /etc/passwd
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
$ sed -i '/\/bin\/bash/a This is User!' ./demo.txt
$ sed -n '/\/bin\/bash/w /tmp/user_login.txt' /etc/passwd
$ sed -i 's/\/bin\/bash/\/BIN\/BASH/' /etc/passwd
$ sed -i 's/\/bin\/bash/\/BIN\/BASH/g' /etc/passwd
$ sed -n '/\/bin\/bash/n' /etc/passwd
$ sed -i 's/had...p/hadoops/g' demo.txt
$ sed -i 's/had..p/&s/g' demo.txt
$ sed -i 's/\(had..p\)/\1O/g' demo.txt
$ sed -i 's/\(had\).../\1doop/g' demo.txt
|
1 2 3 4 5 6 7 8
| #!/bin/bash #
old_str=hadoop new_str=HADOOP
sed -i "s/$old_str/$new_str/g" demo.txt # 当作变量的话使用双引号
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $ sed -i '15d' /etc/passwd
$ sed -i '8,14d' /etc/passwd
$ sed -i '/\/sbin\/nologin/d' /etc/passwd
$ sed -i '/^mail/,/^yarn/d' /etc/passwd
$ sed -i '/\/sbin\/nologin/, 13d' /etc/passwd
$ sed -i '5, /^ftp/d' /etc/passwd
$ sed -i '/^$/d;/[:blank:]*#/d' nginx.conf
$ sed -i '/^[^#]/\*&/g' nginx.conf
|
1 2 3 4 5 6 7 8 9 10
| $ sed -i '1s/root/ROOT' passwd
$ sed -i '5,10s/\/sbin\/nologin\/bin\/bash/g'
$ sed -i '/\sbin\/nologin/s/login/LOGIN/g'
$ sed -i '/^root/, 15s/nologin/SPARK/g' passwd
$ sed -i 's/[0-9]*//g' file.txt
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ sed -i '10a Add Line' /etc/passwd $ sed -i '10,20a Add Line' /etc/passwd $ sed -i '/\/bin\/bash/a Insert Line' /etc/passwd
$ sed -i '/^yarn/i Add Line before' /etc/passwd $ sed -i 'i Line before' /etc/passwd
$ sed -i '20r /etc/fstab' /etc/passwd $ sed -i '\/bin\/bash/r /etc/fstab' /etc/passwd
$ sed -i '\/bin\/bash/w /tmp/demo.txt' /etc/passwd $ sed -i '10,/^hdfs/w /tmp/demo.txt' /etc/passwd
|
awk
awk ‘BEGIN{}pattern{commands}END{}’ file
- BEGIN{} 正式处理之前先执行
- pattern 匹配模式
- {commands} 处理命令,可能多行
- END{} 处理完所有匹配数据后执行
1 2 3 4 5 6 7 8
|
$ awk -v num2="$num2" 'BEGIN{print num2}' $ awk -F ":" '{print $1}'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
$ awk '{print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}{print $1}' /etc/passwd $ awk '{print NF}' /etc/passwd $ awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $2}' /etc/passwd $ awk 'BEGIN{RS="--";FS="|";ORS="&";OFS=":"}{print $2,$3}' /etc/passwd $ awk '{print $NF}' /etc/passwd
|
1 2 3 4 5 6 7 8 9 10
|
$ awk '{printf "%s\n", $1}' /etc/passwd $ awk '{printf "%s %s\n", $1, $7}' /etc/passwd $ awk '{printf "10%s 10%s\n", $1, $7}' /etc/passwd $ awk '{printf "%-20s %-10s\n", $1, $7}' /etc/passwd $ awk '{printf "%#x\n", $1}' /etc/passwd
|
1 2 3 4 5 6 7 8 9 10
|
$ awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd
$ awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}$1=="root" || $1=="yarn" {print $0}' /etc/passwd
|
1 2 3 4 5 6 7 8 9 10 11
| $ awk 'BEGIN{var=20+10;var1="hello";print var}' $ awk '/^$/{sum++}END{print sum}' /etc/passwd $ awk '{total=$2+$3+$4;AVG=total/3;printf "%-8s%5d%5d%5d%5f\n", $1,$2,$3,$4,AVG}' student.txt
$ awk 'BEGIN{FS=":"}{if ($3 < 100 && $3 > 50) print $0}' /etc/passwd $ awk 'BEGIN{FS=":"}{if ($3 < 100 && $3 > 50) {print $0} else {print $0}}' /etc/passwd
$ awk 'BEGIN{while(i < 100){sum+=i;i++}print sum}' /etc/passwd
|
1 2 3 4 5 6 7 8 9 10 11
|
$ awk '{print length($1)}' /etc/passwd
|
数组的使用暂时用不上,就先不做笔记了