您的位置:首页 > 娱乐 > 明星 > Linux -- shell语法2

Linux -- shell语法2

2024/10/6 12:22:35 来源:https://blog.csdn.net/qq_53839898/article/details/141380494  浏览:    关键词:Linux -- shell语法2

10  test命令与判断符号[]

10.1  逻辑运算符&&和||

&& 表示与,|| 表示或
二者具有短路原则:
expr1 && expr2:当expr1为假时,直接忽略expr2
expr1 || expr2:当expr1为真时,直接忽略expr2
表达式的exit code为0,表示真;为非零,表示假。(与C/C++中的定义相反)

10.2  test命令

在命令行中输入man test,可以查看test命令的用法。

test命令用于判断文件类型,以及对变量做比较。

test命令用exit code返回结果,而不是使用stdout。0表示真,非0表示假。

        例如:

test 2 -lt 3  # 为真,返回值为0
echo $?  # 输出上个命令的返回值,输出0
acs@9e0ebfcd82d7:~$ ls  # 列出当前目录下的所有文件
homework  output.txt  test.sh  tmp
acs@9e0ebfcd82d7:~$ test -e test.sh && echo "exist" || echo "Not exist"
exist  # test.sh 文件存在
acs@9e0ebfcd82d7:~$ test -e test2.sh && echo "exist" || echo "Not exist"
Not exist  # testh2.sh 文件不存在

10.3  文件类型判断

        命令格式:

test -e filename  # 判断文件是否存在

测试参数代表意义
-e 文件是否存在
-f是否为文件
-d是否为目录

10.4  文件权限判断

        命令格式:

test -r filename  # 判断文件是否可读

测试参数代表意义
-r文件是否可读
-w文件是否可写
-x文件是否可执行
-s是否为非空文件

10.5  整数间的比较

        命令格式:

test $a -eq $b  # a是否等于b

测试参数代表意义
-eqa是否等于b
-nea是否不等于b
-gta是否大于b
-lta是否小于b
-gea是否大于等于b
-lea是否小于等于b

 10.6  字符串比较

测试参数代表意义
test -z STRING判断STRING是否为空,如果为空,则返回true
test -n STRING判断STRING是否非空,如果非空,则返回true(-n可以省略)
test str1 == str2判断str1是否等于str2
test str1 != str2判断str1是否不等于str2

10.7  多重条件判定

        命令格式:

test -r filename -a -x filename

测试参数代表意义
-a 两条件是否同时成立
-o两条件是否至少一个成立
!取反。如 test ! -x file,当file不可执行时,返回true

10.8  判断符号[]

        []test用法几乎一模一样,更常用于if语句中。另外[[]][]的加强版,支持的特性更多。

        例如:

[ 2 -lt 3 ]  # 为真,返回值为0
echo $?  # 输出上个命令的返回值,输出0

acs@9e0ebfcd82d7:~$ ls  # 列出当前目录下的所有文件
homework  output.txt  test.sh  tmp
acs@9e0ebfcd82d7:~$ [ -e test.sh ] && echo "exist" || echo "Not exist"
exist  # test.sh 文件存在
acs@9e0ebfcd82d7:~$ [ -e test2.sh ] && echo "exist" || echo "Not exist"
Not exist  # testh2.sh 文件不存在

        注意:

  • []内的每一项都要用空格隔开
  • 中括号内的变量,最好用双引号括起来
  • 中括号内的常数,最好用单或双引号括起来

        例如:

name="acwing yxc"
[ $name == "acwing yxc" ]  # 错误,等价于 [ acwing yxc == "acwing yxc" ],参数太多
[ "$name" == "acwing yxc" ]  # 正确

11  判断语句

if…then形式
类似于C/C++中的if-else语句。

11.1  单层if

        命令格式:

if condition
then语句1语句2...
fi

        示例:

a=3
b=4if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
thenecho ${a}在范围内
fi

        输出结果:

3在范围内

11.2  单层if-else

        命令格式

