Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。也就是说,它起到的是一个翻译的作用。
Shell还是一个功能强大的编程语言,易编写、调试,灵活性强。
sh + 脚本路径
sh 脚本路径
bash + 脚本路径
bash 脚本路径
直接使用脚本的路径
脚本路径
但是这样可能会遇到一些问题:
根据我们的Linux基础知识可以发现,这个文件是没有”x“权限的,而”x“权限就是程序运行权限,因此,我们只需给这个文件加上运行权限即可:
chmod +x 脚本路径
注意事项:上面的1、2、3种执行Shell的方式,本质上都是打开了一个子Bash执行,当前的Bash不会受影响,除了source启动:
source 脚本路径
source是Bash内置的一个命令,效果等同于”.“。
在一个Linux中有多个sh解释器,它们的名字存储在etc下的shells文件中,我们可以使用命令查看:
cat /etc/shells
我们可以看到类似以下的打印内容:
这其中的每一个都是一个解释器。
在Linux系统中,/etc文件夹用于存储系统的配置文件和目录,它包含了多个应用程序和系统组件的配置文件,用于定义系统和软件的行为:
这个目录中的东西我们是不能随意修改的。
按照惯例,我们每一门编程语言的第一个程序都是输出一行”hello world“,这里也不例外:
#!/bin/bash
echo hello world
看着这个代码,我们会发现并不陌生,因为代码的执行主体就是我们的echo命令,这是因为Linux的大部分命令(小部分命令可以直接与Linux系统内核进行沟通)本就是通过sh解释器进行了“翻译”之后才能够正常执行的。而我们的Shell编程也是使用sh解释器进行解释,即:Shell 编程是通过将多个 Linux 命令组合在一起来创建脚本或程序的过程。
除了echo指令外,还有一行代码:
#!/bin/bash
在Shell中,“#”是用作注释的符号,但这里是”#!“,它是hashbang或shebang的符号,用于指定脚本执行时使用的解释器。
在本例中,我们指定需要/bin/bash作为本脚本的解释器。这行代码不是必须的,如果我们没有使用hashbang来指定解释器,系统就会使用默认的sh解释器来解释该脚本。
Shell中的变量可以分为两类:系统预定义变量和自定义变量。
Shell中的变量也有全局变量和局部变量之分。全局变量在所有Bash进程中都有效,局部变量仅在当前Bash进程中有效。
在子Bash中,对变量做任何更改都不会影响父Bash。
变量名=值
注意:“=”前后不能有空格!unset 变量名
readonly 变量名
注意:静态变量不能unsetexport 变量名
在Shell中,单引号和双引号有着不同的作用
在Shell中,我们不能直接进行数学运算:
# 计算1+2的值
echo $((1+2))
echo $[1+2]
这两种表达方式都是一样的,在Shell中,所有的数学计算都是这样,只需要注意包裹一下就好了,其他的跟别的语言没什么区别。
若是我们想使用运算对变量赋值,就不一样了,需要使用双引号包裹起来:
temp="$((1*5))"
echo $temp
在Shell中,还有命令替换,跟上面说过的运算符有点像:
$()
其实命令替换运算符有很多种,这个只是其中一种,它更简洁、常用。
条件判断就是一般编程语言中的if语句
test condition
[ condition ]
后者需要注意:condition前后需要有空格,并且条件非空即为true。
两个整数之间的比较:
-eq 等于(equal)
-ne 不等于(not equal)
-lt 小于(less than)
-le 小于等于(less equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
按照文件权限进行判断:
-r 有读权限(read)
-w 有写权限(write)
-x 有执行权限(execute)
按照文件类型进行判断:
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
在Shell中,每种括号都是有用的,因此,Shell中不使用花括号包裹执行程序:
if [ ]
then
执行程序
fi
if [ ]
then
执行程序
elif
then
执行程序
fi
需要注意:除了else,其他的语句之后都需要使用then。
跟其它编程语言一样,它是用于处理多分支语句的:
case $变量名 in
"值1")
如果符合这个,则执行这段程序
;; # 必须以两个分号结尾
"值2")
如果符合这个,则执行这段程序
;;
...
*)
如果都不符合,就执行这个
;;
esac
while [ condition ]
do
执行程序
done
read是Linux内置的命令,而不是Shell提供的:
read (选项) (参数)
函数也一样分为两种:系统函数和自定义函数。
以下两个函数都是属于Linux系统提供的函数,在某些类Unix系统中可能也能使用。这两个函数本质上都是做的字符串操作。
basename [string/pathname] suffix]
这个函数会删除所有前缀包括最后一个”/",然后将字符串显示出来;suffix是后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
dirname 文件绝对路径
会从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录部分)。
[ function ] funcname[()]
{
执行程序
[return int;]
}
调用这个函数的时候”()“中的参数列表可有可无,调用参数采用$1,$2等。
函数的返回值只能通过$?进行获取,return也是可有可无的,若是没有,将会以最后一条语句的执行情况作为返回值,return的数字也有要求:0~255。
接下来给出一个示例,涵盖了Shell编程中的所有知识点:
#! /bin/bash
# if语句
if [ $1="input" ]
then
echo "Hello Shell"
elif [ $1!="output" ]
then
echo exit
else
echo "Good bye"
fi
# while循环
temp=$2
while [ $temp -lt 10 ]
do
echo "whileing"
temp=$(($temp+1))
done
# case的使用
case $temp in
"10")
echo "while正常执行"
;;
*)
echo "while执行异常,temp=$temp"
;;
esac
# 使用read进行终端读取
read -p "请随便输入:" input
echo "input=$input"
# 当前文件名为
echo "当前文件名为:$(basename $0)"
# 更改文件后缀
echo "文件名更换为txt:$(basename $0 .sh).txt"
# 当前文件的路径为
echo "当前文件的路径为:$(dirname $0)"
# 编写一个函数
func(){
echo "函数func正在被调用"
echo "传入func的参数为:$1,即文件路径"
return 1;
}
# 调用这个函数
func "$0"
echo "函数的返回值为$?"