前几天在群里听他们说不会shell编程就不算会linux,嘿,就我这暴脾气,学!干!嘿嘿!行了,不扯犊子了,犊子要生气了,最近学习了shell,感触颇多,我也参考了其他大佬的经验,看着视频课,学了些许基础,其实也就是那回事,认认真真踏踏实实的学,是能学到东西的,还有,要是自学的话,一定要能坐得住啊!
shell介绍
shell(外壳)是C语言编写的程序,是用户使用linux的桥梁,shell既是一种命令也是一种程序设计语言,即就是脚本语言。常见的脚本语言有JavaScript、VBScript、ASP、JSP、PHP、SQL、Perl、shell、python、Ruby、JavaFX、Lua等,shell其实是一种应用程序,这个应用程序提供了一个用户界面。linux中有很多类型的shell,不同的shell具备不同的功能shell还决定了脚本中函数的语法,linux中默认的shell是 /bin/bash,流行的shell有ash、bash、ksh、csh、zsh等,(知道就行了,别问为啥,因为我也不知道)不同的shell都有自己的特点以及用途。
bash:大多数linux系统默认使用的shell都是这个,bash shell是 bourne shell的一个免费版本,是最早的Unix shell,bash还有一个特点就是通过help可以查看帮助,它包含的功能几乎涵盖了shell所有的功能,所以一般的shell脚本都会指定它为执行路径。
一、shell入门
入门很简单,如果你学过其他的编程语言就更容易上手,还有linux的vim最好能会用,就是基本的操作就可以了,进度就会很快的。
先给大伙说一下,我使用的系统是kali linux,权限在root用户下。
代码规范
#!/bin/bash 指定告知系统当前这个脚本要使用的shell解释器,这行一般都写在首部
shell相关指令
文件命名规范:
文件名.sh .sh是linux下的bash shell的默认后缀
使用流程:
(1)创建.sh 文件 | touch test.sh |
(2)编写shell代码 |
|
(3)执行 | 脚本必须得有执行权限 chmod u+x 文件名.sh |
练习:创建一个test.sh 文件脚本程序,输出属于我们的 hello world
注意:输出的内容如果包含字母和符号,则需要用引号包括起来,如果是纯数字,可以包也可以不包。
(1)先创建文件 touch test.sh
(2) vim test.sh 进入编辑,
1 #!/bin/bash
2 echo "hello,world"
(3)完成后按一下 ESC 再shift + : 再输入wq进行保存退出
echo是bash的输出语句相当于C语言的printf,C++的cout,java的print
前面的我尽可能的把细节说一下,后面就不提了,这些基本的操作一定要熟练才是。
加上执行权限:chmod ugo+x test.sh 为所有用户加上此文件的可执行权限,你可能就注意到刚写的test.sh绿了,咳咳,别多想,它就表示整个文件是可执行文件
执行:./test.sh 一定要写成 ./test.sh ./ 就相当于告诉系统就在当前目录找。
这种执行方式最常用 注意了,test.sh此时在Desktop下,能直接执行,若是没有在直接路径,就得加上路径名比如:
练习:使用root账户创建并执行test2.sh 实现创建一个shelltest用户并在其家目录创建新的文件try.html
两步走:(1)添加用户(2)创建文件如下:
1 #!/bin/bash
2 useradd -m -g xk shelltest
3 touch /home/shelltest/try.html
-g 是指定用户所在的组,-m是参数,这个解释起来较麻烦,你可以自己查一查
在bash里面,写入的Linux命令没有什么特别的地方,不需要语法,就和平常键入命令一样,脚本一旦执行命令也就执行了
然后给这个脚本添加可执行权限并且执行:
运行查看:家目录下用户创建成功,对应的文件也创建了
二、进阶
恭喜你通过了入门?纳尼?太快了?基础其实很easy,了解一些基本的手法足矣,来继续吧
1.变量的定义与使用
语言都是相通的,这里的变量和其他语言的变量含义一样。先定义后使用
定义:class_name="new class" 后面不用分号,最好就是一行一条命令
使用:echo $ class_name 这是个美元 $ 符号,一旦要使用变量,这个符号必须要用
以下几点:
(1)在bash里面变量不需要声明,直接写出来直接用$调用。
(2)左边是变量名,右边是变量值
(3)变量名和变量值是使用和被使用的关系;用变量名来使用变量值
(4)使用变量的时候一定要在变量名前面加 $ 符号,这个在其他语言中也是存在的(php)
变量名的规范
注意,变量名后面的等号左右不能有空格,这可能和你熟悉的所有编程语言都不一样,同时命名须遵守以下规则:
(1)命名只能用英文字母,数字和下划线,首字母不能用数字
(2)中间不能有空格,可以使用下划线
(3)不能使用标点符号。
(4)不能使用bash的关键字,使用help可以查看相关的关键字
练习:使用变量输出hello world
1 #!/bin/bash
2 str="hello world"
3 echo $str
如下:
关于单引号和双引号:
在这里双引号和单引号是有差异的,shell命令执行时会将双引号的内容进行解析,它能认识里面的变量,若是而单引号就不行了,若是写成 echo '$str' 则会输出 $str ,改成"$str" 则会输出hello world,此外双引号还能实现转义
练习:
给定一个变量,输出现在的时间
1 #!/bin/bash
2 Time=`date "+%Y-%m-%d %H:%M:%S"`
3 echo $Time
注意反引号(esc下面的那个键),当在脚本中需要执行一些指令,并且将其赋给执行结果时需要用到
2.只读变量(了解)
语法:readonly 变量名
只读变量不能进行更改,只可以读取,就像C的宏定义C++的const一样严谨。
练习:定义变量a 并且其值为10 ,随后设置其值为只读变量,再尝试更改
1 #!/bin/bash
2 a=10
3 readonly a
4 a=20
5 echo $a
代码第4行想要对a进行更改被它的本身禁止了,大家有没有发现,即使第四行出现了错误,但是第五行依然执行了,所指在shell中如果程序不是相互的依赖关系(比如循环和条件判断),只是单行的命令,它们之间的执行是不会相互影响的,不像其他语言,一个地方出错整个程序就会终止,这也是bash的灵活之处。
3.接收用户输入(重点)
学习了输出,来看看输入吧。
语法:read -p 提示信息 变量名
你可以理解为:bash会将你输入的信息读取到内存中进行执行
-p prompt : 提示信息
变量名:你所输入的信息会存入到你指定的这个变量中,后面的使用会调用变量达到对输入的信息进行操作
练习:编写脚本test.6,要求执行之后提示用户输入文件的名称(可指定路径),然后自动为用户创建该文件并提示创建成功
1 #!/bin/bash
2 read -p '请输入需要创建文件的路径:' filepath
3 touch $filepath
4 echo '创建成功'
5 ls -l $filepath
执行:
4.删除变量(用的不多,了解)
语法 unset 变量名
练习: 定义变量b=20,在输出b的值,然后删除b,最后输出b
1 #!/bin/bash
2 b=20
3 echo $b
4 unset b
5 echo $b
在这里虽然不输出数据但是会有一个换行,别忽略了这个小细节
5.条件判断语句
语法1:(一个条件)
if condition
then
command1
command2
…
fi //记住了:if的条件判断中命令结束后一定要使用 fi 来关闭
单行写法(一般在命令行中执行的写法):if [condition];then command;fi
fi表示闭合
语法2:(两个条件)
if condition
then
command1
command2
…
else
command
fi
语法3:(多个条件)
if condition
then
command1
elif condition2
then
command2
else
commandN
fi
6.运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,awk和expr,
expr最常用,是一款表达式计算工具,使用它能完成表达式的求值操作。如下:
例如:两个数相加(注意使用的是反引号` 而不是单引号)
#!/bin/bash
val=`expr 2 + 2`
echo "两个数的和为:$val"
两点注意:
(1)表达式和运算符之间要有空格,2+2就是不对的,必须写成2 + 2,这与我们熟悉的大多数语言不一样
(2)完整的表达式要被 `` 包含
练习:两数的四则运算 以及是否相等:
1 #!/bin/bash
2 a=4
3 b=3
4 echo 'a =' $a
5 echo 'b =' $b
6 c=`expr $a + $b`
7 echo 'a + b =' $c
8 echo 'a - b =' `expr $a - $b`
9 echo 'a * b =' `expr $a \* $b` # 这里注意:乘法要用 \*
10 echo 'a / b =' `expr $a / $b`
11 echo 'a % b =' `expr $a % $b`
12 #判断是否相等
13 if [ $a == $b ]
14 then
15 echo 'a等于b'
16 else
17 echo 'a不等于b'
18 fi
19 #判断不相等
20 if [ $a != $b ]
21 then
22 echo 'a不等于b'
23 else
24 echo 'a等于b'
25 fi
要注意表达式格式和if判断[ ] 前面和后面都要有空格
运行:
7.关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
'123' 1233 就可以 'abc'就不行了
记英文比记简写容易的多
-eq | equal |
-neq | not equal |
-gt | great than |
-lt | less than |
-ge | great equal |
-le | less equal |
练习:进行两数的判断
代码比较多,别慌,都很简单,只是把多个关系运算放在了一个里面
1 #!/bin/bash
2 a=10
3 b=20
4 echo "a = $a"
5 echo "b = $b"
6 if [ $a -eq $b ]
7 then
8 echo 'a = b'
9 else
10 echo 'a ≠ b'
11 fi
12 if [ $a -ne $b ]
13 then
14 echo 'a ≠ b'
15 else
16 echo 'a = b'
17 fi
18 if [ $a -ge $b ]
19 then
20 echo 'a > b'
21 else
22 echo 'a < b'
23 fi
24 if [ $a -lt $b ]
25 then
26 echo 'a < b'
27 else
28 echo 'a > b'
29 fi
30 if [ $a -le $b ]
31 then
32 echo 'a ≤ b'
33 else
34 echo 'a ≥ b'
35 fi
36 if [ $a -ge $b ]
37 then
38 echo 'a ≥ b'
39 else
40 echo 'a ≤ b'
41 fi
执行:
练习:编写脚本,输入任意用户,判断用户是否存在。
费了点时间,刚开始不知道咋搞,一步步试下来的。
首先用read -p 接收输入的用户名。这一点是肯定有的,接下来就是进行怎样的判断,两种方法:
cat /etc/passwd 文件和 id user。因为创建的用户都在这里可以查到,这里的选择在于进行怎样的转换,
是用用户id以数字显示,还是用户名,其实两个都行,后者可读性能高些,
记得把查找到过滤好的信息一定要将它变成变量的形式:$(过滤信息)。然后进行字符串的判断 用 " " 包起来。
(1)cat /etc/passwd |grep inputuser 先看看格式,再决定怎么过滤和截取
cut -d ":"-f 1 : 以冒号为截取关键字,-f 是取截取后的第几个,1就是截取的第一个: xk
如下代码:
#!/bin/bash
read -p '请输入要查找的用户:' inputuser
finduser=$( cat /etc/passwd |grep $inputuser |cut -d ":" -f 1)
if [ "$finduser" == "$inputuser" ]
then
echo '用户存在,如下:'
cat /etc/passwd |grep $inputuser
else
echo '用户不存在'
fi
运行如下:
(2)id user,先看看效果
这里我的意思是,如果用户存在的话,他肯定有对应的 'uid'关键字。以uid作为中间参数。
如下代码:
#!/bin/bash
read -p '请输入要查找的用户:' inputuser
finduser=$( id $inputuser |cut -d "=" -f 1)
if [ "$finduser" == "uid" ]
then
echo '用户存在,如下:'
id $inputuser
else
echo '用户不存在'
fi
执行查询如下
8.逻辑运算符
练习以上几个运算符:
#!/bin/bash
a=10
b=20
if [ !false ]
then
echo '真'
else
echo '假'
fi
if [ $a -le $b -o $a -gt $b ]
then
echo "真"
else
echo "假"
fi
if [ $a -lt $b -a $b -ge 30 ]
then
echo '真'
else
echo '假'
fi
9.字符串运算符
10.文件测试运算符
测试:
执行脚本
可执行和不可执行:有一个用户有执行权限则为脚本认为这个文件就有可执行权限
11.shell脚本附带选项
自己编写一些命令。
传递:
./ test.sh a b c
接收:在脚本中可以用$1 表示 a,$2 表示b $3 表示c。注意 $0表示脚本文件本身
编写test13.sh 传递 a b c
可以看得出来,bash的输入不需要其他什么input、scanf之类的语法以及声明,而是直接输入,参数也就传递进去了
练习:创建自定义指令"user",可以直接执行,要求如下:
a.user-add 用户名 | 添加用户 |
b.user-del 用户名 | 删除用户及其家目录 |
#!/bin/bash
if [ $1 == '-add' ]
then
useradd -m -g xk -G sudo,root,adm $2
else
userdel -r $2
fi
-g是用户组
-G是附加权限组
这个脚本的执行方式就是一旦发现关键字'-add user' 就开始执行下面的添加用户命令。
进行执行和查看,最后删除这个测试的用户
然后将脚本用别名机制写成指令: vim ~/.bashrc
找到下面的alias关键字,仿照语法添加别名'user'
也就是说,这个别名机制成功创建后你在命令行键入user就相当于执行写的脚本命令,
可以理解为映射,注意脚本路径一定要写对。
然后执行,我这将添加和删除命令全执行了一次,如下:
扩展:
1.创建bash文件的时候自动添加可执行权限,什么意思呢?每次你创建一个.sh文件次序基本是
(1)touch test.sh
(2)写代码
(3)chmod u+x test.sh
是不是很麻烦?能不能在创建的同时就给文件可执行权限呢?答案是肯定的!
如下:如何实现将两个命令衔接起来实现同时执行呢?我也只是试了一下,没想到还真行!
用 && 进行连接!实现两个或者多个命令同时执行,多个我没试过,只是我的猜测,你可以试试哈!
我在这里命令是给其他用户权限,你也可以自己给别的用户权限
#/bin/bash
touch $1 && chmod o+x $1
执行一下:
是不是很舒服呢?
脚本写好后使用别名机制写一个属于自己的脚本命令我这里起的名字是mkfile,如果你对别名感兴趣也可以多写几条自己常用的.
然后再次执行一下:
是不是更爽了呢?就是这么好玩!
好了,到这里差不多就结束了,shell的路途还得好好走一阵子,各位同学加油哈!命令和脚本语言一定要多使用,慢慢的也就精通了,一定不能过于着急,要稳得住,坐得下,咳咳,话有点多了哈!总之,努力吧