吴宏东 – 记于2018年07月03日 – 博客 https://segmentfault.com/u/wu…
Linux Shell 基础语法
脚本
标记
#!/bin/bash是shell脚本的第一行代码,表示该脚本使用什么解释器;
#!/bin/bash
echo命令用于向窗口输出文本;
echo "hello shell";
# 开启转义 换行
echo -e "hello \n shell";
# 反引号 显示命令执行结果
echo `ls /`;
# 将显示结果定向到文件
echo 'hello' > 1.txt;
单行注释
# 表示单行注释;
多行注释,EOF还可以用其他符号,例如!
:>>EOF
注释内容1
注释内容2
EOF
:>>!
注释内容1
注释内容2
!
例子
创建脚本文件,命名为/tmp/hello.sh
#!/bin/bash
echo "hello shell";
赋予脚本执行的权限,执行脚本
chmod u+x /tmp/hello.sh;
./tmp/hello.sh
变量
定义使用
格式:key=value;
value当为单引号或双引号内容时,即为字符串;当为数字时,即为数值型;
使用变量用美元符号$引用,标准格式是:${key};但有时也可以使用$key;进行引用;
# 字符串变量
a='A';
b="${a}\\B";
# 只读变量
readonly c=7;
# 全局变量
export d=3.14;
# 单引号的内容会原样输出,不能出现单引号,不能使用转义字符
echo $a;
# 双引号内容可以包含变量,可以使用转义字符
echo $b;
# 删除变量
unset c;
字符串
n="0123456789";
m="aaabbbaaabbb";
# 返回字符串变量n的长度
echo ${#n};
# 返回从第5个字符开始到最后的部分
echo ${n:5};
# 返回从第0个字符开始,长度为5的部分
echo ${n:0:5};
# 删除开头部分与012匹配的部分
echo ${n#012};
# 删除结尾部分与789匹配的部分
echo ${n%789};
# 替换第一次出现的aaa为xxx
echo ${m/aaa/xxx};
# 替换全部aaa为xxx
echo ${m//aaa/xxx};
# 替换开头部分的aaa为xxx
echo ${m/#aaa/xxx};
# 替换结尾部分的bbb为xxx
echo ${m/%aaa/xxx};
执行输出:
10
56789
01234
3456789
0123456
xxxbbbaaabbb
xxxbbbxxxbbb
xxxbbbaaabbb
aaabbbaaabbb
替换扩展
v=V;
echo $v;
# 若v未定义或为空值,则返回vvv,但v的值不变;若v存在且非空,则返回V;
echo ${v:-vvv};
# 若v未定义或为空值,则返回vvv,且v的值被赋值为vvv;若v存在且非空,则返回V;
echo ${v:=vvv};
# 若v未定义或为空值,则返回vvv,并终止脚本;若v存在且非空,则返回V;
echo ${v:?vvv};
# 若v未定义或为空值,则返回空值,但v的值不变;若v存在且非空,则返回vvv;
echo ${v:+vvv};
数值运算
四则运算符:+、-、*、/
幂运算符、模运算符:**、%
自增自减运算符:++、–
赋值运算符:=、+=、-=、*=、/=、%=
比较运算符:<、>、<=、>=、==、!=
逻辑运算符:&&、||、!
# 运算表达式必须在双括号内((表达式))
echo $((a=3**2));# 输出9
变量输入
格式:read -p <Prompt String> [<变量名>…];
# 输入单个变量
read -p "请输入:" n;
echo $n;
# 输入多个变量
read -p "请输入:" n1 n2 n3;
echo $n1 / $n2 / $n3;
返回值
每个命令都会返回一个状态码,0表示成功,其他非零数值表示各种情况的错误,exit n;(n的范围是0~255),1表示通用错误,126表示没有执行权限,127表示命令没有找到;
参数
传参
格式:./shell脚本文件 参数1 参数2 …
# 向脚本文件test.sh参入3个参数
./shell/test.sh p1 p2 p3;
# test.sh文件内获取参数
echo $1 $2 $3;
获参
# 传递到脚本的参数个数
echo $#;
# 显示所有参数
echo $*;
echo $@;
# 显示第1个参数
echo $1;
# 显示第10个参数,第10个参数起必须使用${n}
echo ${10};
# 显示最后命令的退出状态,0表示没有错误,其他值表示有错;
echo $?;
# 当前进程的PID
echo $$;
测试表达式
测试语句
格式1:test <测试表达式>
格式2:[ <测试表达式> ]
格式3:[[ <测试表达式> ]]
格式1和格式2等价,格式3可以使用&&、||、!的逻辑连接符;
格式2和3符号前后必须留空格;
a=1.1;
b=1.1;
if test $a == $b; then
# if (( $a == $b )); then
# if [ $a -eq $b ]; then
# if [[ $a == $b ]]; then
echo '相等';
fi;
字符串测试
-z str 字符串是否为空串;
-n str 字符串是否为非空串;
str1 == str2 两个字符串是否相同;
str1 != str2 两个字符串是否不同;
整数二元比较
[] 中使用-eq、-ne、-gt、-ge、-lt、-le;
(())中使用==、!=、>、>=、<、<=;
[]中使用-a、-o、!;
[[]]中使用&&、||、!;
文件目录测试
-e file 文件是否存在;
-f file 是否普通文件;
-d file 是否目录;
-L file 是否链接文件;
-b file 是否为块设备文件;
-c file 是否为字符设备文件;
-s file 是否长度不为零、非空文件;
-r file 是否为可读文件;
-w file 是否为可写文件;
-x file 是否为可执行文件;
-O file 是否为文件的属主;
-G file 是否为文件的属组;
-u file 是否设置了SUID的权限;
-g file 是否设置了SGID的权限;
# 当目录不存在时创建该目录
[ !-e /shell ] && mkdir -p /shell;
数组
定义
格式1:array=(a1 ‘a2’ a3);
格式2:array[0]=a1;array[1]=’a2′;array[2]=a3;
# 定义数组
array=(1 '2');
# 设置第三个元素
array[2]=3;
# 显示第一个元素
echo array[0];
# 获取数组的全部元素
echo ${array[*]};
echo ${array[@]};
# 获取数组的大小
echo ${#array[*]};
函数
定义
格式:function fun() { }
function关键字可以省略;
可以添加返回 return n;(n必须是0~255)执行函数后,可以通过$?获取返回值;
fun() {
return 1;
echo 'over';
}
fun;
echo $?;
流程控制
if 语句
if test -e /shell/1; then
echo '1文件存在';
elif test -e /shell/2; then
echo '2文件存在';
# else分支是最后的默认分支,可以省略,最多只能一个
else
echo '都不存在';
fi;
case 语句
read -p '请输入:' num;
case $num in
1) echo 'num=1' ;;
2) echo 'num=2' ;;
*) echo 'num=?' ;;
esac
while 语句
break:跳出循环;
continue:跳过本次循环,进入下一次迭代;
exit n:会中止当前函数以及调用它的主shell;
i=0;
len=10;
while (($i < $len));do
echo $i;
let "i++";
done;
# 循环读取文件行内容
while read line;
do
echo $line;
done < /shell/proxy;
# 或
cat /shell/proxy | while read line;
do
echo $line;
done;
until 语句
until 表达式与while相反,当返回值为0时结束循环;
for 语句
# 字面常量列表
for loop in 1 2 3 4 5;
do
echo "The value is: $loop"
done;
# 参数列表,in $@可以省略
for p in $@;
do
echo $p;
done;
# 序列列表
for x in {1..9};
do
echo $x;
done;
# C语言型for循环
for((i=0;i<10;i++)) {
echo $i;
}
select 语句
select是一种菜单循环结构,无限循环,退出可以加入break或按<Ctrl+C>,一般加入case语句处理;
select x in 1 2 3;
do
case $x in
1) echo 'x=1' ;;
*) echo 'x=?' ;;
esac;
done;
无限循环
while :
# 或 while true
do
echo 'loop';
done;
for(( ; ; )){
echo 'loop';
}