shell编程-shell基础

shell 特殊符号

$? 命令返回值

在shell中,每条命令执行都有返回值$?

[root@iZwz9f92w7soch5m251ghgZ ~]# echo "hello world"
hello world
[root@iZwz9f92w7soch5m251ghgZ ~]# echo $?
0

单引号与双引号区别

  • 单引号用于保持引号内所有字符的字面值

  • 双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:

    • $加变量名可以取变量的值
    • 反引号仍表示命令替换
    • $表示$的字面值
    • `表示`的字面值
    • "表示”的字面值
    • \表示\的字面值
    • 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值。
[root@iZwz9f92w7soch5m251ghgZ ~]# echo "`date`"
Sun Aug 28 08:58:13 CST 2022
[root@iZwz9f92w7soch5m251ghgZ ~]# echo '`date`'
`date`
[root@iZwz9f92w7soch5m251ghgZ ~]# 
[root@iZwz9f92w7soch5m251ghgZ ~]# echo "$name"
Milton
[root@iZwz9f92w7soch5m251ghgZ ~]# echo '$name'
$name

由上可见,单引号中完全是保持字符串的原型输出,而双引号进行了命令替换。

注意:在双引号中不能使用!

[root@iZwz9f92w7soch5m251ghgZ ~]# echo "hello world !"
-bash: !": event not found
[root@iZwz9f92w7soch5m251ghgZ ~]# echo 'hello world !'
hello world !

\ 转义符,让元字符回归本意

[root@iZwz9f92w7soch5m251ghgZ test]# echo -e "atb"
atb
[root@iZwz9f92w7soch5m251ghgZ test]# echo -e "a\tb"
a       b

反引号 ` ` 命令替换,等价于 $(),命令先被执行

[root@iZwz9f92w7soch5m251ghgZ ~]# echo `date`
Sun Aug 28 21:28:39 CST 2022
[root@iZwz9f92w7soch5m251ghgZ ~]# 
[root@iZwz9f92w7soch5m251ghgZ test]# touch `date +%F`_file.txt
[root@iZwz9f92w7soch5m251ghgZ test]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 28 21:31 2022-08-28_file.txt
[root@iZwz9f92w7soch5m251ghgZ test]# df -Ph
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        59G  2.6G   54G   5% /
devtmpfs        858M     0  858M   0% /dev
tmpfs           868M     0  868M   0% /dev/shm
tmpfs           868M  604K  867M   1% /run
tmpfs           868M     0  868M   0% /sys/fs/cgroup
tmpfs           174M     0  174M   0% /run/user/0
[root@iZwz9f92w7soch5m251ghgZ test]# df -Ph | grep '/$'
/dev/vda1        59G  2.6G   54G   5% /
[root@iZwz9f92w7soch5m251ghgZ test]# df -Ph | grep '/$' | awk '{print $4}'
54G
[root@iZwz9f92w7soch5m251ghgZ test]# disk_free=$(df -Ph | grep '/$' | awk '{print $4}')
[root@iZwz9f92w7soch5m251ghgZ test]# echo $disk_free
54G
[root@iZwz9f92w7soch5m251ghgZ test]# 

&& 逻辑关系

只有前面的语句执行成功返回成功($? == 0),才执行后面的语句
如果前面的语句执行失败,则不再执行后面的语句

