一起来学linux:shell script(一)关于变量
(一)首先来看什么是变量,在shell中打印出变量采用的是echo $path或者echo ${path}的方式
比如打印出当前系统路径变量就采用echo $PATH的方式
root@zhf-linux:/home/zhf# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
那么如何设置和修改变量呢?比如echo $myname得到的结果是空值。按照如下方式进行复制即可
root@zhf-linux:/home/zhf# myname=zhf
root@zhf-linux:/home/zhf# echo $myname
zhf
其中变量赋值有几点需要注意;
1 =两边不能直接接空格符。比如下面的这种形式就会报错。有了空格后,空格后的zhf就被当做了命令而不是变量
root@zhf-linux:/home/zhf# myname=chengdu zhf
No command 'zhf' found, did you mean:
Command 'zhm' from package 'zephyr-clients' (universe)
Command 'zmf' from package 'zoneminder' (universe)
Command 'zf' from package 'zend-framework-bin' (universe)
zhf: command not found
2 变量的开头不能是数字,必须是字母。下面的赋值就是错误的
root@zhf-linux:/home/zhf# 1myname=zhf
1myname=zhf: command not found
3 在第一点中说到不能有空格符,但是如果确实有空格符可以用双引号或者单引号将变量内容结合起来
root@zhf-linux:/home/zhf# myname="chengdu zhf"
root@zhf-linux:/home/zhf# echo $myname
chengdu zhf
但是有一种情况需要注意,那就是双引号或者单引号里面有$字符的时候。首先讲下$在赋值的时候的作用。如果我们想把一个变量赋值给另外一个变量,就要采用$的方式。比如我想将PATH的内容赋值给myname
root@zhf-linux:/home/zhf# myname=$PATH
root@zhf-linux:/home/zhf# echo $myname
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
如果$出现在双引号中,可以保持原本的特性。也就是说$在双引号中还是代表一个变量的意思
root@zhf-linux:/home/zhf# myname="chengdu $PATH"
root@zhf-linux:/home/zhf# echo $myname
chengdu /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
但是如果$出现在单引号中,那么$就只能代表一般字符的意思,不能代表变量了。
root@zhf-linux:/home/zhf# myname='chengdu $PATH'
root@zhf-linux:/home/zhf# echo $myname
chengdu $PATH
4 如果想将变量变成系统变量,通过export的方式
5 $本身也是变量。这个代表的是这个shell的线程代号。也就是PID(procedd id). Echo $$的时候就会出现当前的PID号码
root@zhf-linux:/home/zhf# echo $$
3157
6 ?代表的是上次shell命令的执行结果,如果命令执行成功,则返回0,否则返回非0,也就是具体的错误码
root@zhf-linux:/home/zhf# myname=chengdu zhf
No command 'zhf' found, did you mean:
Command 'zf' from package 'zend-framework-bin' (universe)
Command 'zhm' from package 'zephyr-clients' (universe)
Command 'zmf' from package 'zoneminder' (universe)
zhf: command not found
root@zhf-linux:/home/zhf# echo $?
127
(二)下面来看下环境变量和自定义变量。有些书上也称为全局变量和局部变量。
当登录Linux并取得一个bash之后,你的bash就是一个独立的进程,接下来你在这个bash下执行的任何命令都是由这个bash衍生出来的。这些命令就被称为子进程。子进程可以继承父进程的环境变量,不会继承父进程的自定义变量。
那么也就是说环境变量是给所有子进程共享的,而自定义变量只是当前进程可以获取。要想将自定义变狼转换程环境变量。就要用到export命令。 我们来看一个具体的例子。
(1) 首先定义一个变量name=’zhf’
root@zhf-linux:/home/zhf/zhf/shell_prj# name="zhf"
root@zhf-linux:/home/zhf/zhf/shell_prj# echo $name
zhf
(2)然后创建一个sh文件,里面就一条命令echo $name。执行sh.test.sh的时候得不到任何值
root@zhf-linux:/home/zhf/zhf/shell_prj# sh test1.sh
(3) 用export命令将name转变成环境变量。并在export中查看 可以看到 declare -x name=”zhf”
declare是申明变量用的,-x的作用和export一样
root@zhf-linux:/home/zhf/zhf/shell_prj# export name
root@zhf-linux:/home/zhf/zhf/shell_prj# export | grep 'name'
declare -x name="zhf"
(4)再次执行sh test1.sh. 打印出了name的名字
root@zhf-linux:/home/zhf/zhf/shell_prj# sh test1.sh
zhf
在整个执行过程中,sh test1.sh就是当前bash的子进程。当name是自定义变量的时候,test1.sh中是获取不了name的。只有在export name后。子进程test1.sh才能获取到。
同样的还可以运用到sh文件中去,test1.sh中的代码如下:
name=”zhf”
export name
sh test2.sh
test2.sh的代码如下:
echo $name
如果在test1.sh中没有export name,那么在test2.sh中就无法访问到这个变量。
(三)变量的读取和申明。
在对变量赋值的时候,我们经常通过键盘输入的方式进行读取。要读取来自键盘的命令,就要用到read整个命令。
-p: 后面接提示符
-t:后面可以接秒数,不会一直等待客户
root@zhf-linux:/home/zhf/zhf/shell_prj# read -p "please input your name:"
please input your name:zhf
我们知道在程序中变量也是有类型的,比如数组,整型,只读等等。什么能够变量的类型就要用到declare命令:
-a: 定义为数组类型
-i:定义为整数类型
-x:用法和export一样,将variable变成环境变量
-r:定义位只读类型,内容不可以更改
我们来看下使用的例子,在这里定义sum=100+200+300在这里我们期望得到600,但是结果却是100+200+300
root@zhf-linux:/home/zhf/zhf/shell_prj# sum=100+200+300
root@zhf-linux:/home/zhf/zhf/shell_prj# echo $sum
100+200+300
原因在于没有定义sum的类型。变量的默认类型位字符类型。当我们申明类型后就可以得到600了。
root@zhf-linux:/home/zhf/zhf/shell_prj# declare -i sum
root@zhf-linux:/home/zhf/zhf/shell_prj# sum=100+200+300
root@zhf-linux:/home/zhf/zhf/shell_prj# echo $sum
600
申明为只读类型的时候,是无法更改的
root@zhf-linux:/home/zhf/zhf/shell_prj# declare -r sum1
root@zhf-linux:/home/zhf/zhf/shell_prj# sum1=100
bash: sum1: readonly variable
同时也无法删除只读变量,只有在注销bash的时候才能删除,因此定义只读变量需谨慎
root@zhf-linux:/home/zhf/zhf/shell_prj# unset sum1
bash: unset: sum1: cannot unset: readonly variable
申明为数组的情况,注意在访问具体的数组元素的时候用的${sum2[1]}
root@zhf-linux:/home/zhf/zhf/shell_prj# declare -a sum2
root@zhf-linux:/home/zhf/zhf/shell_prj# sum2[1]=zhf
root@zhf-linux:/home/zhf/zhf/shell_prj# sum2[2]=zhf1
root@zhf-linux:/home/zhf/zhf/shell_prj# echo ${sum2[1]}
zhf
(四)变量内容的删除,替代与替换
我们用一个比较长的变量PATH来进行测试。首先将PATH赋值给path。
root@zhf-linux:/home/zhf# echo $path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
在path中有这么多的路径,如果我想将从开始到/local/bin结尾的变量都删除,该如何操作呢。操作如下
root@zhf-linux:/home/zhf# echo ${path#/*local/bin:}
/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
如果我只想保留最后一个/usr/local/games,可以像下面这样操作。
root@zhf-linux:/home/zhf# echo ${path##/*:}
/usr/local/games
前面的#以及##都是从前往后删除,如果想从后往前删除,就要采用如下的方式:
root@zhf-linux:/home/zhf# echo ${path%:*games}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
删除掉最长的:
root@zhf-linux:/home/zhf# echo ${path%%:*games}
/usr/local/sbin
字符的替换采用如下的方式:单个替换
root@zhf-linux:/home/zhf# echo ${path/sbin/bisan}
/usr/local/bisan:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
全部替换
root@zhf-linux:/home/zhf# echo ${path//sbin/bisan}
/usr/local/bisan:/usr/local/bin:/usr/bisan:/usr/bin:/bisan:/bin:/usr/games:/usr/local/games
几种方式都介绍完了,下面来总结下
${变量#关键字} 若变量从头开始的数据符合关键字,则将符合的最短数据删除
${变量##关键字} 若变量从头开始的数据符合关键字,则将符合的最长数据删除
${变量%关键字} 若变量从尾向前的数据符合关键字,则将符合的最短数据删除
${变量%%关键字} 若变量从尾向前的数据符合关键字,则将符合的最长数据删除
${变量/旧字符串/新字符串}若变量符合旧字符串,则替换第一个旧字符串
${变量//旧字符串/新字符串} 若变量符合旧字符串,则替换全部旧字符串
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架