if condition
then语句1语句2...
else语句1语句2...
fi

        示例:

a=3
b=4if ! [ "$a" -lt "$b" ]
thenecho ${a}不小于${b}
elseecho ${a}小于${b}
fi

        输出结果:

3小于4

11.3  多层if-elif-elif-else

        命令格式

if condition
then语句1语句2...
elif condition
then语句1语句2...
elif condition
then语句1语句2
else语句1语句2...
fi

        示例:

a=4if [ $a -eq 1 ]
thenecho ${a}等于1
elif [ $a -eq 2 ]
thenecho ${a}等于2
elif [ $a -eq 3 ]
thenecho ${a}等于3
elseecho 其他
fi

        输出结果:

其他

11.4  case…esac形式

类似于C/C++中的switch语句。

        命令格式

case $变量名称 in值1)语句1语句2...;;  # 类似于C/C++中的break值2)语句1语句2...;;*)  # 类似于C/C++中的default语句1语句2...;;
esac

        示例:

a=4case $a in1)echo ${a}等于1;;  2)echo ${a}等于2;;  3)                                                echo ${a}等于3;;  *)echo 其他;;  
esac

        输出结果:

其他

12  循环语句

12.1  for…in…do…done

        命令格式:

for var in val1 val2 val3
do语句1语句2...
done

        示例1,输出a 2 cc,每个元素一行:

for i in a 2 cc
doecho $i
done

        示例2,输出当前路径下的所有文件名,每个文件名一行:

for file in `ls`
doecho $file
done

        示例3,输出1-10

for i in $(seq 1 10)
doecho $i
done

        示例4,使用{1..10} 或者 {a..z}

for i in {a..z}
doecho $i
done

12.2  for ((…;…;…)) do…done

         命令格式:

for ((expression; condition; expression))
do语句1语句2
done

        示例,输出1-10,每个数占一行:

for ((i=1; i<=10; i++))
doecho $i
done

12.3  while…do…done循环

        命令格式:     

while condition
do语句1语句2...
done

        示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。

while read name
doecho $name
done

12.4  until…do…done循环

当条件为真时结束。

        命令格式:

until condition
do语句1语句2...
done

        示例,当用户输入yes或者YES时结束,否则一直等待读入。

until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
doread -p "Please input yes/YES to stop this program: " word
done

12.5  break命令

跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。

        示例

while read name
dofor ((i=1;i<=10;i++))docase $i in8)break;;*)echo $i;;esacdone
done

该示例每读入非EOF的字符串,会输出一遍1-7。
该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程。

12.6  continue命令

跳出当前循环。

        示例:

for ((i=1;i<=10;i++))
doif [ `expr $i % 2` -eq 0 ]thencontinuefiecho $i
done

该程序输出1-10中的所有奇数。

12.7  死循环的处理方式

如果AC Terminal可以打开该程序,则输入Ctrl+c即可。

否则可以直接关闭进程:

  1. 使用top命令找到进程的PID
  2. 输入kill -9 PID即可关掉此进程

 13  函数

bash中的函数类似于C/C++中的函数,但return的返回值与C/C++不同,返回的是exit code,取值为0-255,0表示正常结束。

如果想获取函数的输出结果,可以通过echo输出到stdout中,然后通过$(function_name)来获取stdout中的结果。

函数的return值可以通过$?来获取。

        命令格式:

[function] func_name() {  # function关键字可以省略语句1语句2...
}

13.1  不获取 return值和stdout

        示例

func() {name=yxcecho "Hello $name"
}func

        输出结果:

Hello yxc

13.2  获取 return值和stdout

不写return时,默认return 0

        示例

func() {name=yxcecho "Hello $name"return 123
}output=$(func)
ret=$?echo "output = $output"
echo "return = $ret"

        输出结果:

output = Hello yxc
return = 123

13.3  函数的输入参数

在函数内,$1表示第一个输入参数,$2表示第二个输入参数,依此类推。

