【Linux篇】Shell脚本语法< 1 >

简介: 在安卓源码里,离不开两个东西,一个就是.sh文件,还有一个就是.mk文件。这两个文件各持有一个语法,一个是Makefile语法,一个是Shell脚本语法。这两个是真的让我头疼,就像看天书一样,呜呜呜。

前言


在安卓源码里,离不开两个东西,一个就是.sh文件,还有一个就是.mk文件。


这两个文件各持有一个语法,一个是Makefile语法,一个是Shell脚本语法。


这两个是真的让我头疼,就像看天书一样,呜呜呜。



1、变量


完整的变量打印:

name="乌鸡哥"
echo ${name}


简写:

name="乌鸡哥"
echo $name


乌鸡哥


实例:

bd7d62e294094b5b9d642aa8637bf748.png


一开始没有namess这个变量,所以没有输出。


后来我添加了,就有输出了。


最后我删除了变量namess,又没有输出了。



1)变量输出长度

name="乌鸡哥"
echo ${#name}


4



2)提取子字符串


以下实例从字符串第 2 个字符开始截取 4 个字符:

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo


注意:第一个字符的索引值为 0。



3)查找子字符串


查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4


注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。


4)单引号和双引号的区别


在 shell 脚本中,echo命令用于输出字符串或者变量的值。在使用echo命令时,可以使用反引号、单引号或双引号来包围要输出的内容。


你们猜猜下面打印结果是什么?

name="乌鸡哥"
name2='${name}'
name3="${name}"
...
echo $name
echo $name2


结果如下:


乌鸡哥

${name}

乌鸡哥


1.反引号(``):反引号用于将要执行的命令包围起来,并将命令的输出作为参数传递给 echo 命令。例如:

echo "Today is `date +%A`"


这个命令会将 date +%A 命令输出的结果插入到 echo 命令中进行输出。


2.单引号('):单引号用于将其中的内容视为字面值进行输出,不进行任何解释和替换。例如:

echo 'The value of $HOME is' $HOME


这个命令会输出 The value of $HOME is /home/user,其中 $HOME 被视为普通字符输出,而不会被解释为变量。


3.双引号("):双引号用于将其中的内容进行变量替换和转义解析等操作,并将其作为一个整体进行输出。例如:

name='John'
echo "Hello, $name!"


这个命令会输出 Hello, John!,其中 $name 会被自动替换为变量的值。


需要注意的是,在使用双引号和反引号时,如果其中包含特殊字符或者空格等不安全的字符,需要进行适当的转义处理,以避免出现意外的错误。


单引号变量,不识别特殊语法;

双引号变量,识别特殊符号。


5)特殊变量


查看上条命令是否执行成功。


●  $?


       ○  0:成功


       ○  1-255:错误码


实例:

6a2bb34f3f174fa6985f8f92c33837f6.png


另外,还有几个特殊字符用来处理参数(调用函数传参,命令行传参等…):


●  $*:以一个单字符串显示所有向脚本传递的参数。如∗用「“」括起来的情况、以”*用「“」括起来的情况、以”1 22…2 … n"的形式输出所有参数。


●  $@:与$*相同,但是使用时加引号,并在引号中返回每个参数。如@@用「“」括起来的情况、以”@用「“」括起来的情况、以”1" “2 " … " 2" … "2"…"n” 的形式输出所有参数。


●  $$:脚本运行的当前进程ID号


●  $!:后台运行的最后一个进程的ID号


●  $#:传递到脚本的参数个数


●  $-:显示Shell使用的当前选项,与set命令功能相同。


●  $?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。还有一个作用就是函数返回值在调用该函数后通过 $? 来获得


6)脚本里变量的赋值情况


1.每次调用bash/sh解释器,都会开启一个子shell,不保留当前的shell变量,通过pstree检查进程树。(用bash执行脚本里面的变量赋值不被保存)


2.source.是在当前shell环境加载脚本,因此保留变量。(用source执行脚本里面的变量赋值会被保存)


2dcdbee507474f3da5635716b684b2c8.jpg


7)变量存储命令的内容

name=ls
#显示ls
echo $name


name='ls'
#显示当前目录的文件
echo ${name}


8)环境变量


环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。


shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件。


某个远程登录用户专属配置文件(局部变量)


