Shell脚本学习
admin
2024-01-20 15:12:42
0

一、介绍

shell是一个用C语言编写的程序,是使用Liunx的桥梁。shel既是一种命令语言,又是一种设计语言,它提供一个界面(小黑屏),用户通过这个界面访问操作系统内核的服务。

在我们通常说的shell一般说的是shell script(shell脚本)。但学习者还是需要知道shell 和shell script两者是不同的概念。由于习惯问题,所以shell都是指shell脚本编写。

shell编程和JavaScript、PHP一样,除了文本编辑外就只需要一个能解释执行的脚本解释器就可以了。Linux的shell种类有很多,常见的有

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)

二、初识Shell脚本

shell脚本扩展名为sh,但实际扩展名并不影响脚本执行,见名知意就好。

#!/bin/bash
echo "Hello World !"
  • 文件开头说明

    #! 是shell的约定标记,它告诉系统这个脚本需要什么解释器执行,#!/bin/bash 代表Bash方式执行。

  • 授权为可执行程序

    chmod +x ./test.sh  #使脚本具有执行权限
    
  • 执行

    ./test.sh # 或者指定解释器运行,这种方式不需要在第一行指定解释器信息,指定了也没用。
    /bin/sh ./test.sh
    

三、shell变量

3.1、声明变量

test_name="xiaoMing"

变量名和等号之间不能有空格。

  • 直接声明变量名,不用加其他符号
  • 变量名只能使用英文、数字和下划线,且不能以数字开头

3.2、使用变量

test_name="xiaoMing"
echo $your_name
# 推荐使用这个
echo ${your_name}

加大括号可以帮助解释器识别变量边界,所以推荐所有变量名都加上大括号,这是个编程的好习惯

3.3、设置只读变量

test_name="xiaoMing"
readonly  $your_name

如果将变量设置为只读,后面重新赋值,在运行时就是执行报错: /bin/sh: NAME: This variable is read only.

3.4、删除变量

unset variable_name

3.5、变量类型

运行shell时,会同事存在三种变量

  • 局部变量

    局部变量在脚本或者命令中定义,仅在当前shell实例中有效

  • 环境变量

    所有的程序,包含shell启动的程序,都能访问的环境变量

  • shell变量

    shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

四、Shell字符

4.1、单引号

str='123'

单引号里不能引用变量名,除非单引号里再嵌套个单引号里引用变量。并且不是出现一个单引号,除非成对出现,作为字符串拼接

4.2、双引号

hi="Hello World"
name="${hi} shenyao"
echo ${name}

使用双引号的优点

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

4.3、拼接字符

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"# 使用单引号拼接
greeting_2='hello, '$your_name' !'

4.4、获取字符长度

