Shell命令学习笔记(2)- bash脚本编写

背景

shell命令学习笔记(1) - linux 三剑客对三剑客深入学习以后,可以完成基本数据操作和分析,但这还不够。

于是继续二刷视频,学习更多技巧,掌握bash脚本的编写,可以做更复杂的处理。

Linux命令分类

  • 文件:everything is file
  • 进程:文件的运行状态
  • 网络:特殊的文件

文件

  • 文件路径:cd ,ls,pwd,$PWD,
  • 文件编辑:vim,awk,sed
  • 文件查看:less,more,cat,grep,
  • 文件创建:mv,cp,mkdir
  • 文件权限:chmod,chown,chgrp,ll
  • 文件搜索:find,which

进程

  • ps
  • 实时进程:top

网络

  • netstat
  • 发起http请求:curl
  • 下载文件:wget

其他工具

  • 聚合,排序:sort,head
  • 计算行数:wc,uniq
  • json格式化:jq
  • 查看命令说明:man + 命令
  • 添加环境变量:export

grep

把符合正则条件的数据整行打印出来

-ABC,同时打印上下文

  • An 后面n行
  • Bn 前面n行
  • Cn 前后n行,上下文信息
[indeyo@VM_0_14_centos ~]$ grep -C1 family go.txt 
It's my lunar birthday~
I'm so glad and lucky that my family care about me so much.

--
I don't need many friends.
Only family and a few friends are enough.
[indeyo@VM_0_14_centos ~]$ grep -A1 family go.txt 
I'm so glad and lucky that my family care about me so much.

--
Only family and a few friends are enough.
[indeyo@VM_0_14_centos ~]$ grep -B1 family go.txt 
It's my lunar birthday~
I'm so glad and lucky that my family care about me so much.
--
I don't need many friends.
Only family and a few friends are enough.

-r 递归搜索

[indeyo@VM_0_14_centos ~]$ grep -r lucky .
./go.txt:I'm so glad and lucky that my family care about me so much.
[indeyo@VM_0_14_centos ~]$ grep -r glad .
./go.txt:I'm so glad and lucky that my family care about me so much.
[indeyo@VM_0_14_centos ~]$ grep -r love .
./study_source/linux-sed-awk-grep-cut-find-frequently-used-commands-such-as-introduction.html:  <span class="with-love" id="animate">
./study_source/sed-and-awk-in-linux-and-its-associated-instance-of-the-use-of-analytical.html:  <span class="with-love" id="animate">

-o, -v, -i

  • i 忽略大小写
  • v 取反
  • o 只打印匹配的部分
[indeyo@VM_0_14_centos ~]$ grep -i FAMILY go.txt 
I'm so glad and lucky that my family care about me so much.
Only family and a few friends are enough.
[indeyo@VM_0_14_centos ~]$ grep -v -i FAMILY go.txt 
hahahh...

Today is Saturday..
It's my lunar birthday~

They try their best to make me happy, give me surprise and wish me good luck.

It is The Best Day~
I don't need many friends.
[indeyo@VM_0_14_centos ~]$ grep -o -i FAMILY go.txt 
family
family

正则表达式

基本正则(BRE)

  • ^开头,$结尾
  • *0个或者多个
  • .任意字符
  • [0-9] [A-Z]区间匹配

扩展正则(ERE)

需要加上-E参数

  • (A|B) 存在A或者B,分组
  • ? 非贪婪匹配,一般跟在*后面,减少匹配范围
  • {最小匹配数,最大匹配数} 范围约束
  • +一个或者多个
  • |相当于或,可以匹配任意一个表达式
[indeyo@VM_0_14_centos ~]$ ps aux | grep process
indeyo   10748  0.0  0.0 112712   964 pts/0    R+   11:22   0:00 grep --color=auto process
root     20497  0.0  0.0  47488  1228 ?        Ss   Mar26   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    20498  0.0  0.2  50952  5272 ?        S    Mar26  11:35 nginx: worker process
[indeyo@VM_0_14_centos ~]$ ps aux | grep 'process$'
nginx    20498  0.0  0.2  50952  5272 ?        S    Mar26  11:35 nginx: worker process
mily
[indeyo@VM_0_14_centos ~]$ grep 'd' 2.txt
dksjfklslf
dddddddddddd
:sjdfl
sfd 
df
[indeyo@VM_0_14_centos ~]$ grep 'd...' 2.txt
dksjfklslf
dddddddddddd
[indeyo@VM_0_14_centos ~]$ grep '^d...' 2.txt
dksjfklslf
dddddddddddd
[indeyo@VM_0_14_centos ~]$ grep '^d' 2.txt
dksjfklslf
dddddddddddd
df
[indeyo@VM_0_14_centos ~]$ grep 'dd*' 2.txt
dksjfklslf
dddddddddddd
:sjdfl
sfd 
df