●  ~/.bash_profile(系统优先加载所有全局环境变量和 shell 函数)


●  ~/.bashrc (在 ~/.bash_profile中被加载,相当于套娃),用户在登录的时候会去加载~/.bash_profile~/.bashrc文件


所有用户共有(全局变量)

●  /etc/profile (系统优先加载)

●  /etc/bashrc ,且系统建议最好创建在 /etc/profile.d/,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户

在 Linux 和类 Unix 系统中,全局的 Bash Shell 配置数据通常被保存在 /etc/profile 与 /etc/bashrc 文件中。这些文件包含所有用户共享的系统级别的配置和环境变量信息。

当操作系统启动时,Bash Shell 会首先执行 /etc/profile 脚本以加载所有全局环境变量和 shell 函数。对于每个新的 Bash 终端窗口,系统还将自动执行 /etc/bashrc 文件中的某些特定配置命令。

在更推荐的做法是创建自己的配置脚本并将其存储在 /etc/profile.d/ 目录下。这样,管理员可以随意创建单独的配置文件来自定义系统级别的平台和服务特定参数,而不必修改 /etc/profile 或 /etc/bashrc 文件。

例如,可以为每个服务或应用程序创建单独的配置文件,并将其放置在 /etc/profile.d/ 目录中,该目录中的任何 .sh 文件都会被整合到系统全局的 Bash 环境中。最后,每次启动新的 Bash 终端窗口时,系统都会自动执行这些文件中包含的命令和设置环境变量,实现系统环境的自动化配置。

检查系统环境变量的命令

●  set:输出所有变量,包括全局变量、局部变量

●  env:只显示全局变量

●  declare:输出所有的变量,如同set

●  export:显示和设置环境变量值

撒销环境变量

●  unset+变量名,删除变量或函数

设置只读变量

●  readonly:只有shell结束,只读变量才失效

直接readonly 显示当前系统只读变量
[root@chaogelinux ~]# readonly name="超哥
[root@chaogelinux ~]# name="chaochao"
-bash: name: 只读变量


2、数组


支持一维数组(不支持多维数组),并且没有限定数组的大小,数组元素的下标由 0 开始编号。


1)定义数组


在 Shell 中,用括号来表示数组,初始化时不需要定义数组大小(与 PHP 类似),数组元素用"空格"符号分割开。定义数组的一般形式为:

数组名=(值1 值2 … 值n)

array_name=(A B "C" D)


还可以单独定义数组的各个分量

数组名[下标值]=变量值


array_name[0]=value0


2)读取数组


读取数组元素值的一般格式是:

# ${数组名[下标]}
valuen=${array_name[n]}


例如:

#使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}


#我们尝试打印一下数组元素。
array_name=(A B "C" D)
echo "第二个元素为: ${array_name[1]}"
echo "第三个元素为: ${array_name[2]}"


打印出来后你觉得加了双引号的会有区别吗?

答案是没有哦,打印出来都一样。


B

C



最后

#结合上述知识点
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}


3)关联数组


declare 是一个 shell 内置命令,在 Linux 和其他类 Unix 系统中都可以使用。它用于声明变量的类型和属性,以及定义函数等。下面是一些 declare 命令的常见用法:

1.声明普通变量

declare variable_name=value

这个命令将创建一个名为 variable_name 的变量,并将其初始化为指定的值。

2.声明只读变量

declare -r variable_name=value

这个命令将创建一个只读的名为 variable_name 的变量,并将其初始化为指定的值。只读变量的值不能被修改或重新赋值。

3.声明整数变量

declare -i variable_name=value

这个命令将创建一个名为 variable_name 的整型变量,并将其初始化为指定的值。如果后续对该变量进行了非整型的赋值操作,系统会尝试自动转换为整型。

4.声明数组变量

declare -a array_name

这个命令将创建一个名为 array_name 的数组变量。在后续的操作中,可以使用数组下标来访问和赋值数组元素。

5.声明关联数组变量

declare -A associative_array_name

这个命令将创建一个名为 associative_array_name 的关联数组变量。在后续的操作中,可以使用任意字符串作为数组下标来访问和赋值数组元素。

6.声明函数

declare -f function_name

这个命令将打印名为 function_name 的函数的定义。如果不加参数,则会列出所有已经定义的函数。

