shell 入门 ☞ 01
一、解析简单的 Shell 脚本
#!/usr/bin/bash
ping -c1 www.baidu.com &>/dev/null && echo "www.baidu.com is up" || echo "www.baidu.com is down!"
- #!/usr/bin/bash:#!这个符号的名称,叫做”Shebang”或者”Sha-bang”。
#! 一句必须在文件的最开始,第一行
如果执行脚本的时候没有指定解释器如:
bash /test/script/ping01.sh 或 bash ./ping01.sh
python /test/script/ping01.sh 或 python ./ping01.sh
这个时候才会生效,就会根据 #!指定的解释器来解释脚本。
[root@yangzelu ~]# which bash
/usr/bin/bash
[root@yangzelu ~]# which python
/usr/bin/python
[root@yangzelu ~]# which perl
/usr/bin/perl
[root@yangzelu ~]#
最好在脚本顶部带上 #!,因为大多数Linux 系统默认是shell,如果执行脚本没有指定解释器可能有问题。
-
ping -c -w :-c 指ping 的次数,-w 指执行的最后期限
-
0:表示标准输入;
1:表示标准输出;
2:表示标准错误输出;
>:默认为标准输出重定向,同 1 >;
2>&1:把标准错误输出 重定向到 标准输入;
&>file:把标准输出 和 标准错误输出 都重定向到文件file 中;
n>&m:使文件描述符n 成为输出 文件描述符m 的副本。 -
& > /dev/null :/dev/null 是一个比较特殊的文件夹,所有传给它的东西都会丢掉。上面的命令会丢掉ping 的所有过程。
-
a && b || c :a为真,则执行b;否则执行c
链接: Shell重定向.
- echo -n 表示不换行输出
[root@yangzelu ~]# echo -n "www.baidu.com";echo "www.taobao.com"
www.baidu.comwww.taobao.com
- echo -e 表示可以使用转义字符
[root@yangzelu ~]# echo -e "www.baidu\t.com"
www.baidu .com
- 使用echo 输出命令替换后的内容时,格式可能发生变化。
- $?: 表示上一个命令执行后的退出状态。
- echo $?: 如果返回是0 表示执行成功;如果是返回0 以外的值(非0的数,返回值在0-255间),就是失败。
二、bash 中引入python
#!/usr/bin/bash
ping -c1 www.baidu.com &>/dev/null && echo "www.baidu.com is up" || echo "www.baidu.com is down!"
#!/usr/bin/python
print ("hello world!");
将 A 里面的内容合并到B 里面去:
cat A >> B
#!/usr/bin/bash
ping -c1 cloud.yangzelu.com &>/dev/null && echo "cloud.yangzelu.com is up" || echo "cloud.yangzelu.com is down!"
/usr/bin/python <<-EOF
print ("hello world!");
EOF
echo "嵌入python 成功"
EOF和-EOF区别:
EOF 只是一个标识,可以替换成任意的合法字符
没有 - 的话,EOF作为结束符,前面不能有任何tab制表符。
有 - 的话,EOF作为结束符,前面可以有tab制表符,容错率更高一点
Shell 脚本:
#!/usr/bin/bash
cd /home
ls
. 和 source 在当前shell 中执行,会影响到当前shell,所以跳转了目录。
在自己的脚本中想调用其他脚本的变量时,可以先用 . 或 source 执行了被调用的脚本,这样就可以直接调用别人定义的变量,不必用export 定义全局的变量。
三、命令的排序
- ; 仅仅是命令的排序,不具备逻辑判断。
- && 和 || 具有逻辑判断。
[root@yangzelu ~]# ping -c1 11.22.33.44 &>/dev/null && echo "ok..." || echo "down..."
down...
[root@yangzelu ~]#
[root@yangzelu ~]# echo "ok..." && cd /test/111/222 && echo "error..."
ok...
-bash: cd: /test/111/222: No such file or directory
[root@yangzelu ~]#
==========================
注意:
command & 后台执行
command &>/dev/null 混合重定向(标准输出1,错误输出2)
command1 && command2 命令排序,逻辑判断
==========================
四、shell 通配符(元字符)
- * 匹配任意多个字符
[root@xterm variable]# ls
array communication demo_01 demo_02 express join length read_only string substring unset
[root@xterm variable]# ls demo_*
demo_01 demo_02
[root@xterm variable]#
- ? 匹配任意一个字符
[root@xterm variable]# ls
array communication demo_01 demo_02 express join length read_only string substring unset
[root@xterm variable]# ls ?emo_0*
demo_01 demo_02
[root@xterm variable]#
- [ ] 匹配括号中任意一个字符
[root@xterm variable]# ls
array communication demo_01 demo_02 express join length read_only string substring unset
[root@xterm variable]# ls demo_0[1-9]
demo_01 demo_02
[root@xterm variable]#
- ( ) 在子shell 中执行
[root@xterm variable]# umask
0022
[root@xterm variable]# umask 077; touch 100.text
[root@xterm variable]# ll 100.text
-rw------- 1 root root 0 Aug 1 22:25 100.text
[root@xterm variable]# umask
0077
当前shell 的umask 变了。
[root@xterm variable]# umask
0022
[root@xterm variable]# (umask 077; touch 200.text)
[root@xterm variable]# ll 200.text
-rw------- 1 root root 0 Aug 1 22:27 200.text
[root@xterm variable]# umask
0022
[root@xterm variable]#
当前shell 的umask 没变。
- { } 集合 touch file{1…9}
[root@xterm script]# mkdir {aaa,bbb}
[root@xterm script]# ls
aaa bbb path.sh ping01.py ping01.sh variable
[root@xterm script]#
{} 里面的元素不能有空格。
[root@xterm script]# mkdir -pv /aa/{33/{44,55},66}
mkdir: created directory ‘/aa’
mkdir: created directory ‘/aa/33’
mkdir: created directory ‘/aa/33/44’
mkdir: created directory ‘/aa/33/55’
mkdir: created directory ‘/aa/66’
- \ 转义符 - 让元字符回归本意
[root@xterm script]# ls
path.sh ping01.py ping01.sh variable
[root@xterm script]# echo *
path.sh ping01.py ping01.sh variable
[root@xterm script]# echo \* #这点输出了 * 而非列表
*
[root@xterm script]#
[root@xterm script]# echo -e "atb"
atb
[root@xterm script]# echo -e "a\tb"
a b
[root@xterm script]#
五、颜色文本输出
- echo 固定写法 “\e[1;30-37”
- echo -e “\e[0m” 清除颜色
六、变量
6.1 环境变量
系统定义的变量基本都是环境变量:/etc/profile
显示定义好的所有的环境变量:env
定义环境变量:
- 方法一:export back_dir1=/home/backup
- 方法二:export back_dir2 将自己定义的变量转换成环境变量
环境变量作用的范围:当前shell 和子shell 有效
查看环境变量:echo $变量名;env;例如env |grep back_dir2
取消环境变量:unset 变量名
6.2 变量赋值的方式
1. 显示赋值:
- ip=11.22.33.44
- school=“school_name”
- today=`date +%F`
- today=$(date +%F)
命令替换:
`` 等价于 $( ),这里面的命令会被先执行。
2. read 从键盘读取变量名
- read 变量名
- read -p “提示信息:” 变量名
- read -t 5 -p “提示信息:” 变量名 //倒计时5s
- read -n 2 变量名 //只需要输入的前2个字符
#!/usr/bin/bash
read -p "请输入姓名:" name
read -p "请输入性别:" sex
read -p "请输入年龄:" age
echo "你输入的姓名是:$name, 性别是:$sex, 年龄是:$age"
运行结果:
[root@xterm read]# ./read_01
请输入姓名:kangkang
请输入性别:M
请输入年龄:12
你输入的姓名是:kangkang, 性别是:M, 年龄是:12
#!/usr/bin/bash
read -p "输入姓名,性别,年龄[e.g. zhangsan m 20]:" name sex age
echo "你输入的姓名是:$name,性别是:$sex,年龄是:$age"
运行结果:
输入姓名,性别,年龄[e.g. zhangsan m 20]:kangkang M 12
你输入的姓名是:kangkang,性别是:M,年龄是:12
6.3 变量的运算
- 整数运算
方法一:expr
[root@xterm ~]# expr 1+2
1+2
[root@xterm ~]# expr 1 + 1
2
方法二:$(( )) //脚本中用得比较多
[root@xterm ~]# echo $((2 + 3))
5
[root@xterm ~]# echo $((2+3))
5
方法三:$[]
[root@xterm ~]# echo $[1+2]
3
[root@xterm ~]# echo $[ 1 + 3 ]
4
方法四:let //脚本中用得比较多
[root@xterm ~]# let sum=1+2; echo ${sum}
3
[root@xterm ~]# let sum = 1 + 2; echo ${sum}
-bash: let: =: syntax error: operand expected (error token is "=")
3
[root@xterm ~]# let sum=1 + 2; echo ${sum}
-bash: let: +: syntax error: operand expected (error token is "+")
1
6.4 变量“内容”的删除和替换
1. # 从前面往后面数数,最终并未改变原字符串的内容
[root@xterm ~]# url=www.sina.com.cn
[root@xterm ~]# echo ${#url} //字符串长度
15
[root@xterm ~]# echo ${url}
www.sina.com.cn
[root@xterm ~]# echo ${url#*.}
sina.com.cn
[root@xterm ~]# echo ${url##*.}
cn
[root@xterm ~]# echo ${url}
www.sina.com.cn
2. % 从后面往前面数数,最终并未改变原字符串的内容
[root@xterm ~]# url=www.sina.com.cn
[root@xterm ~]# echo ${url}
www.sina.com.cn
[root@xterm ~]# echo ${%url}
-bash: ${%url}: bad substitution
[root@xterm ~]# echo ${url%.*}
www.sina.com
[root@xterm ~]# echo ${url%%.*}
www
[root@xterm ~]# echo ${url}
www.sina.com.cn
3. 索引及切片
[root@xterm ~]# url=www.sina.com.cn
[root@xterm ~]# 0123456789 ^C
[root@xterm ~]# echo ${url:0:5} //从0开始,切5位数
www.s
[root@xterm ~]# echo ${url:5:5} //从5开始,切5位数
ina.c
[root@xterm ~]# echo ${url}
www.sina.com.cn
4. 内容的替换
[root@xterm ~]# url=www.sina.com.cn
[root@xterm ~]# echo ${url/n/N}
www.siNa.com.cn
[root@xterm ~]# echo ${url}
www.sina.com.cn
[root@xterm ~]# echo ${url//n/N}
www.siNa.com.cN
5. 变量的替代
5.1 -
[root@xterm ~]# echo ${var1} //未定义变量var1
[root@xterm ~]# echo ${var1-aaaa}
aaaa
[root@xterm ~]# var2=1111
[root@xterm ~]# echo ${var2-bbbb}
1111
[root@xterm ~]# var3= //定义变量var3 为空
[root@xterm ~]# echo ${var3-cccc}
[root@xterm ~]#
${变量名-新的变量值} 只要变量被赋值(包括空值),就不会被替代
5.2 :-
[root@xterm ~]# echo ${var1}
[root@xterm ~]# var2=1111
[root@xterm ~]# echo ${var2:-bbbb}
1111
[root@xterm ~]# var3=
[root@xterm ~]# echo ${var3:-cccc}
cccc
${变量名:-新的变量值} 只要变量没有被赋值(包括空值),就会被替代
+、 :+、 =、 :=、 ?、 :?
6. 字符串变量
提示:要使用双引号,不然会出现预想不到的错误
案例1:
[root@xterm ~]# [ $username = root ]; echo $?
-bash: [: =: unary operator expected
2
[root@xterm ~]# [ "$username" = "root" ]; echo $?
1
[root@xterm ~]#
案例2:
[root@xterm ~]# BBB=""
[root@xterm ~]# echo ${#BBB} //字符串长度
0
[root@xterm ~]# [ -z ${BBB} ]; echo $? // -z 表示长度为0
0
[root@xterm ~]# [ -n ${BBB} ]; echo $? // -n 表示长度不为0
0
[root@xterm ~]# [ -z "${BBB}" ]; echo $? // 加了字符串
0
[root@xterm ~]# [ -n "${BBB}" ]; echo $? // 加了字符串!!!
1
变量为空 或者 未定义,长度都是0.
七、数组
7.1 普通数组
只能使用整数作为数组的索引。
7.2 关联数组
可以使用字符串作为数组索引。