《Linux》day4--shell语法(下)

发布于:2022-11-13 ⋅ 阅读:(903) ⋅ 点赞:(0)

判断语句

if…then形式

类似于 C/C++中的 if…else语句

单层if
命令格式

if condition
then
	语句一
	语句二
	...
fi

例如:

#! /bin/bash

a=3
b=4

if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
then
    echo ${a}在范围内
fi

在这里插入图片描述

单层if-else

命令格式:

if condiotion
then
	语句一
	语句二
	...
else
	语句一
	语句二
	...
fi

例如:

#! /bin/bash

a=3
b=4

if ! [ "$a" -lt "$b" ]
then
    echo ${a}不小于${b}
else
    echo ${a}小于${b}
fi

在这里插入图片描述

多层if-elif-elif-else
命令格式

if condition
then
	...
elif condition
then
	...
else
	...
fi

例如:

#1 /bin/bash

a=4

if [ $a -eq 1 ]
then
        echo ${a}等于1
elif [ $a -eq 2 ]
then
        echo ${a}等于2
elif [ $a -eq 3 ]
then
        echo $a等于3
else
        echo 其他
fi

在这里插入图片描述

case…esac形式

类似于C/C++中的 Switch 语句

命令格式:

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

例如:

#1 /bin/bash

a=4

case $a in
        1)
                echo $a等于1
                ;;
        2)
                echo $a等于2
                ;;
        3)
                echo $a等于3
                ;;
        *)
                echo 其他
                ;;
esac

在这里插入图片描述

循环语句

for…in…do…done

命令格式

for val in val1 val2 val3
do
	语句一
	语句二
	...
done

例如1:输出sun 20 tong,每个元素占一行

#1 /bin/bash

for i in sun 20 tong
do
    echo "$i"
done

在这里插入图片描述
例如2:输出当前路径下的所有文件名,每个文件名占一行

#1 /bin/bash

for file in `ls`
do
    echo $file
done

在这里插入图片描述
示例3:输出1-10之间的数字(seq命令只支持数字)

#1 /bin/bash

for i in $(seq 1 10)
do
    echo $i
done

在这里插入图片描述
示例4:使用 {1…10} 或者 {a…z}

#1 /bin/bash

for i in {a..z}
do
    echo $i
done

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

命令格式

for((expression; condition; expression))
do
	语句一
	语句二
	...
done

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

#1 /bin/bash

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

在这里插入图片描述

while…do…done循环

命令格式

while condition
do
	...
done

例如:文件结束符为 ctrl + d ,输入文件结束符后 read命令返回 false

#1 /bin/bash

while read name
do
    echo $name;
done

在这里插入图片描述

until…do…done循环

当条件为真时结束,命令格式

until condition
do
	...
done

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

#1 /bin/bash

until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
    read -p "please input yes or YES to stop this commod: " word
done

在这里插入图片描述

break命令

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

例如:

#1 /bin/bash

while read name
do
    for ((i=1; i<=10; i++))
    do
        case $i in
            8)
                break;
                ;;
            *)
                echo $i
                ;;
        esac
    done
done

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

continue命令

跳出当前循环,与C++一样

示例:输出 1-10 之间的所有奇数

#1 /bin/bash

for ((i=1; i<=10; i++))
do
    if [ `expr $i % 2` -eq 0 ]
    then
        continue
    fi
    echo $i
done

在这里插入图片描述

死循环的处理方式

如果terminal可以打开该程序,可以输入 ctrl + c 直接杀掉该程序即可

如果打不开该程序,可以直接关闭进程:
关闭进程:

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

函数

bash中的函数类似于C++中的函数,但是return的返回值与C++不同,返回的是 exit code(退出状态,0表示正常退出,取值为0-255)
如果想要获取函数的输出结果,可以通过 echo 输出到sdout 中,然后通过 $(function_name) 来获取sdout中的结果
函数中的 return 值可以通过 $? 来获取

命令格式:

[function] func_name(){  # funtion关键字可以省略
	...
}

不获取 return 值和 sdout 值

例如:

#1 /bin/bash

func(){
    name=sun
    echo "hello $name"
}

func   #调用函数,不需要加 ()

在这里插入图片描述

获取 return 值和 sdout 值:不写return值时,默认 return 0

例如:

#1 /bin/bash

func(){
    name=sun
    echo "hello $name"

    return 123
}

output=$(func)   #sdout
ret=$?   #exit code

echo "output = $output"
echo "ret = $ret"

在这里插入图片描述

函数的输入参数

在函数内,$1 表示第一个输入的参数,$2 表示第二个输入参数,…
注意:函数内的 $0 仍然是文件名,而不是函数名

例如:

#! /bin/bash

# 递归计算 $1 + ($1 - 1) + ($1 -2) + ... + 0
func(){
    if [ $1 -le 0 ]
    then
        echo 0
        return 0
    fi

    sum=$(func $(expr $1 - 1))
    echo $(expr $sum + $1)
}

echo $(func 10)

在这里插入图片描述

这里面为什么只输出最后结果55,而不输出其他值呢?因为 echo 函数后面有 $ ,就会截获 sdout 里面的值,使得 echo 找不到 sdout 里的数据从而不能输出

函数内的局部变量

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

命令格式:

local 变量名=变量值

例如:

#! /bin/bash

func(){
    local name=sun
    echo $name
}

func

echo $name

在这里插入图片描述

exit命令

exit命令用来退出当前 shell 进程,并返回一个退出状态;使用 $? 可以接受这个退出状态
exit命令可以接受一个整数值作为参数,代表退出状态,如果不指定,默认退出状态是0
exit退出状态只能是一个介于0-255之间的整数,其中0表示成功退出,其他值都表示失败

例如:

#! /bin/bash

if [ $# -ne 1 ] #如果传入参数等于1,则正常退出
then
    echo "arguments not vaild"
    exit 1
else
    echo "arguments vaild"
    exit 0
fi
acs@fb883ed03006:~$ ./test.sh 25 #传入一个参数
arguments vaild
acs@fb883ed03006:~$ echo $?
0
acs@fb883ed03006:~$ ./test.sh #传入0个参数
arguments not vaild
acs@fb883ed03006:~$ echo $?
1

文件重定向

每个进程默认打开三个文件描述符

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

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

重定向命令列表

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

输入和输出重定向

#! /bin/bash

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

在这里插入图片描述
同时重定向stdin和stdout

#! /bin/bash

read a
read b

echo $(expr "$a" + "$b")

创建output.txt文件,里面内容为
3
4

执行命令:

acs@fb883ed03006:~$ ./test.sh < input.txt > output.txt	#从output.txt中读取内容,并输入到input.txt文件中
-bash: input.txt: No such file or directory
acs@fb883ed03006:~$ ./test.sh < output.txt > input.txt
acs@fb883ed03006:~$ cat input.txt
7

引入外部脚本

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

语法形式:

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

例如:先创建一个 test1.sh,内容为

#! /bin/bash

name=sun

然后创建 test2.sh脚本,内容为

#! /bin/bash

source test1.sh #或者 . test1.sh

echo my name is: $name

输出结果:my name is: sun


网站公告

今日签到

点亮在社区的每一天
去签到