string="abcd"
echo ${#string}   # 输出 4

4.5、截取字符

name="123";
name2=${name:0:2} //12
  • 截取字符,一个是从哪个开始截取,第二个数代表要截取多少个

五、数组

shell数组支持一维数组,并且没有限制数组的大小,可以通过索引访问元素。

5.1、数组定义

  • 直接声明

    array_name=(value0 value1 value2 )array_name=('111' '2222 22' '3333')
    
  • 换行

    array_name=(
    value0
    value1
    value2
    )
    
  • 可以单独定义各个值

    array_name[0]=value0
    array_name[1]=value2
    
  • 不仅可以使用索引赋值,也可以用任意字符来关联元素

    首先使用declare 关键字声明为关联数组

    declare -A array_namearray_name["google"]="www.google.com"
    array_name["runoob"]="www.runoob.com"
    array_name["taobao"]="www.taobao.com"
    

5.2、读取数组

${数组名[索引下标]}value=${array_name[0]}#@符号获取所有元素
values=${array_name[@]}

5.3、获取数组长度

获取字符串长度时使用${#string} ,数组长度也类似使用#

length=${#array_name[@]}
#或者
length=${#array_name[*]}

六、传递参数

在运行shell脚本时,有时我们需要在执行脚本时传递参数。脚本内获取参数的格式为:$n。n代表一个数字,其中$0代表里执行的文件名,从1开始才是真正传的参数,$1代表第一个传递的参数,$2代表第二个传递的参数

例如

#执行脚本
./test.sh 1 2 3# 脚本内容
#!/bin/bas
echo "shell 传递参数示例开始"
# 执行的文件名
echo "执行的文件名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"shell 传递参数示例开始
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2

其他引用列表

参数说明
$#传递参数的个数
$*传递的所有参数
$$脚本运行的当前进程ID号
$@$*相同,但是传参的时候需要使用引号括起来,否则它就当成一个参数

七、基本运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如:awk,expr,let最常用。

val=`expr 2 + 2`

注意
1、表达式何运算符质检要有空格,例如2+2是不对,要 2 + 2,

2、表达式要用``包裹起来,

let s=(2+4)*4

注意

1、运算符和参数之间不能有空格
2、与expr对比,let命令更简洁直观
3、let使用位操作符<< >>&需要用\ 来转义

7.1、算术运算符

运算符说明
+加法
-减法
*乘法
/除法
%取余
=赋值
==判断相等,用于比较两个数字,相同返回true。只能用于数字类型且在if判断中使用
!=判断不相等,不相同则返回 true。

7.2、关系运算符

该运算符只支持数字

运算符说明
-eq检查两个数是否相等
-ne不相等
-gt大于
-lt小于
-ge大于等于
-le小于等于

7.3、布尔运算符

运算符说明
!非运算,取反的作用
-o或运算,相当于`
-a且运算,相当于&,两个表达式为true才返回true

7.4、逻辑运算符

运算符说明
&&and
||OR

7.5、字符串运算符

运算符说明
=两个字符串是否相等
!=是否不相等
-z长度是否为0
-n长度是否不为0
$是否不为空

7.6、文件测试运算符

操作符说明
-d file文件是否是目录
-r file是否可读
-w file是否可写
-x file是否可执行
-s file是否为空
-e file文件(包含目录)存在

八、echo命令

echo是一个输出命令,格式如下

echo string

获取控制台输入

read name
echo "${name} 你好"

执行后脚本,name变量作为控制台输入的变量

./test.sh
xiaoMing   #控制台输入
xiaoMing 你好  #输出

九、printf

printf和echo都是输出命令,但printf的脚本比echo移植性高。比如可以传参数

示例

printf "你好吗? %s \n" 小明#打印出来就是
你好吗? 小明
  • 格式化输出

    printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
    
    符号说明
    %s替换符,s声明是字符串的意思
    %-10s指定一个宽度为10个字符,-表示左对齐,没有则右对齐。不满10字符会自动空格值填充,超过也全部显示
    %c%c是输出一个字符
    %f数字类型
    %-5.3f数字类型,占5个字符,超过也展示,保留3位小数

十、流程控制

if判断里可以用[...]((...))。 使用[...] 判断大小用-gt-lt ,使用((...))可以用><

10.1、if

if [条件]
then满足后执行命令
fi

10.2、if…then…else

if [条件]
thenecho '两个数字相等!'
elseecho '两个数字不相等!'
fi

10.3、if…then…elif…

if [条件1]
then满足条件1执行
elif [ 条件2 ]
then满足条件2执行
else都不满足执行
fi

10.4、for循环

  • for in 类型

    for loop in 1 2 3 4 5
    doecho "The value is: ${loop}"
    done
    
    array_name=('一' '二' '三')
    for var in ${array_name[*]}
    doecho "值为: ${var}"
    done
    
  • for i 类型

    fori 模式和其他编程语法差不多

      
    array_name=('一' '二' '三')
    for(( i=0;i<${#array_name[*]}; i++ ))
    doecho "值为: ${array_name[i]}"
    done
    

10.5、while

while [条件]
do执行命令
done

示例

#!/bin/basharray_name=('一' '二' '三')
num=${#array_name[*]}echo "长度为--> ${num}"
while [ ${num} -ge 0 ]
doecho "该值为:${array_name[${num}]}"let "num--"
done

相关内容

热门资讯

【IPO追踪】零成交常态化,解... 港股市场最尴尬的处境,莫过于股价跌跌不休,连交易都无人问津。6月24日,美联股份(02671.HK)...
SK海力士冲刺美国上市,ADR... 若顺利完成,相关交易最快有望于下个月启动,并成为韩国企业历史上规模最大的海外股权融资项目之一。 人工...
伯恩斯坦:锂价上行周期远未结束... 6月23日消息,伯恩斯坦最新研报中上调锂价预测,并将 天齐锂业(002466.SZ)A股目标价从73...
原创 全... 中国与印度尼西亚之间,正在上演一场围绕镍矿资源的激烈博弈。令人颇感意外的是,这场博弈的主动挑起者竟然...
企业出海ESG合规与可持续发展... 中新网北京6月24日电 (记者 尹倩芸)2026年北京市“走出去”系列活动——企业出海ESG合规与可...
原创 中... 聊到现在的楼市,身边人想法差得挺远。有人还在等跌,觉得再观望一阵更稳妥。也有人盯上了官方最近放的几个...
企业微信Agent内测悄启 主... 继微信AI助手开启内测后,企业微信紧跟步伐开启了AI助手的内测,但跟微信嵌入的不是同一个Agent。...
马斯克官宣Starmind太空... IT之家 6 月 24 日消息,埃隆 · 马斯克(Elon Musk)今天(6 月 24 日)在 X...
5000亿市值巨头,盘中涨停 6月24日午后,立讯精密股价直线拉升,盘中触及涨停后开板。截至发稿,该股报75.39元/股,涨8.6...
中兴通讯爱理财?额度2年翻倍至... 图片来源:图虫创意 钱的流向,往往折射出一家企业的战略重心。 6月17日,中兴通讯在深圳召开股东大会...
中国掌控全球过半铜冶炼产能,美... 【文/观察者网 王恺雯】 面对中国在铜冶炼和精炼上的主导地位,美国试图通过关税及工业政策复兴国内铜产...
年内92宗IPO获受理 创业板... 来源:滚动播报 (来源:北京商报) 随着创业板深化改革持续推进,今年创业板IPO申报热度攀升,替代北...
SpaceX跌破IPO首日开盘... 来源:滚动播报 来源:中国基金报 【导读】SpaceX股价连续重挫 中国基金报记者 张舟 Space...
酒庄头条:在郎酒庄园,看见世界... 文/酒庄头条 中国酒业该向何处去?又如何走向国际市场?酿酒业是有根产业历史经典产业,郎酒以全球视野开...
100个选基指标|利润总额,真... 推荐阅读: 100个选基指标丨自然年度收益率,最简单,也最重要(第一期) 100个选基指标丨区间收益...
连云港开发区为AI“制药”按下... 从人才赋能、校地协同到产业落地,今年以来,连云港开发区通过一系列密集举措构建起全链条、立体化的产业赋...
1.08亿控股德维嘉:无锡振华... 一家传统汽车冲压件上市公司,正试图用一笔亿元级别的现金收购,为自己贴上“汽车智能化”的标签。 6月2...
ATFX:SpaceX下跌16... 来源:市场资讯 6月23日,ATFX汇评:美国航空航天代表性个股SpaceX,上市六个交易日,三个交...
嘉实基金李涛:长期视角决策未来... 嘉实成长共赢混合基金经理李涛表示, 投资理财本质上是一场长期主义的远行,权益投资本质是追求赚取产业与...
震裕科技可转债发行申请获深交所... 雷达财经 文|苏静 编|深海 6月23日, 震裕科技(300953)发布关于公司向不特定对象发行可转...