一文掌握Shell

文章目录

    • Shell概述
    • 脚本的常用执行方式
      • Linux中的sh解释器
      • Linux中的/etc
    • 编写sh脚本
      • 第一个sh脚本
      • 变量
        • 1. 系统预定义变量
        • 2. 自定义变量
        • 3. 变量定义规则
          • 单引号和双引号的区别
        • 4. 特殊变量
      • 运算符
      • 命令替换
      • 条件判断
        • 常用判断语句
      • 流程控制
        • if语句
        • case语句
        • while循环
      • read读取控制台输入
      • 函数
        • 系统函数
          • 1. basename
          • 2. dirname
        • 自定义函数
    • Shell示例

Shell概述

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。也就是说,它起到的是一个翻译的作用。一文掌握Shell_第1张图片
Shell还是一个功能强大的编程语言,易编写、调试,灵活性强。

脚本的常用执行方式

  1. sh + 脚本路径

    sh 脚本路径
    
  2. bash + 脚本路径

    bash 脚本路径
    
  3. 直接使用脚本的路径

    脚本路径
    

    但是这样可能会遇到一些问题:

    终端显示:没有权限执行。我们详细看看这个脚本的权限:在这里插入图片描述

    根据我们的Linux基础知识可以发现,这个文件是没有”x“权限的,而”x“权限就是程序运行权限,因此,我们只需给这个文件加上运行权限即可

    chmod +x 脚本路径
    

注意事项:上面的1、2、3种执行Shell的方式,本质上都是打开了一个子Bash执行,当前的Bash不会受影响,除了source启动

source 脚本路径

source是Bash内置的一个命令,效果等同于”.“。

Linux中的sh解释器

在一个Linux中有多个sh解释器,它们的名字存储在etc下的shells文件中,我们可以使用命令查看:

cat /etc/shells

我们可以看到类似以下的打印内容:
一文掌握Shell_第2张图片
这其中的每一个都是一个解释器。

Linux中的/etc

在Linux系统中,/etc文件夹用于存储系统的配置文件和目录,它包含了多个应用程序和系统组件的配置文件,用于定义系统和软件的行为:一文掌握Shell_第3张图片

这个目录中的东西我们是不能随意修改的。

编写sh脚本

第一个sh脚本

按照惯例,我们每一门编程语言的第一个程序都是输出一行”hello world“,这里也不例外:

#!/bin/bash

echo hello world

看着这个代码,我们会发现并不陌生,因为代码的执行主体就是我们的echo命令,这是因为Linux的大部分命令(小部分命令可以直接与Linux系统内核进行沟通)本就是通过sh解释器进行了“翻译”之后才能够正常执行的。而我们的Shell编程也是使用sh解释器进行解释,即:Shell 编程是通过将多个 Linux 命令组合在一起来创建脚本或程序的过程
除了echo指令外,还有一行代码:

#!/bin/bash

在Shell中,“#”是用作注释的符号,但这里是”#!“,它是hashbangshebang的符号,用于指定脚本执行时使用的解释器
在本例中,我们指定需要/bin/bash作为本脚本的解释器。这行代码不是必须的,如果我们没有使用hashbang来指定解释器,系统就会使用默认的sh解释器来解释该脚本

变量

Shell中的变量可以分为两类:系统预定义变量自定义变量
Shell中的变量也有全局变量局部变量之分。全局变量在所有Bash进程中都有效,局部变量仅在当前Bash进程中有效。
在子Bash中,对变量做任何更改都不会影响父Bash

1. 系统预定义变量
  • 常用系统变量:$HOME、$PWD、$SHELL、$USER等等。
  • 使用set可以显示当前Shell中的所有变量,包括全局变量和局部变量
2. 自定义变量
  • 基本语法:
    变量名=
    注意:“=”前后不能有空格
  • 撤销变量:
    unset 变量名
    
  • 声明静态变量(只读变量):
    readonly 变量名
    
    注意:静态变量不能unset
  • 将自定义变量导出为环境变量:
    export 变量名
    
3. 变量定义规则
  1. 变量名称可以由字母、数字和下划线组成,但是不能能以数字开头,环境变量名建议大写
  2. 等号两侧不能有空格
  3. 在Bash中,变量默认类型都是字符串类型,无法直接进行数值运算
  4. 变量的值如果有空格,需要使用双引号或单引号包裹起来
单引号和双引号的区别