[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.com &>/dev/null && echo "ping ping ping"
ping ping ping
[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.test.com &>/dev/null && echo "ping ping ping"
[root@iZwz9f92w7soch5m251ghgZ ~]#  

|| 逻辑关系

当前面的语句执行失败,才执行后面的语句

[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.com &>/dev/null || echo "ping ping ping"
[root@iZwz9f92w7soch5m251ghgZ ~]# 
[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.test.com &>/dev/null || echo "ping ping ping"
ping ping ping
[root@iZwz9f92w7soch5m251ghgZ ~]# 

; 语句顺序组合

分号仅仅起到命令的组合作用,不管前面的语句是否执行成功,都会继续执行后面的语句

[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.com &>/dev/null ; echo "ping ping ping"
ping ping ping
[root@iZwz9f92w7soch5m251ghgZ ~]# ping -c1 www.baidu.test.com &>/dev/null ; echo "ping ping ping"
ping ping ping
[root@iZwz9f92w7soch5m251ghgZ ~]# 

执行shell脚本

常见脚本解释器

[root@iZwz9f92w7soch5m251ghgZ ~]# which bash
/usr/bin/bash
[root@iZwz9f92w7soch5m251ghgZ ~]# which python
/usr/bin/python
[root@iZwz9f92w7soch5m251ghgZ ~]# which perl
/usr/bin/perl

准备shell脚本:ping.sh

#!/usr/bin/bash
ping -c1 www.baidu.com &>/dev/null && echo "website is up" || echo "website is down"

脚本首行#!指定脚本解释器,如果不指定解释器,默认为bash

bash 执行

[root@iZwz9f92w7soch5m251ghgZ ~]# bash ping.sh 
website is up
[root@iZwz9f92w7soch5m251ghgZ ~]# sh ping.sh 
website is up

通过sh 执行脚本,实际上也是使用的bash

[root@iZwz9f92w7soch5m251ghgZ ~]# ll /usr/bin/sh
lrwxrwxrwx. 1 root root 4 Jul 11  2019 /usr/bin/sh -> bash

通过路径执行脚本

通过路径执行,脚本需要可执行权限

[root@iZwz9f92w7soch5m251ghgZ ~]# ./ping.sh
-bash: ./ping.sh: Permission denied
[root@iZwz9f92w7soch5m251ghgZ ~]# /root/ping.sh
-bash: /root/ping.sh: Permission denied
[root@iZwz9f92w7soch5m251ghgZ ~]# 
[root@iZwz9f92w7soch5m251ghgZ ~]# chmod a+x ping.sh 
[root@iZwz9f92w7soch5m251ghgZ ~]# 
[root@iZwz9f92w7soch5m251ghgZ ~]# ./ping.sh 
website is up
[root@iZwz9f92w7soch5m251ghgZ ~]# /root/ping.sh 
website is up

调试脚本

#sh -n ping.sh 仅调试语法 syntax error
#sh -vx ping.sh 以调试的方式执行,查询整个执行过程
[root@iZwz9f92w7soch5m251ghgZ test]# sh -vx ping.sh 
#!/usr/bin/bash

ping -c1 www.baidu.com &>/dev/null && echo "website is up" || echo "website is down"
+ ping -c1 www.baidu.com
+ echo 'website is up'
website is up

linux shell 环境变量相关文件

nologin shell

为了直观体现shell中各环境文件的执行顺序,分别在以下文件的末尾添加一条echo语句。
/etc/profile,/etc/bashrc,~/.bash_profile,~/.bashrc,~/.bash_logout

login shell

su 切换用户时,带横杆-,表示切换后使用用户shell环境

[root@iZwz9f92w7soch5m251ghgZ ~]# su - gfc
Last login: Sun Aug 28 12:42:28 CST 2022 on pts/6
here is /etc/profile
here is /etc/bashrc
here is ~/.bashrc
here is ~/.bash_profile
[gfc@iZwz9f92w7soch5m251ghgZ ~]$ 
[gfc@iZwz9f92w7soch5m251ghgZ ~]$ exit
logout
here is ~/.bash_logout

nologin shell

su 切换用户时,不带横杆-,表示切换后不使用用户shell环境

[root@iZwz9f92w7soch5m251ghgZ ~]# su gfc
here is /etc/bashrc
here is ~/.bashrc
[gfc@iZwz9f92w7soch5m251ghgZ root]$ exit
exit
[root@iZwz9f92w7soch5m251ghgZ ~]# 

shell通配符(元字符)

元字符:表示的不是本意

* 匹配任意多个字符

[root@iZwz9f92w7soch5m251ghgZ test]# ls
ab  abc
[root@iZwz9f92w7soch5m251ghgZ test]# ls a*
ab  abc

? 匹配任意一个字符

[root@iZwz9f92w7soch5m251ghgZ test]# ls
ab  abc
[root@iZwz9f92w7soch5m251ghgZ test]# ls a?
ab

[] 匹配括号中的任意一个字符

[root@iZwz9f92w7soch5m251ghgZ test]# ls
abc  acc  adc
[root@iZwz9f92w7soch5m251ghgZ test]# ls a[bd]c
abc  adc
[root@iZwz9f92w7soch5m251ghgZ test]# ls
abc  acc  adc
[root@iZwz9f92w7soch5m251ghgZ test]# ls a[^bd]c
acc

{} 集合

[root@iZwz9f92w7soch5m251ghgZ test]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 28 13:39 abc
-rw-r--r-- 1 root root 0 Aug 28 13:42 acc
-rw-r--r-- 1 root root 0 Aug 28 13:42 adc
[root@iZwz9f92w7soch5m251ghgZ test]# touch a{1,2,3}c
[root@iZwz9f92w7soch5m251ghgZ test]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 28 13:44 a1c
-rw-r--r-- 1 root root 0 Aug 28 13:44 a2c
-rw-r--r-- 1 root root 0 Aug 28 13:44 a3c
-rw-r--r-- 1 root root 0 Aug 28 13:39 abc
-rw-r--r-- 1 root root 0 Aug 28 13:42 acc
-rw-r--r-- 1 root root 0 Aug 28 13:42 adc
[root@iZwz9f92w7soch5m251ghgZ test]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 28 13:46 abc
[root@iZwz9f92w7soch5m251ghgZ test]# cp /root/test/ab{c,c_bak}
[root@iZwz9f92w7soch5m251ghgZ test]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 28 13:46 abc
-rw-r--r-- 1 root root 0 Aug 28 13:47 abc_bak

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
My Show My Code