shell脚本的一些学习笔记----(一)
一、确认shell的种类:默认都是Bash
确认shell类型:echo $SHELL,返回路径可以看出,例如返回:/bin/zsh
,那么你正在使用Zsh。
当前系统可用的shell类型:cat /etc/shells
二、打印
学过编程对打印不陌生,C中就是printf函数,python中就是print,就是利用输入输出库函数来把想要打印出的信息打印到指定的设备(例如屏幕上)。而linux中的打印是可以指定输入内容从哪来,且打印到哪的,即输入输出重定向。这个后面阐述。
linux中的打印是echo
例如打印“hello”,echo hello。
打印“hello world”,echo hello world
添加单引号的效果也一样,例如echo hello 和 echo ‘hello’都是打印hello,单引号的作用是忽略变量和其他转义字符,纯输出字符串。
这里示例中都是从键盘输入,显示屏输出。因为linux默认的输入输出设备就是屏幕和键盘。
设备 | 设备名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
echo的打印是自带换行符的,echo hello本质等同于C中的printf("hello\n");
若要手动输出多个换行符,可以选择写多个echo,或者利用转义符\n,但是若要实现转义符功能,就要在echo 之后添加一个选项 '-e' ,这个选项意味着echo会对转义字符进行识别。同时还必须在需要识别的转义字符外添加双引号才能实现转义。例如我想hello之后添加2行空白,那么可以这样写:echo -e “hello\n” 或者 echo -e hello"\n"
若要去掉echo自带的换行,则使用-n选项。
重定向输入输出
打印不一定就是打印到屏幕上,可以选择打印到其他文件中。
例如我编写一个打印的shell脚本 PrintName.sh:
#!/bin/bash
echo -n ‘my name is ’
echo -n -e "cps\n"
然后我跑这个脚本应该能打印一行:my name is cps然后换行
但是我希望打印直接打印到log.txt中,而不是屏幕,那么我可以选择使用‘>’来重定向输出完成。
bash PrintName.sh > log.txt
这样在我运行脚本的时候,输出内容就不会输出到屏幕而是输出到我指定的文件中了。
这里使用的是‘>’,这个是覆盖重定向输出,如果用‘>>’就是追加重定向输出。
例如还是bash PrintName.sh > log.txt,我跑两次,那么log.txt中就会出现两行内容
如果是‘<’就是覆盖重定向输入,‘<<’就是追加重定向输入。
如果希望什么都不打印,即不打印屏幕也不打印到文件,可以丢到/dev/null 文件中,
即:命令 > /dev/null
这个重定向不仅仅用于跑脚本,可以用于一切命令,例如ls -la,可以把打印信息打印到某个文件中。
三、逻辑符号
命令1;命令2:命令1和命令2顺序执行,先1后2
命令1&&命令2:与运算,命令1正确才会执行命令2, 命令1不正确不会执行命令2。和C中的逻辑运算符有所不同的是命令1作为主要影响因素,命令2执行与否由命令1决定
命令1||命令2:或运算,命令1正确则不执行命令2, 命令1不正确则执行命令2。二者选一执行,同样由命令1作为主导。
四、shell变量
什么是变量?
在一个脚本周期内,其值可以发生改变的量就是变量。
变量的命名规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 等号左右两侧不能有空格,可以使用下划线“_”,变量的值如果有空格,需要使用单引号或双引号包括。如:“test=“hello world!””。其中双引号括起来的内容“$”,“(”和反引号都拥有特殊含义,而单引号括起来的内容都是普通字符。
- 不能使用标点符号,不能使用bash里的关键字(可用help命令查看保留关键字)。
- 环境变量建议大写,便于区分
- 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含"$变量名"或用${变量名}包含变量名。
其中变量声明很简单,直接取名令其=某个值就行
例如:name=cps
那么变量name的值就是cps。
需要注意的是引用变量的方式和一些特殊的符号用途。
单引号:前面说过,输出字符串,不进行转义也不识别命令。例如echo ‘ls’,他就真的打印ls
双引号:可以识别-> 转义符\ 反引号·· $ 被调用的命令 引用的变量值
反引号:就是esc下面的··,括起来的内容是系统命令,echo ·ls·,会执行这个系统命令
$():同反引号一样的功能,建议用这个,反引号容易混
#:注释
上面打印篇中,hello world的打印可以不使用引号也能打印出来,但是变量如果出现空格,就必须使用引号包括。
例如name=hello world是会报错的
并且等号两端不能有空格,变量名不能数字开头
变量的调用采用$符号
name=hello
echo “$name”
就能打印出name的值
环境变量
环境变量的设置是:export 变量名=“xxx”
添加的环境变量可以通过‘env’得到
删除变量使用:unset
位置参数(类似形参设置)
shell脚本中可以使用以下这几种来作为特殊参数来用
$n : 例如$0,$1...其中0比较特殊,代表文件名字。1~无穷都是传入的参数(两位数以上就要用{}括起来)
例如在shell中写:echo "this file name is $0",就会打印出这个脚本名称代替$0
$# : 传入的实参的个数。
例如我有个脚本这样写:
其中的$1~3都是传入的实参,我调用脚本的时候在命令后跟上,实际上就是跟3个实参来调,所以最终Have $# Var会被打印成Have 3 Var
$? :这个变量是预定义变量,内容等同于 “!(上一条命令正确)”。如果上条正确就返回0(不打印信息),如果不正确就返回其它非0数字。
第一条命令是cd到某个不存在的目录,显然是失败的,所以返回1(非0数字)。
而对于最后那条echo命令来说,他的上一条指的是返回1那条echo,显然那条打印是正确执行的,所以最后返回0(正确)
$$: 指的是当前PID
$!: 指的是后台最后一条进程的PID
其它暂时没用过,还有$@和$*,大致了解了下,$@和$*都是指的输入的实参总和,只不过*是拼成一个整体,而@是拼成一个类似数组/列表的分别独立的变量。
只读变量
只读变量使用readonly来声明,例如创建了一个变量name,令他的值是3,然后再声明成只读变量。之后除了读操作是不能对其进行修改的。
这是一个测试的脚本内容:
其中name=30的操作就是在尝试修改只读变量,执行这个shell会报错
但是打印不受影响,说明echo某个变量属于是读操作。