#!/usr/bin/env bash
echo “hello shell”
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
Linux 的 Shell 种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
变量
不需要声明var ,$ 这种标识,直接声明即可,命名规范跟其他语言基本差不多
除了显式地直接赋值,还可以用语句给变量赋值,如:
for file inls /etc
或
for file in $(ls /etc)
以上语句将 /etc 下目录的文件名循环出来。
使用变量需要加 $,例如
name=“tutu”
echo $name
echo $
这里发现一个错误,name=“tutu”,这个变量赋值中间的 “=” 两边不能留空格,留空格就会报错,导致变量not found
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种拼接情况:
echo ${content}_id
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
sendlink = “https://baidu.com”
readonly $sendLink
sendLink = “https://google.cn”
删除变量
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
变量类型
运行shell时,会同时存在三种变量:
- 局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 - 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。 - shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
单双引号区别:类似php,单引号直接输出字符串,双引号里面可以解析变量。
username=“图图”
#str='引号字符串测试username"
echo $str
字符串长度
两种方式获取字符串长度
echo ${#str}
echo $
字符串截取
echo $
两个参数,第一个是开始位置下标,第二个是截取长度,跟golang几乎一样
expr
expr命令可以实现数值运算、数值或字符串比较、字符串匹配、字符串提取、字符串长度计算等功能。它还具有几个特殊功能,判断变量或参数是否为整数、是否为空、是否为0等。
声明测试字符串
#!/bin/bash
var1=www.baidu.com
- ‘match STRING REGEX’
等价于’STRING : REGEX’。匹配字符串默认是从^,即第一个字符开始匹配的。
expr "$var1" : 'ww.*'
# 输出:13
- ‘substr STRING POSITION LENGTH’
返回STRING字符串中从POSITION开始,长度最大为LENGTH的子串。如果POSITION或LENGTH为负数,0或非数值,则返回空字符串。通俗点就是截取字符串
expr substr "$var1" 5 5
# 输出:baidu
- ‘index STRING CHARSET’
CHARSET中任意单个字符在STRING中最前面的字符位置。如果在STRING中完全不存在CHARSET中的字符,则返回0。
expr index "$var1" dub
# 输出:5
- ‘length STRING’
返回STRING的字符长度。跟前文提到的${#var1}效果一致。
expr length "$var1"
# 输出:13
这里遇到一个大坑,我本地是MacOs ,执行expr 参数的时候提示:expr: syntax error,搜索了半天,全是linux相关的解决方法。最后怀疑是不是系统问题,将脚本提交云服务器以后测试发现运行成功。最后搜索mac expr关键字找到一下解释。
数组
定义数组的两种方式
array_name=(value0 value1 value2 value3)
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
取数组元素跟其他编程语言几乎没有区别
valuen=$
bash中支持关联数组,即golang中的map。shell中的数组跟php非常相似,只是没有多维数组。所有的数组都不需要定义长度
关联数组的定义方式
declare -A site=([“google”]=“www.google.com” [“runoob”]=“www.runoob.com” [“taobao”]=“www.taobao.com”)
declare -A site
site[“google”]=“www.google.com”
site[“runoob”]=“www.runoob.com”
site[“taobao”]=“www.taobao.com”
获取数组长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
注释
单行注释
# 这是单行注释
以下是多行注释的几种方式
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!
传参
shell脚本接收参数通过1~n变量顺序读取
#! /bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
其他参数
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与@“用「”」括起来的情况、以"$1" “n” 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
$* 与 $@ 区别:
- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
运算符
算术运算符跟其他语言几乎一致,唯一需要注意有些符号使用需要转义,略过
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 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。 |
布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。【&】 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符与其他语言完全一致,略过
字符运算符
运算符 | 说明 | 举例 |
---|---|---|
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
echo命令
输出字符串命令,跟php echo几乎没有区别。略过
echo -e "OK! \n" # -e 开启转义
printf命令
语法
printf format-string [arguments...]
跟golang中的fmt.sprintf()几乎一致,格式化输出,略过。
流程控制
分支语法
if condition
then
command1
command2
...
commandN
fi
shell中的流程控制不允许写空分支。
for循环语法
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while循环语法
while condition
do
command
done
引入文件
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh