目录

  1. 1. 前言
  2. 2. Hello World
  3. 3. 变量
    1. 3.1. 使用变量
    2. 3.2. 只读变量
    3. 3.3. 删除变量
    4. 3.4. 变量类型
    5. 3.5. shell字符串
      1. 3.5.1. 单引号
      2. 3.5.2. 双引号
      3. 3.5.3. 拼接字符串
      4. 3.5.4. 获取字符串长度
      5. 3.5.5. 提取子字符串
      6. 3.5.6. 查找子字符串
    6. 3.6. shell数组
      1. 3.6.1. bash数组
      2. 3.6.2. sh数组
    7. 3.7. 注释
  4. 4. 传递参数
  5. 5. 运算符
    1. 5.1. 算术运算符
    2. 5.2. 关系运算符
    3. 5.3. 布尔运算符
    4. 5.4. 逻辑运算符

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

shell脚本语法

2024/4/25 Basic
  |     |   总文章阅读量:

前言

因为有写脚本的需求于是学了一下

不出意外的话都会用sh语法

参考:

https://www.runoob.com/linux/linux-shell.html


Hello World

#!/bin/sh
echo "Hello World !"

#!是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell

运行shell脚本:

  1. 作为可执行程序:

    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本
  2. 作为解释器参数:即直接运行解释器

    /bin/sh test.sh
    /bin/php test.php

变量

在 Shell 编程中,变量是用于存储数据值的名称

your_name="runoob"

注意:变量名和等号之间不能有空格

遵循以下规则:

  • 只包含字母、数字和下划线: 变量名可以包含字母(大小写敏感)、数字和下划线 _,不能包含其他特殊字符。
  • 不能以数字开头: 变量名不能以数字开头,但可以包含数字。
  • 避免使用 Shell 关键字: 不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
  • 使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母,例如 PI=3.14。
  • 避免使用特殊符号: 尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。
  • 避免使用空格: 变量名中不应该包含空格,因为空格通常用于分隔命令和参数。
RUNOOB="www.runoob.com"
LD_LIBRARY_PATH="/bin/"
_var="123"
var2="abc"

除了显式地直接赋值,还可以用语句给变量赋值,如:

for file in `ls /etc`for file in $(ls /etc)

以上语句会将 /etc 下目录的文件名循环出来


使用变量

$

your_name="0w0"
echo $your_name
echo ${your_name}

加花括号只是为了帮助解释器识别变量的边界,如下,识别的就不是 skillScript 而是 skill

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变

#!/bin/sh

myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"

image-20240425152511216

删除变量

#!/bin/sh

myUrl="https://www.runoob.com"
unset myUrl
echo $myUrl	# 无输出

变量类型

字符串变量:

my_string='Hello, World!'
或者
my_string="Hello, World!"

整数变量:在一些Shell中,你可以使用 declaretypeset 命令来声明整数变量

declare -i my_integer=42

如果尝试将非整数值赋给它,Shell会尝试将其转换为整数(有的shell会报错)

数组变量:

my_array=(1 2 3 4 5)

关联数组:

declare -A associative_array
associative_array["name"]="John"
associative_array["age"]=30

环境变量:

echo $PATH	# 操作系统搜索可执行文件的路径

特殊变量:

$0	# 脚本的名称
$1,$2	# 脚本的参数
$#	# 传递给脚本的参数
$?	# 表示上一个命令的退出状态

shell字符串

单引号

限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字符串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用

双引号

your_name="runoob"
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str

输出:Hello, I know you are "runoob"!

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

这里感觉和其他语言差不多

拼接字符串

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1

# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'	# 无法拼接
echo $greeting_2  $greeting_3

输出:

hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !

获取字符串长度

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

变量为字符串时,${ # string} 等价于 ${ # string[0]}

提取子字符串

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

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

查找子字符串

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

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

shell数组

bash数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小

bash的写法如下:

array_name=(value0 value1 value2 value3)
或
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

读取数组:

${数组名[下标]}

获取数组长度:

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}

使用@*可以获取数组中的所有元素

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com

my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D

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

sh数组

而sh的写法比较复杂:

  1. 可以用set命令和位置参数来模拟数组
# 定义数组
set 'word 1' word2 word3

# 输出数组的第一个元素
echo $1

# 输出数组的第二个元素
echo $2

# 输出数组的第三个元素
echo $3

# 输出数组的所有元素
echo $*
echo $@

# 向数组中增加一个元素
set -- "$@" word4
echo $4

# 查看数组元素的个数
echo $#

# 遍历数组元素
for i in do "$@"; do
  echo "$i"
done

# 从数组中删除一个元素
shift
echo $@

# 删除数组的所有元素
set x; shift
  1. 也可以用eval命令来模拟数组
#!/bin/sh
eval a1=word1
eval a2=word2
eval a3=word3
for i in 1 2 3; do
  eval echo "The $i element of array is: \$a$i"
done

注释

单行注释:#

多行注释:

:<<EOF
注释内容...
注释内容...
注释内容...
EOF

或者

: '
这是注释的部分。
可以有多行内容。
'

传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为 $n,n为几就是第几个参数,$0是执行的文件名

一些特殊参数:

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 如”$*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ $*相同,但是使用时加引号,并在引号中返回每个参数。 如”$@”用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

$*$@ 区别:

  • 相同点:都是引用所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,则 “ * “ 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com

echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done

输出:

$ chmod +x test.sh 
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3

运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awkexpr

#!/bin/sh

val=`expr 2 + 2`
echo "两数之和为 : $val"

注意:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2

算术运算符

#!/bin/sh
a=10
b=20

val=`expr $a + $b`
echo "a + b : $val"

val=`expr $a - $b`
echo "a - b : $val"

val=`expr $a \* $b`
echo "a * b : $val"

val=`expr $b / $a`
echo "b / a : $val"

val=`expr $b % $a`
echo "b % a : $val"

if [ $a == $b ]
then
   echo "a 等于 b"
fi
if [ $a != $b ]
then
   echo "a 不等于 b"
fi

注意:

条件表达式要放在方括号之间,并且要有空格

乘号*前边必须加反斜杠\才能实现乘法运算

关系运算符

假定变量 a 为 10,变量 b 为 20

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"
fi

布尔运算符

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ]返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi

逻辑运算符

运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR `[[ $a -lt 100