除了上述用法外,declare 命令还支持一些其他的选项和参数,可以通过 help declare 命令来查看它们的详细说明。

我们这里详细介绍第五点

在 Bash shell 中,关联数组(associative array)是一种特殊的数组类型,它使用任意字符串作为下标来访问和赋值数组元素。关联数组也被称为哈希表(hash table)、字典(dictionary)或映射(map)。

要声明一个关联数组变量,可以使用 declare 命令的 -A 选项,例如:

declare -A my_array

也可以这样直接定义:

declare -A my_array=(["name"]="John" ["age"]="30")

这里,我们使用关联数组下标 "name" "age" 来分别给数组元素赋值。

my_array["name"]="John"
my_array["age"]=30

在后续的操作中,可以使用任何字符串作为数组下标来访问和赋值数组元素,例如:

echo "My name is ${my_array["name"]} and I am ${my_array["age"]} years old."

打印数组的所有value:

# 两者等效
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"

数组的元素为: John 30

打印数组的所有key:

echo "数组的键为: ${!site[*]}"
echo "数组的键为: ${!site[@]}"

数组的键为: name age

打印数组的元素个数:

echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"

数组元素个数为: 2

需要注意的是,在关联数组中,每个元素都与一个独立的字符串键相关联。因此,在访问数组元素时,可以使用任何合法的字符串作为下标,包括空字符串、特殊字符和空格等。与普通数组不同,关联数组不需要事先指定数组的长度,也不需要在定义时初始化数组元素。



3、注释


# 别学习了 好好睡觉(单行注释)


# 多行注释(Here Document)
: <<END_COMMENT
注释内容...
注释内容...
注释内容...
END_COMMENT


# 举个栗子
# 这段代码先执行 Here Document (<<)语法结构,可以看成标准输入
# 将内容传递给 cat 命令作为标准输入
# 然后再将 cat 命令的输出结果重定向(>)到文件中
# 最终将字符串 "五级五级" 和 "66666666" 写入到 77.sh 文件中。
cat > device/$1/$2/vendorsetup.sh << EOF
echo "五级五级"
echo "66666666"
EOF

目录
相关文章
|
29天前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
70 1
|
15天前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
38 2
6种方法打造出色的Shell脚本
|
1天前
|
XML JSON 监控
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell脚本在系统管理和自动化任务中扮演着重要角色。尽管存在调试困难、可读性差等问题,但其简洁高效、易于学习和强大的功能使其在许多场景中不可或缺。通过掌握Shell脚本的基本语法、常用命令和函数,并了解其优缺点,开发者可以编写出高效的脚本来完成各种任务,提高工作效率。希望本文能为您在Shell脚本编写和应用中提供有价值的参考和指导。
9 1
|
6天前
|
Ubuntu Shell 开发工具
ubuntu/debian shell 脚本自动配置 gitea git 仓库
这是一个自动配置 Gitea Git 仓库的 Shell 脚本,支持 Ubuntu 20+ 和 Debian 12+ 系统。脚本会创建必要的目录、下载并安装 Gitea,创建 Gitea 用户和服务,确保 Gitea 在系统启动时自动运行。用户可以选择从官方或小绿叶技术博客下载安装包。
19 2
|
12天前
|
Ubuntu Linux Shell
Linux 系统中的代码类型或脚本类型内容
在 Linux 系统中,代码类型多样,包括 Shell 脚本、配置文件、网络配置、命令行工具和 Cron 定时任务。这些代码类型广泛应用于系统管理、自动化操作、网络配置和定期任务,掌握它们能显著提高系统管理和开发的效率。
|
1月前
|
Web App开发 网络协议 Linux
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
这篇文章是关于Linux命令的总结,涵盖了从基础操作到网络配置等多个方面的命令及其使用方法。
61 1
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
|
20天前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
41 6
|
16天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
34 1
|
1月前
|
存储 Shell Linux
【Linux】shell基础,shell脚本
Shell脚本是Linux系统管理和自动化任务的重要工具,掌握其基础及进阶用法能显著提升工作效率。从简单的命令序列到复杂的逻辑控制和功能封装,Shell脚本展现了强大的灵活性和实用性。不断实践和探索,将使您更加熟练地运用Shell脚本解决各种实际问题
23 0