目录
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
一、第一个shell脚本
1、创建
ubuntu@ubuntu:~$ cd qqq #来到之前创建好的一个文件夹qqq
ubuntu@ubuntu:~/qqq$ mkdir 1.shell #再创建一个名叫1.shell的文件夹
ubuntu@ubuntu:~/qqq$ cd 1.shell #来到这个文件夹下
ubuntu@ubuntu:~/qqq/1.shell$ ls #看看里面有什么
ubuntu@ubuntu:~/qqq/1.shell$ vim 1.sh #用vim编辑一个叫1.sh的shell脚本
出现如下界面,加个hello进去(不会使用vim的看第一章)
2、运行
ubuntu@ubuntu:~/qqq/1.shell$ ls #看一下创建成功没有
1.sh
ubuntu@ubuntu:~/qqq/1.shell$ ls -al #显示所有文件及目录,. 开头的隐藏文件也会列出
total 12
drwxrwxr-x 2 ubuntu ubuntu 4096 4月 22 11:06 .
drwxrwxr-x 3 ubuntu ubuntu 4096 4月 22 10:57 ..
-rw-rw-r-- 1 ubuntu ubuntu 13 4月 22 11:06 1.sh
ubuntu@ubuntu:~/qqq/1.shell$ chmod a+x 1.sh # 运行方法1
#chmod控制用户对文件的权限的命令
#u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个群体(group)者
#o 表示其他以外的人,a 表示这三者皆是
#+ 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
#r 表示可读取,w 表示可写入,x 表示可执行
#x 表示只有当该文件是个子目录或者该文件已经被设定过为可执行。
ubuntu@ubuntu:~/qqq/1.shell$ ls -l 1.sh #-l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出
-rwxrwxr-x 1 ubuntu ubuntu 13 4月 22 11:06 1.sh
ubuntu@ubuntu:~/qqq/1.shell$ ./1.sh
hello
ubuntu@ubuntu:~/qqq/1.shell$ bash 1.sh # 运行方法2
hello
3、输入输出
(1)read学习
read命令用于从标准输入读取数值。从键盘收到信息以后使用echo输出,可以看出不加$是输不出正确内容的
read -p
指令后面跟提示信息(用双引号括起来),即在输入前打印提示信息。
read -s
是安静模式,在输入字符时不再屏幕上显示
再加-t
参数+秒数,则会定义输入字符的等待时间。
(2)echo学习
echo -e
指令开启转义
(3)printf
(4)pwd命令用于显示工作目录。执行 pwd 指令可立刻得知目前所在的工作目录的绝对路径名称。
a=`pwd`中符号不是单引号,而是反单引号,esc键下面那个
二、shell变量
1、定义变量及变量名的命名规则
定义变量时,变量名不加美元符号。变量名和等号之间不能有空格,比如
school_name="zhongbei"
以上是显式给变量赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`
或
for file in $(ls /etc)
以上语句将 /etc 下目录的文件名循环出来。
变量名的命名规则
1、命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
2、中间不能有空格,可以使用下划线(_)。
3、不能使用标点符号。
4、不能使用bash里的关键字(可用help命令查看保留关键字)。
2、使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:
echo $school_name
或
echo ${school_name}
以上两种情况虽然都行,但第一种有时会出错,如下
如果不给skill变量加花括号且没有空格,写成echo "I am good at $skillScript"
,解释器就会把$skillScript
当成一个变量(其值为空),代码执行结果就不一样了。最好给所有变量加上花括号。
使用变量的命令
1、使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
2、使用 unset 命令可以删除变量。变量被删除后不能再次使用。unset 命令不能删除只读变量。
3、特殊变量
位置变量
$0
:获取当前执行shell脚本的文件名,包括路径。
$n
:获取当前执行脚本的第n个参数,n=1…9,如果n大于9,则需要将n使用大括号括起来;
$#
:得到执行当前脚本的参数个数;
下面这两个用法上有些相似
$*
:获取当前shell的所有参数,将所有命令行参数视为单个字符串,相当于"$1$2$3"
$@
:获取这个程序所有参数,并保留参数之间的任何空白,相当于"$1" "$2""$3"
,这是将参数传给其他程序的最好办法;
状态变量
$?
:判断上一指令是否成功执行,0为成功,非零为不成功
以下,因为没有dfe这个文件所以这个指令不成功,故返回非零值
$$
:取当前进程的PID
$ !
:上一个指令的PID
PID(Process Identification)操作系统里指进程识别号,也就是进程标识符。
操作系统里每打开一个程序都会创建一个进程ID,即PID。
变量,参数展开
$ {parameter:-word}
如果变量未定义,则表达式的值为word。
$ {parameter:=word}
如果变量未定义,则设置变量的值为word,返回表达式的值也是word。
$ {parameter: ?word}
用于捕捉由于变量未定义而导致的错误并退出程序。
${parameter:+word}
如果变量已经定义,返回word,也就是真。
${ !prefixe}prefix
开头的变量
$ { !prefix* }
字符串展开
${#parameter}
输出字符串的长度
${parameter:offset}
从第offset字符开始截取
${parameter:offset:length]
从offset字符开始截取,取length长度
${parameter#pattern}
从头删除最短匹配
${parameter##pattern}
最长
${parameter%pattern}
从尾删除最短
${parameter%%pattern}
从尾删除最长
${parameter/pattern/string}
第一个匹配被替换
${parameterl/pattern/string}
全部匹配被替换
${parameter/ #pattern/string}
字符串开头的替换
${parameter/%pattern/string}
字符串结尾的替换
${parameter,,}${parameter^^}
全部转换为小写、大写
${parameter,}${parameter^}
首字母转换为小写、大写
三、shell字符串
1、引号问题
除了数字以外字符串是shell编程中最常用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
体会一下以下内容的不同
研究一下下面的内容做更深的理解
2、常用命令
其中查找子字符串哪个字母先出现就计算哪个
四、shell数组
1、定义
用括号来表示数组,数组元素用空格符号分割
数组名=(值1 值2 ... 值n)
array_name=(value0 value1 value2 value3)
或
array_name=(
value0
value1
value2
value3
)
或
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
2、读取与输出
${数组名[下标]}
valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
取得数组元素的个数
length=${#array_name[@]}
或
length=${#array_name[*]}
取得数组单个元素的长度
lengthn=${#array_name[n]}
找到数组的下标
${!arry[@]}
数组追加
arry+=( a b c)
数组排序
sort
删除数组与元素
unset
五、shell注释
1、以 # 开头的行就是注释,通过每一行加一个 # 号设置多行注释
2、可以把一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。
3、多行注释,形式如下,其中EOF可以使用其他符号替换
:<<EOF
注释内容...
注释内容...
EOF