注意:函数内的$0仍然是文件名,而不是函数名。

        示例:

func() {  # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0word=""while [ "${word}" != 'y' ] && [ "${word}" != 'n' ]doread -p "要进入func($1)函数吗?请输入y/n:" worddoneif [ "$word" == 'n' ]thenecho 0return 0fi  if [ $1 -le 0 ] thenecho 0return 0fi  sum=$(func $(expr $1 - 1))echo $(expr $sum + $1)
}echo $(func 10)

        输出结果:

55

13.4  函数内的局部变量

可以在函数内定义局部变量,作用范围仅在当前函数内。

可以在递归函数中定义局部变量。

        命令格式:

local 变量名=变量值

        例如:

#! /bin/bashfunc() {local name=yxcecho $name
}
funcecho $name

        输出结果:

yxc

第一行为函数内的name变量,第二行为函数外调用name变量,会发现此时该变量不存在。

14  exit命令

exit命令用来退出当前shell进程,并返回一个退出状态;使用$?可以接收这个退出状态。

exit命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是 0。

exit退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。

        示例:

创建脚本test.sh,内容如下:

#! /bin/bashif [ $# -ne 1 ]  # 如果传入参数个数等于1,则正常退出;否则非正常退出。
thenecho "arguments not valid"exit 1
elseecho "arguments valid"exit 0
fi

执行该脚本:

acs@9e0ebfcd82d7:~$ chmod +x test.sh 
acs@9e0ebfcd82d7:~$ ./test.sh acwing
arguments valid
acs@9e0ebfcd82d7:~$ echo $?  # 传入一个参数,则正常退出,exit code为0
0
acs@9e0ebfcd82d7:~$ ./test.sh 
arguments not valid
acs@9e0ebfcd82d7:~$ echo $?  # 传入参数个数不是1,则非正常退出,exit code为1
1

---->return和exit的共同之处都是返回exit code,区别是return结束当前函数,exit结束整个shell脚本 

15  文件重定向

15.1  每个进程默认打开3个文件描述符:

  • stdin标准输入,从命令行读取数据,文件描述符为0
  • stdout标准输出,向命令行输出数据,文件描述符为1
  • stderr标准错误输出,向命令行输出数据,文件描述符为2

可以用文件重定向将这三个文件重定向到其他文件中。

15.2  重定向命令列表

命令说明
command > filestdout重定向到file
command < filestdin重定向到file
command >> filestdout以追加方式重定向到file
command n> file将文件描述符n重定向到file
command n>> file将文件描述符n以追加方式重定向到file

15.3  输入和输出重定向

echo -e "Hello \c" > output.txt  # 将stdout重定向到output.txt中
echo "World" >> output.txt  # 将字符串追加到output.txt中read str < output.txt  # 从output.txt中读取字符串echo $str  # 输出结果:Hello World

15.4  同时重定向stdin和stdout

        创建bash脚本:

#! /bin/bashread a
read becho $(expr "$a" + "$b")

        创建input.txt,里面的内容为:

3
4

        执行命令:

acs@9e0ebfcd82d7:~$ chmod +x test.sh  # 添加可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh < input.txt > output.txt  # 从input.txt中读取内容,将输出写入output.txt中
acs@9e0ebfcd82d7:~$ cat output.txt  # 查看output.txt中的内容
7

16  引入外部脚本

类似于C/C++中的include操作,bash也可以引入其他文件中的代码。

        语法格式:

. filename  # 注意点和文件名之间有一个空格或source filename

        示例

        创建test1.sh,内容为:

#! /bin/bashname=yxc  # 定义变量name

        然后创建test2.sh,内容为:

#! /bin/bashsource test1.sh # 或 . test1.shecho My name is: $name  # 可以使用test1.sh中的变量

        执行命令:

acs@9e0ebfcd82d7:~$ chmod +x test2.sh 
acs@9e0ebfcd82d7:~$ ./test2.sh 
My name is: yxc

引用库里的一句话:why not me,shell night night!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com