在Shell中,单引号和双引号有着不同的作用

  1. 双引号(“”):
    • 双引号允许在字符串中使用变量,并会对变量进行扩展。比如,$var会被展开为对应变量的值
    • 双引号内部可以使用转义字符,比如\n表示换行符,\"表示双引号本身
    • 双引号内部的特殊字符会被解释和展开,比如命令替换($(command)或 `command)、参数替换($((expression))或$[expression]、$variable等)
    • 双引号不会对特殊字符作为字面量值进行转义
  2. 单引号(‘’):
    • 单引号将字符串视为字面量,不会对其中的内容作任何扩展或解释。内容会被原样输出
    • 单引号适用于在字符串中包含特殊字符或避免变量扩展的场景
4. 特殊变量
  1. $n:n为数字,代表参数名称,$0为运行脚本时使用的脚本路径,0~99为运行脚本时传入的参数
  2. $#:获取输入参数的个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性
  3. $*:它代表命令行中的所有参数,将所有的参数看作一个整体
  4. $@:也代表命令行中的所有参数,不同的是,它会将参数区分对待
  5. $?:表示最后一次执行的命令的返回状态,如果这个变量的值为0,证明上一个命令正确执行;如果这个变量非0(具体是哪个数,由执行的命令确定),则证明上一个命令执行不正确

运算符

在Shell中,我们不能直接进行数学运算:

# 计算1+2的值
echo $((1+2))
echo $[1+2]

这两种表达方式都是一样的,在Shell中,所有的数学计算都是这样,只需要注意包裹一下就好了,其他的跟别的语言没什么区别。
若是我们想使用运算对变量赋值,就不一样了,需要使用双引号包裹起来:

temp="$((1*5))"
echo $temp

命令替换

在Shell中,还有命令替换,跟上面说过的运算符有点像:

$()

其实命令替换运算符有很多种,这个只是其中一种,它更简洁、常用。

条件判断

条件判断就是一般编程语言中的if语句

test condition
[ condition ]

后者需要注意:condition前后需要有空格,并且条件非空即为true

常用判断语句
  1. 两个整数之间的比较:

    -eq 等于(equal)
    -ne 不等于(not equal)
    -lt 小于(less than)
    -le 小于等于(less equal)
    -gt 大于(greater than)
    -ge 大于等于(greater equal)
    
  2. 按照文件权限进行判断:

    -r 有读权限(read)
    -w 有写权限(write)
    -x 有执行权限(execute)
    
  3. 按照文件类型进行判断:

    -e 文件存在(existence)
    -f 文件存在并且是一个常规的文件(file)
    -d 文件存在并且是一个目录(directory)
    

流程控制

if语句

在Shell中,每种括号都是有用的,因此,Shell中不使用花括号包裹执行程序:

  • 单分支:
    if [ ]
    then
    	执行程序
    fi
    
  • 多分支:
    if [ ]
    then
    	执行程序
    elif
    then
    	执行程序
    fi
    

需要注意:除了else,其他的语句之后都需要使用then

case语句

跟其它编程语言一样,它是用于处理多分支语句的:

case $变量名 in
"值1")
	如果符合这个,则执行这段程序
;; # 必须以两个分号结尾
"值2")
	如果符合这个,则执行这段程序
;;
	...
*)
	如果都不符合,就执行这个
;;
esac
while循环
while [ condition ]
do
	执行程序
done

read读取控制台输入

read是Linux内置的命令,而不是Shell提供的:

read (选项) (参数)
  • 选项,这里我们讲两个最常用的选项:
    • -p(prompt):指定读取值时的提示符
    • -t(time):指定读取值时等待的时间(秒),若是不加-t,则会一直等待
  • 参数:
    • 变量:指定读取值的变量名

函数

函数也一样分为两种:系统函数自定义函数

系统函数

以下两个函数都是属于Linux系统提供的函数,在某些类Unix系统中可能也能使用。这两个函数本质上都是做的字符串操作。

1. basename
basename [string/pathname] suffix]

这个函数会删除所有前缀包括最后一个”/",然后将字符串显示出来;suffix后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

2. dirname
dirname 文件绝对路径

会从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录部分)。

自定义函数
[ function ] funcname[()]
{
	执行程序
	[return int;]
}

调用这个函数的时候”()“中的参数列表可有可无,调用参数采用$1,$2等。
函数的返回值只能通过$?进行获取,return也是可有可无的,若是没有,将会以最后一条语句的执行情况作为返回值,return的数字也有要求:0~255。

Shell示例

接下来给出一个示例,涵盖了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 "函数的返回值为$?"

你可能感兴趣的:(Linux,服务器,linux)