Shell学习
前言
本文参考菜鸟教程-Shell 教程
可以在Linux中使用vi/vim创建文件 test.sh
基础学习
输出
#!/bin/bash
echo "Hello World!"
#!
是约定的标记,它告诉系统需要什么解释器来执行
运行方式
1.作为可执行程序
将上面的代码保存为 test.sh,并 cd 到相应目录:
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
2、作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
/bin/sh test.sh
/bin/php test.php
变量
命名:temp="123"
等号两边尽量不用空格;直接赋值即可,不需要设置数据类型
使用变量
需在变量前加美元符号 $
temp="test"
echo $test
一般情况下可以加 {}
来帮助解释器识别变量的边界
temp="Java"
echo "I am good at ${skill}Script"
只读变量
# 给变量定义readonly,其就不可以被再次更改
myUrl="https://romcere.top"
readonly myUrl
删除变量
# 使用unset可以删除变量,但不能删除`只读变量`
unset myUrl
变量类型
1.字符串变量
my_string='' my_string=""
2.整数变量
declare -i my_integer=42
加上
-i
表示,如果赋值非整数给它,Shell会尝试转换为整数
3.数组
my_array=(1 2 3 4 5)
字符串操作
1.双引号和单引号的区别
使用 ""
双引号拼接字符串,可以双引号中可以出现 变量
和 转义字符
,而 ''
单引号不可以
myUrl="https://romcere.top"
str1="这是我的网站${myUrl}"
str2='这是我的网站${myUrl}'
echo $str1 $str2
# 输出 `这是我的网站https://romcere.top 这是我的网站${myUrl}`
2.获取字符串长度
str="abcd"
echo ${#str} # 输出 4
# 或
echo ${str[0]} # 输出 4
3.提取子字符串
# 提取1-4字符 !提取方法:0 1 2 3 4 ...
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
数组操作
arr_name=(1 2 3 4)
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}
注释
单行注释
# xxx
多行注释
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
或
:'
注释内容...
'
:
是个空命令;<<EOF
是Here文档的标识符,这两个标识符之间的内容都会被视为注释,不会被执行
传参
外部传参
#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
$ ./test.sh 1 2
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
$0
为执行的文件名(包含文件路径)
数组
定义数组
元素用 空格
隔开
array_name=(value1 value2 ... valuen)
读取数组
${array_name[index]}
定义关联数组
declare -A array_name
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"
echo ${site["runoob"]}
即定义一个键值对数组,类
字典
获取所有元素
使用
@
或*
获取数组中的全部元素
echo "数组的元素为: ${site[*]}"
echo "数组的元素为: ${site[@]}"
# 输出:www.google.com www.runoob.com www.taobao.com
使用
!
可以获取数组中的所有键
echo "数组的键为: ${!site[*]}"
# 输出:google runoob taobao
获取数组长度
使用
#
echo "数组元素个数为: ${#site[*]}"
# 数组元素个数为: 4
基本运算
算数运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
val=`expr 2 + 2`
echo "两数之和为 : $val"
表达式和运算符之间要有空格,例如
2+2
是不对的,必须写成2 + 2
,这与我们熟悉的大多数编程语言不一样。
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
eq
:==、-ne
:!=、-gt
:>、-lt
:<、-ge
:>=、-le
:<=
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
布尔运算符
!
为非运算、-o
为或运算、-a
为与运算
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
逻辑运算符
&&、||
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
布尔运算符:需使用
[]
逻辑运算符:需使用
[[]]
[ ]
中需要空格隔开
字符运算符
=
为检查是否相等、!=
为检查是否不相等、-z
为检查字符串长度是否为0、
-n
为检查字符串长度是否不为0、$
为检查字符串是否不为空
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
文件测试运算符
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
常用命令
echo 命令
输出普通字符串
echo "It is a test"
或 echo It is a test
echo "$name"
输出转义字符
echo "\"It is a test\""
echo -e "OK! \n" # -e 开启转义
echo -e "OK! \c" # \c 不换行
输出命令执行结果
echo date
printf 命令
printf "%s %s %s\n" 姓名 性别 体重kg
# 输出:姓名 性别 体重kg
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
test 命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
num1=100
num2=100
# 类:if [$[num1] -eq $[num2]]
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
流程控制
shell中的
else{}
的内容不能为空,否则就不要写else{}
if else
# 语法格式
if condition
then
command1
command2
...
commandN
fi
# 写成一行,用`;`隔开
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
若使用
((...))
作为判断语句,可以直接使用>
和<
if (( a > b )); then
for 循环
# 语法格式
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
# 写成一行
for var in item1 item2 ... itemN; do command1; command2… done;
while 循环
# 语法格式
while condition
do
command
done
until 循环
until 循环执行一系列命令直至条件为 true 时停止;
until 循环与 while 循环在处理方式上刚好相反。
# 语法格式
until condition
do
command
done
case ... esac 多选择语句
类似switch ... case
# 语法格式
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read num # 输入数字
case $num in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
跳出循环
break、continue
函数
# 定义格式
[ function ] funname [()]
{
action;
[return int;]
}
函数参数
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
# 输出:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
需要注意的是10 不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数
输入/输出重定向
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
文件包含
# 引用外部文件
. url # 注意点号(.)和文件名中间有一空格
或
source url