发现一个正则的小规则!

[]里面,-_ 同时出现的时候,

  • 两者有先后顺序,_要放在前面
  • -要做转义
[86413302@shell.testing-studio.com ~]$echo '/raoul-h' | sed -E 's#/[0-9a-zaA-Z\-]+#/member#'
/member
[86413302@shell.testing-studio.com ~]$echo '/raoul-h' | sed -E 's#/[0-9a-zaA-Z\-_]+#/member#'
sed: -e expression #1, char 28: Invalid range end
[86413302@shell.testing-studio.com ~]$echo '/raoul-h_' | sed -E 's#/[0-9a-zaA-Z_\-]+#/member#'
/member

sort 排序工具

默认按照ascii码升序排列

➜  bash_pratice cat 1.txt | sort



hello
hello
hello
world
➜  bash_pratice cat 1.txt | sort | uniq -c
   3
   3 hello
   1 world

-n -k

  • -n 表示根据数字排序
  • -k [列数] 表示第几列排序
➜  bash_pratice sort -n -k 3 1.txt
pear 3 1
hello 4 2
apple 3 3
world 5 4
hello 1 5
hello 2 8

-r 降序

➜  bash_pratice sort -k 2 -r -n 1.txt
world 5 4
hello 4 2
pear 3 1
apple 3 3
hello 2 8
hello 1 5

uniq 统计数量

➜  bash_pratice uniq -c 1.txt
   2 hello 1 5
   1 apple 3 3
   1 hello 4 2
   1 pear 3 1
   1 world 5 4

管道

每个管道都是一个进程,同时进行,变量在不同进程之间不能共享,所以第二条语句没有输出

[indeyo@VM_0_14_centos ~]$ cat 2.txt | wc -l
91
[indeyo@VM_0_14_centos ~]$ cat 2.txt | wc -l | read x| echo $x

[indeyo@VM_0_14_centos ~]$ cat 2.txt | wc -l | while read x; do echo x=$x;done
x=91

输入输出

  • read 输入
  • echo printf 输出
  • >file重定向输出到文件
  • >>file追加数据
  • <file重定向从文件获取输入
[indeyo@VM_0_14_centos ~]$ echo 123 > num.txt
[indeyo@VM_0_14_centos ~]$ cat num.txt 
123
[indeyo@VM_0_14_centos ~]$ echo 456 > num.txt 
[indeyo@VM_0_14_centos ~]$ cat num.txt 
456
[indeyo@VM_0_14_centos ~]$ echo 789 >> num.txt 
[indeyo@VM_0_14_centos ~]$ cat num.txt 
456
789
[indeyo@VM_0_14_centos ~]$ read x
555555
[indeyo@VM_0_14_centos ~]$ echo $x
555555
[indeyo@VM_0_14_centos ~]$ read x < num.txt 
[indeyo@VM_0_14_centos ~]$ echo $x
456
[indeyo@VM_0_14_centos ~]$ while read x;do echo $x;done < num.txt 
456
789

netstat 网络

  • netstat -tlnp 查看正在对外开放监听的端口
  • netstat -tnp 查看外部链接的进程

参数的具体含义可以man一下~

由于没有root权限,所以无法看到进程对应的pid和名字

[indeyo@VM_0_14_centos ~]$ netstat -tlnp
(No info could be read for "-p": geteuid()=1003 but you should be root.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      -                                   
[indeyo@VM_0_14_centos ~]$ netstat -tnp
(No info could be read for "-p": geteuid()=1003 but you should be root.)
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 172.16.0.14:80          202.181.2.10:30779      SYN_RECV    -                   
tcp        0      0 172.16.0.14:80          45.88.14.38:30113       SYN_RECV    -                   
tcp        0      0 172.16.0.14:80          103.230.217.149:61465   SYN_RECV    -                   
tcp        0      0 172.16.0.14:80          45.87.53.191:64209      SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.140.230.24:31858    SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.140.230.178:54537   SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.140.230.178:27981   SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.38.165.216:13006    SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.38.165.242:60398    SYN_RECV    -                   
tcp        0      0 172.16.0.14:443         185.140.230.178:29812   SYN_RECV    -                   
tcp        0      0 172.16.0.14:55704       169.254.0.4:80          TIME_WAIT   -                   
tcp        0      0 172.16.0.14:36322       104.16.25.35:443        ESTABLISHED -              

进程

top 查看系统实时情况

[86413302@shell.testing-studio.com ~]$top
top - 10:13:00 up 160 days, 12:28, 12 users,  load average: 0.07, 0.30, 0.64
Tasks: 151 total,   1 running, 148 sleeping,   2 stopped,   0 zombie
%Cpu(s):  2.0 us,  2.0 sy,  0.0 ni, 96.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1016396 total,    73248 free,   583512 used,   359636 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   201104 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                
29111 root      10 -10  128788  10012   2716 S  2.0  1.0   7:17.53 AliYunDun              
  533 root      20   0  907508  29084   4800 S  0.7  2.9 383:37.08 CmsGoAgent.linu        
    1 root      20   0  125944   3480   1400 S  0.0  0.3  47:17.74 systemd                
    2 root      20   0       0      0      0 S  0.0  0.0   0:02.55 kthreadd               
    3 root      20   0       0      0      0 S  0.0  0.0  12:02.95 ksoftirqd/0            
    5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H           
    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0            
    8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh                 
    9 root      20   0       0      0      0 S  0.0  0.0  96:45.68 rcu_sched              
   10 root      rt   0       0      0      0 S  0.0  0.0   0:43.46 watchdog/0             
   12 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kdevtmpfs              
   13 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 netns                  
   14 root      20   0       0      0      0 S  0.0  0.0   0:04.23 khungtaskd             
   15 root       0 -20       0      0      0 S  0.0  0.0   0:00.05 writeback              
   16 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kintegrityd            
   17 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 bioset                 
   18 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kblockd                
   19 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 md                     
   25 root      20   0       0      0      0 S  0.0  0.0  41:15.04 kswapd0                
   26 root      25   5       0      0      0 S  0.0  0.0   0:00.00 ksmd                   
   27 root      39  19       0      0      0 S  0.0  0.0   2:11.76 khugepaged             
   28 root      20   0       0      0      0 S  0.0  0.0   0:00.00 fsnotify_mark          
   29 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 crypto     

ps 打印进程快照

  • ps aux

  • ps -ef 不包含内存等信息

[86413302@shell.testing-studio.com ~]$ps
  PID TTY          TIME CMD
 6375 pts/3    00:00:00 bash
 6986 pts/3    00:00:00 ps

[86413302@shell.testing-studio.com ~]$ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.3 125944  3480 ?        Ss    2019  47:17 /usr/lib/systemd/systemd -
root         2  0.0  0.0      0     0 ?        S     2019   0:02 [kthreadd]
root         3  0.0  0.0      0     0 ?        S     2019  12:02 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<    2019   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S     2019   0:00 [migration/0]

[86413302@shell.testing-studio.com ~]$ps aux | grep python
root       849  0.0  1.0 553640 10732 ?        Ssl   2019  20:50 /usr/bin/python -Es /usr/sbin/tuned -l -P
86413302  7542  0.0  0.0 112644   968 pts/3    R+   10:15   0:00 grep --color=auto python

[86413302@shell.testing-studio.com ~]$ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0  2019 ?        00:47:17 /usr/lib/systemd/systemd --switched-root --system --deseriali
root         2     0  0  2019 ?        00:00:02 [kthreadd]
root         3     2  0  2019 ?        00:12:02 [ksoftirqd/0]
root         5     2  0  2019 ?        00:00:00 [kworker/0:0H]
root         7     2  0  2019 ?        00:00:00 [migration/0]
root         8     2  0  2019 ?        00:00:00 [rcu_bh]
root         9     2  0  2019 ?        01:36:45 [rcu_sched]
root        10     2  0  2019 ?        00:00:43 [watchdog/0]
root        12     2  0  2019 ?        00:00:00 [kdevtmpfs]
root        13     2  0  2019 ?        00:00:00 [netns]
root        14     2  0  2019 ?        00:00:04 [khungtaskd]
root        15     2  0  2019 ?        00:00:00 [writeback]

find 查找文件(夹)

[indeyo@VM_0_14_centos ~]$ echo ~
/home/indeyo
[indeyo@VM_0_14_centos ~]$ find ~ -name "*.txt"
/home/indeyo/shell_bing.txt
/home/indeyo/2.txt
/home/indeyo/bing_taylor.txt
/home/indeyo/go.txt
/home/indeyo/indeyo/2.txt
[indeyo@VM_0_14_centos ~]$ find ~ -name "*.sh"
/home/indeyo/1.sh
/home/indeyo/cgi-bin/baidu.sh
/home/indeyo/five-in-a-row.sh
/home/indeyo/function.sh
/home/indeyo/indeyo/1.sh
/home/indeyo/indeyo/file.sh
/home/indeyo/baidu.sh
# 在当前目录继续往下找,深度为2
[indeyo@VM_0_14_centos ~]$ find ~ -maxdepth 2
/home/indeyo
/home/indeyo/.bash_history
/home/indeyo/1.sh
/home/indeyo/.config
/home/indeyo/.config/abrt
/home/indeyo/cgi-bin
/home/indeyo/cgi-bin/baidu.sh
/home/indeyo/.lesshst
/home/indeyo/.cache
/home/indeyo/.cache/abrt
/home/indeyo/shell_bing.txt
/home/indeyo/.bash_profile
/home/indeyo/index.html
/home/indeyo/study_source
/home/indeyo/study_source/linux-sed-awk-grep-cut-find-frequently-used-commands-such-as-introduction.html
/home/indeyo/study_source/sed-and-awk-in-linux-and-its-associated-instance-of-the-use-of-analytical.html
/home/indeyo/.viminfo
/home/indeyo/.pki
/home/indeyo/.pki/nssdb
/home/indeyo/.bashrc
/home/indeyo/five-in-a-row.sh
/home/indeyo/2.txt
/home/indeyo/bing_taylor.txt
/home/indeyo/baidu.sh.1
/home/indeyo/go.txt
/home/indeyo/.Xauthority
/home/indeyo/.bash_logout
/home/indeyo/function.sh
/home/indeyo/indeyo
/home/indeyo/indeyo/1.sh
/home/indeyo/indeyo/2.txt
/home/indeyo/indeyo/file.sh
/home/indeyo/baidu.sh
# 查找文件夹
[indeyo@VM_0_14_centos ~]$ find ~ -type d -maxdepth 2
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.

/home/indeyo
/home/indeyo/.config
/home/indeyo/.config/abrt
/home/indeyo/cgi-bin
/home/indeyo/.cache
/home/indeyo/.cache/abrt
/home/indeyo/study_source
/home/indeyo/.pki
/home/indeyo/.pki/nssdb
/home/indeyo/indeyo
[indeyo@VM_0_14_centos ~]$ find ~ -type d -maxdepth 2 -name "s*"
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.

/home/indeyo/study_source
[indeyo@VM_0_14_centos ~]$ find ~ -type d -name "s*"
/home/indeyo/study_source

ls -l 获取文件信息

文件权限:当前用户 当前组用户 非当前组用户

文件路径

  • 根路径 /
  • 主路径 ~
[indeyo@VM_0_14_centos ~]$ ls /
bin   data  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
boot  dev   home  lib64  media       opt  root  sbin  sys  usr
[indeyo@VM_0_14_centos ~]$ ls ~
1.sh      baidu.sh.1       five-in-a-row.sh  index.html      study_source
2.txt     bing_taylor.txt  function.sh       indeyo
baidu.sh  cgi-bin          go.txt            shell_bing.txt
[indeyo@VM_0_14_centos ~]$ echo ~
/home/indeyo
[indeyo@VM_0_14_centos ~]$ echo /
/

less vs more

more是最早的工具

less功能更强大,可以向上翻页,左右滑动,b键返回上一页

/搜索,n向前搜索,shift+n向后搜索

[indeyo@VM_0_14_centos ~]$ which vi
alias vi='vim'
	/usr/bin/vim
[indeyo@VM_0_14_centos ~]$ which vim
/usr/bin/vim
[indeyo@VM_0_14_centos ~]$ ll /usr/bin/vim /usr/bin/vi
-rwxr-xr-x. 1 root root  910136 Aug  2  2017 /usr/bin/vi
-rwxr-xr-x. 1 root root 2289640 Aug  2  2017 /usr/bin/vim

软链 ln

  • 相当于快捷方式,把一个文件链接到另外一个,两个文件都可以操作

  • 文件类型为 l。

  • 从文件大小来看软链小很多,有点像是一个指针,并没有申请另外一块存储空间(不负责任地猜测)

[86413302@shell.testing-studio.com ~]$ln -s a.txt b.txt
[86413302@shell.testing-studio.com ~]$ll
total 568
-rwxrwxr-x 1 86413302 86413302     29 Apr 18 16:16 1.sh
-rw-rw-r-- 1 86413302 86413302     57 Apr 22 22:46 a.txt
-rw-rw-r-- 1 86413302 86413302      0 Dec 10 07:34 b
-rw-rw-r-- 1 86413302 86413302 135583 Dec 10 07:25 bing_shell.txt
lrwxrwxrwx 1 86413302 86413302      5 Apr 22 22:46 b.txt -> a.txt
-rw-rw-r-- 1 86413302 86413302     68 Apr 20 15:18 file.sh
drwxrwxr-x 2 86413302 86413302   4096 Mar  4 16:52 indeyo
-rw-r--r-- 1 86413302 86413302 424573 Feb  4 09:55 nginx.log

特殊符号使用

`` 和 $() 表示保存命令执行结果到一个变量

[indeyo@VM_0_14_centos ~]$ seq 2 2 10
2
4
6
8
10
[indeyo@VM_0_14_centos ~]$ for i in `seq 2 2 10`;do echo $i;done
2
4
6
8
10
[indeyo@VM_0_14_centos ~]$ for i in $(seq 2 2 10);do echo $i;done
2
4
6
8
10

内置判断

  • -e 是否存在
  • -f 是否是文件
  • -d 是否是文件夹
  • -w 可写
  • -r 可读
  • -x 可执行
  • -s 是否不为空,文件长度不为0,则true

哈哈哈!写了一个小小脚本,用来测试file的结果命令,挺好玩儿的!

file.py
#!/bin/bash
if [ "$1" "$2" ];then
   echo true;
else
   echo false;
fi 
[indeyo@VM_0_14_centos ~]$ ll
total 128
-rwxrwxr-x 1 indeyo indeyo    45 Apr 20 12:25 1.sh
-rw-rw-r-- 1 indeyo indeyo   202 Apr 18 09:40 2.txt
-rwxrwxr-x 1 indeyo indeyo    72 Apr 20 15:23 file.sh
-rw-rw-r-- 1 indeyo indeyo   284 Apr 18 09:38 go.txt
drwxrwxr-x 2 indeyo indeyo  4096 Apr 18 09:28 indeyo
-rw-rw-r-- 1 indeyo indeyo 98808 Dec 11 22:59 shell_bing.txt
drwxrwxr-x 2 indeyo indeyo  4096 Apr 18 09:29 study_source
[indeyo@VM_0_14_centos ~]$ file.sh -d 2.txt 
false
[indeyo@VM_0_14_centos ~]$ file.sh -d indeyo 
true
[indeyo@VM_0_14_centos ~]$ file.sh -f indeyo 
false
[indeyo@VM_0_14_centos ~]$ file.sh -e indeyo 
true
[indeyo@VM_0_14_centos ~]$ file.sh -e 1.sh 
true
[indeyo@VM_0_14_centos ~]$ file.sh -r 1.sh 
true
[indeyo@VM_0_14_centos ~]$ file.sh -s 1.sh 
true
[indeyo@VM_0_14_centos ~]$ file.sh -w indeyo 
true
[indeyo@VM_0_14_centos ~]$ file.sh -x go.txt 
false

#!/bin/bash

#!/bin/bash,脚本开头加上这一句,表示用bash来运行脚本,系统会根据后缀名和这一句注释来判断,如果不写,默认是bash。以防万一,还是加上

bash脚本调试

bash -x 可以打印每行命令的执行结果,方便调试

[indeyo@VM_0_14_centos ~]$ bash -x 1.sh *.txt
+ wc -l 2.txt go.txt shell_bing.txt
   91 2.txt
   11 go.txt
   39 shell_bing.txt
  141 total
+ ll list
1.sh: line 3: ll: command not found

函数

  • $N,取函数入参
  • $*$@,取出所有入参,可以用于表达式中
  • ${#*}${#@},获得所有入参数
[indeyo@VM_0_14_centos indeyo]$ f1(){
> wc -l *.txt
> }
[indeyo@VM_0_14_centos indeyo]$ type f1
f1 is a function
f1 () 
{ 
    wc -l *.txt
}
[indeyo@VM_0_14_centos indeyo]$ f1
    6 2.txt
   39 shell_bing.txt
   45 total
[indeyo@VM_0_14_centos indeyo]$ f2(){
> echo p0=$0
> echo p1=$1
> echo p2=$2
> echo $*
> echo $@
> echo ${#*}
> echo ${#@}
> }
[indeyo@VM_0_14_centos indeyo]$ f2
p0=-bash
p1=
p2=


0
0
[indeyo@VM_0_14_centos indeyo]$ f2 a b
p0=-bash
p1=a
p2=b
a b
a b
2
2
[indeyo@VM_0_14_centos indeyo]$ f2 1 2 3 4 5 6 7 8 9 10
p0=-bash
p1=1
p2=2
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
10
10
[indeyo@VM_0_14_centos indeyo]$ f1(){ wc -l $@; }
[indeyo@VM_0_14_centos indeyo]$ f1


^C
[indeyo@VM_0_14_centos indeyo]$ f1 1.txt
wc: 1.txt: No such file or directory
[indeyo@VM_0_14_centos indeyo]$ f1 1.sh
18 1.sh
[indeyo@VM_0_14_centos indeyo]$ f1 *.txt
    6 2.txt
   39 shell_bing.txt
   45 total

逻辑判断语句

if语句

[indeyo@VM_0_14_centos indeyo]$ if [ -e 1.sh ] ;then echo 1.sh exist; else echo 1.sh not exist;fi 
1.sh exist
[indeyo@VM_0_14_centos indeyo]$ if [ -e 2.sh ] ;then echo 1.sh exist; else echo 1.sh not exist;fi 
1.sh not exist
[indeyo@VM_0_14_centos indeyo]$ if [ -e 1.sh ] ;then
> echo 1.sh exist
> else
> echo 1.sh not exist
> fi
1.sh exist

for语句

[indeyo@VM_0_14_centos indeyo]$ for i in 1 2 3 4 ;do echo $i;done
1
2
3
4
[indeyo@VM_0_14_centos indeyo]$ for i in "1 2 3 4" ;do echo $i;done
1 2 3 4
[indeyo@VM_0_14_centos indeyo]$ ll
total 112
-rw-rw-r-- 1 indeyo indeyo   167 Dec 16 07:21 1.sh
-rw-rw-r-- 1 indeyo indeyo    44 Dec 27 08:28 2.txt
-rw-rw-r-- 1 indeyo indeyo 98808 Dec 11 22:59 shell_bing.txt
[indeyo@VM_0_14_centos indeyo]$ for f in *.txt; do wc -l $f;done
6 2.txt
39 shell_bing.txt
[indeyo@VM_0_14_centos indeyo]$ for i in $(seq 1 3 10);do echo $i;done
1
4
7
10

while语句

[indeyo@VM_0_14_centos indeyo]$ while read line;do echo line=$line;done < 1.sh
line=gogog1111111111abczzzzzzz
line=q
line=11111111sdfsdf222
line=
line=q
line=q
line=q
line=
line=
line=Today is Wednessday.
line=I wake up at 6.20.
line=I prepare for the soap.
line=It must be delicious.
line=
line=
line=2019-12-11
line=2019-12-12
line=

seq 自动生成序列

分别支持传入1个、2个、3个参数

[indeyo@VM_0_14_centos indeyo]$ seq 1 3 10
1
4
7
10
[indeyo@VM_0_14_centos indeyo]$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[indeyo@VM_0_14_centos indeyo]$ seq 5 20
5
6
7
8
9
10
11
12
13
14
15
16

字符串操作

[86413302@shell.testing-studio.com ~]$s="hello world"
[86413302@shell.testing-studio.com ~]$echo ${#s}
11
[86413302@shell.testing-studio.com ~]$xx="1234567"
[86413302@shell.testing-studio.com ~]$echo ${xx:2:3}
345
[86413302@shell.testing-studio.com ~]$echo ${xx:2:4}
3456
[86413302@shell.testing-studio.com ~]$echo ${xx:2:5}
34567
[86413302@shell.testing-studio.com ~]$echo ${xx/3/c}
12c4567
[86413302@shell.testing-studio.com ~]$echo ${xx##*3}
4567
[86413302@shell.testing-studio.com ~]$echo ${xx%%5*}
1234
[86413302@shell.testing-studio.com ~]$echo $xx | awk '{print substr($0,2,3)}'
234
[86413302@shell.testing-studio.com ~]$echo $xx | sed 's#3#c#'
12c4567

数字型变量操作

整数计算用$(())

浮点数计算用awk,精度更高,可以格式化输出

[indeyo@VM_0_14_centos indeyo]$ awk 'BEGIN{print 1/3}'
0.333333
[indeyo@VM_0_14_centos indeyo]$ echo $((1/3))
0
[86413302@shell.testing-studio.com ~]$awk 'BEGIN{printf("%.2f\n"), 1/3}'
0.33

保存命令结果

[indeyo@VM_0_14_centos indeyo]$ ll
total 112
-rw-rw-r-- 1 indeyo indeyo   167 Dec 16 07:21 1.sh
-rw-rw-r-- 1 indeyo indeyo    44 Dec 27 08:28 2.txt
-rw-rw-r-- 1 indeyo indeyo 98808 Dec 11 22:59 shell_bing.txt
[indeyo@VM_0_14_centos indeyo]$ echo `ll`
total 112 -rw-rw-r-- 1 indeyo indeyo 167 Dec 16 07:21 1.sh -rw-rw-r-- 1 indeyo indeyo 44 Dec 27 08:28 2.txt -rw-rw-r-- 1 indeyo indeyo 98808 Dec 11 22:59 shell_bing.txt
[indeyo@VM_0_14_centos indeyo]$ echo $(ll)
total 112 -rw-rw-r-- 1 indeyo indeyo 167 Dec 16 07:21 1.sh -rw-rw-r-- 1 indeyo indeyo 44 Dec 27 08:28 2.txt -rw-rw-r-- 1 indeyo indeyo 98808 Dec 11 22:59 shell_bing.txt

预定义变量

RANDOM蛮好玩的,生成的基本是4、5位数的随机数

[indeyo@VM_0_14_centos indeyo]$ echo ~
/home/indeyo
[indeyo@VM_0_14_centos indeyo]$ pwd
/home/indeyo/indeyo
[indeyo@VM_0_14_centos indeyo]$ echo $PWD
/home/indeyo/indeyo
[indeyo@VM_0_14_centos indeyo]$ echo $USER
indeyo
[indeyo@VM_0_14_centos indeyo]$ echo $HOME
/home/indeyo
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
9487
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
4947
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
15869
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
13591
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
1955
[indeyo@VM_0_14_centos indeyo]$ echo $RANDOM
6610
[indeyo@VM_0_14_centos indeyo]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/indeyo/.local/bin:/home/indeyo/bin
[indeyo@VM_0_14_centos indeyo]$ which ls
alias ls='ls --color=auto'
	/usr/bin/ls

单引号 vs 双引号

双引号有转义的作用,一般用双引号。

如果不想被转义,则用单引号

[indeyo@VM_0_14_centos indeyo]$ x="1 2"
[indeyo@VM_0_14_centos indeyo]$ echo $x
1 2
[indeyo@VM_0_14_centos indeyo]$ echo "1 2 $x"
1 2 1 2
[indeyo@VM_0_14_centos indeyo]$ echo "1 2 $(ls)"
1 2 1.sh
2.txt
shell_bing.txt
[indeyo@VM_0_14_centos indeyo]$ echo '1 2 $x'
1 2 $x

权限

chmod 改变文件权限

ll + [文件名]查看文件权限,最左侧包含10个字符的字符串表示权限。

其中,第一列表示文件类型,文件夹 d,文件 -,软链 l。

➜  Test ll
total 24
-rwxrw-r-x  2 indeyo  staff   65  6 12 10:29 1.sh
-rwxrw-r-x  2 indeyo  staff   65  6 12 10:29 2.sh
lrwxr-xr-x  1 indeyo  staff    4  6 12 10:25 3.sh -> 1.sh
-rw-r--r--  1 indeyo  staff  875  5 20 17:28 find_river.py
drwxr-xr-x  2 indeyo  staff   64  6 12 09:43 test
两种方法
  1. 文字法

    • 用户类型:所属用户 u,本组用户 g,其他用户 o,所有用户 a(默认)

    • 执行权限:可写 w,可读 r,可执行 x

    • 操作类型:添加权限 +,删除权限 -

      ➜  Test cat 1.sh
      #!/bin/bash
      echo $PATH
      ➜  Test ll 1.sh
      -rw-r--r--  1 indeyo  staff  23  6 12 09:29 1.sh
      ➜  Test chmod +x 1.sh
      ➜  Test ll 1.sh
      -rwxr-xr-x  1 indeyo  staff  23  6 12 09:29 1.sh
      ➜  Test 1.sh
      /Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/indeyo/.android-sdk-macosx/platform-tools/:/Users/indeyo/Library/Android/sdk/tools:/Users/indeyo/Library/Android/sdk/tools/bin:/Users/indeyo/Library/Android/sdk/platform-tools:/Users/indeyo/Library/Android/sdk/build-tools/29.0.3:.
      ➜  Test chmod -x 1.sh
      ➜  Test 1.sh
      zsh: permission denied: 1.sh
      ➜  Test ll 1.sh
      -rw-r--r--  1 indeyo  staff  23  6 12 09:29 1.sh
      ➜  Test chmod u+x 1.sh
      ➜  Test ll 1.sh
      -rwxr--r--  1 indeyo  staff  23  6 12 09:29 1.sh
      ➜  Test chmod g+w 1.sh
      ➜  Test ll 1.sh
      -rwxrw-r--  1 indeyo  staff  23  6 12 09:29 1.sh
      ➜  Test chmod o+x 1.sh
      ➜  Test ll 1.sh
      -rwxrw-r-x  1 indeyo  staff  23  6 12 09:29 1.sh
      
  2. 数字法

    1 表示可执行,2 表示可写,4 表示可执行

    ➜  Test ll
    total 24
    -rwxrwxrwx  2 indeyo  staff   65  6 12 10:29 1.sh
    -rwxrwxrwx  2 indeyo  staff   65  6 12 10:29 2.sh
    lrwxr-xr-x  1 indeyo  staff    4  6 12 10:25 3.sh -> 1.sh
    -rw-r--r--  1 indeyo  staff  875  5 20 17:28 find_river.py
    drwxr-xr-x  2 indeyo  staff   64  6 12 09:43 test
    ➜  Test chmod 177 1.sh
    ➜  Test ll 1.sh
    ---xrwxrwx  2 indeyo  staff  65  6 12 10:29 1.sh
    ➜  Test chmod 277 1.sh
    ➜  Test ll 1.sh
    --w-rwxrwx  2 indeyo  staff  65  6 12 10:29 1.sh
    ➜  Test chmod 377 1.sh
    ➜  Test ll 1.sh
    --wxrwxrwx  2 indeyo  staff  65  6 12 10:29 1.sh
    ➜  Test chmod 774 1.sh
    ➜  Test ll 1.sh
    -rwxrwxr--  2 indeyo  staff  65  6 12 10:29 1.sh
    

趣味脚本

CGI-Bin技术搭建小网站

步骤

  1. 编写bash脚本

  2. 加上执行权限

  3. 执行以下命令在当前目录下启动服务

    不同python版本执行不同的命令

    python2 -m CGIHTTPServer 8000
    python3 -m http.server --cgi 8000
    

蛮好玩的~直接在当前目录搭建网站,可以访问当前目录

使用场景
  • 测试接口,mock服务端的返回数据

  • 性能不高,无法支持高访问量,适合日常测试

F:\cmder_mini
λ python -m http.server --cgi 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [17/Apr/2020 15:23:20] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:23:21] code 404, message File not found
127.0.0.1 - - [17/Apr/2020 15:23:21] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [17/Apr/2020 15:23:25] "GET /bin/ HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:23:26] "GET /bin/Readme.md HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:23:40] "GET /node_modules/ HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:23:44] "GET /LICENSE HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:23:59] "GET /config/ HTTP/1.1" 200 -
127.0.0.1 - - [17/Apr/2020 15:24:05] "GET /Version%201.3.11.843 HTTP/1.1" 200 -

java程序重启服务

[test@sd-3-centos126 for-test]$ cat restart.sh
#!/bin/bash
app=for-test.jar
args='-Dappid=WC7vBzXALACPbPfy -Xms256m -Xmx512m'
cmd=$1
pid=`ps aux | grep java | grep $app | awk '{print $2}'`

startup(){
   nohup java -jar $args $app &
   tail -f nohup.out
}

kill -9 $pid
startup

问题

  1. 什么情况下需要用到exit,脚本退出?如果不执行会怎么样?

    主要用于退出当前shell。

    可以带一个参数n(可选),0 <= n <= 255,以某个值退出。

    如果不带n,默认以上一条命令的返回值退出。

    不执行就保持bash进程。

  2. $@ $*的区别不是很明白

    没关系,要用的时候再看用哪个

    [indeyo@VM_0_14_centos ~]$ ff(){ for d in $@ "$@" $* "$*"; do echo $d; done; };ff 1 2 '3 "4 5" 6' 7 "8 9"
    1
    2
    3
    "4
    5"
    6
    7
    8
    9
    1
    2
    3 "4 5" 6
    7
    8 9
    1
    2
    3
    "4
    5"
    6
    7
    8
    9
    1 2 3 "4 5" 6 7 8 9
    
    

一点TIPS

有空看看一些大厂写的bash,学习格式和规范,比如appium、Android等脚本。

学习没有捷径,唯有脚踏实地,方得真谛。

参考资料

9 个赞

请问,我是零基础的文科转理科的,学这个的整个逻辑是怎样的?它的整个前因后果体系该怎么理清楚

推荐学习~