Shell(三)

Shell 控制流程

if else

if

# 语法
if condition
then
	command_1
	command_2
	...
fi
# 可写成
if condition ; then command1; command2; fi

if else

# 语法
if condition
then
	command_1
	command_2
	...
else
	command_N
	...
fi

if else-if else

# 语法
if condition1
then
	command_1
	...
elif condition2
then
	command_M
	...
else
	command_N
	...
fi

if else 语句经常与test命令搭配使用
有实例如下:

#!/bin/bash

if test $1 -eq $2                                                                                      
then
    echo "两个数相等"
else
    echo "两个数不相等"
fi

运行结果如下:

[root@aliyun test]# ./test.sh 100 200
两个数不相等
[root@aliyun test]# ./test.sh 100 100
两个数相等

for 循环

# 格式
for var in item1 item2 ... itemN
do
    command_1
    command_2
    ...
    command_N
done
# 可写为
for var in item1 item2 ... itemN; do command_1; command_2;done;

当变量值在列表中时,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可以为任何有效的shell命令和语句。in 列表可以包含替换、字符串和文件名
in 列表是可选的,如果不用它,for循环使用命令行的位置参数

有实例如下:

#!/bin/bash

for i in 1 2 3 4 5
do  
    echo -e "$i \c"
done
echo
 
for((i=1;i<=5;i++))
do
    echo -e "$i \c"
done                                                                                                                              
echo

运行结果如下:

[root@aliyun test]# ./test.sh
1 2 3 4 5 
1 2 3 4 5 

有上述实例中可以看出,在shell中除了标准的for循环格式外,还支持类似C语言的for循环格式

while 语句

while condition
do
	command
done

使用方法同理,此处不再赘述

无限循环

while :
do
	command
done
# 或者
while true
do
	command
done
# 或者
for (( ; ; ))

until 循环

until循环执行一系列命令直至调节键为 true才停止,其在处理方式上与while 循环相反,类似于C语言中的do…while() 语句

# 语法
until condition
do
	command
done

condition 一般为条件表达式,如果返回值为false,则继续执行循环体内的语句,否则跳出循环

case

case语句为多分支选择结构语句。用 case 语句匹配一个值与一个模式,如果 匹配成功,执行相匹配的命令
其基本语法如下:

casein
	模式1)
	    command1
	    command2
	    ...
	    commandN
	    ;;
	模式2)
	    command1
	    command2
	    ...
	    commandN
	    ;;
esac

模式取值可以为变量或者常数。匹配发现取值符合某一模式后,其间所有命令都会执行直到";;"停止
取值将检测匹配uude每一个模式。一旦模式匹配,则执行完 匹配模式相应命令后不再继续其他模式
如果没有检测到所有匹配的模式,就会使用星号(*)捕获,并执行其后命令

有实例如下:

#!/bin/bash

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '1'
    ;;
    2)  echo '2'
    ;;
    3)  echo '3'
    ;;
    4)  echo '4'
    ;;
    *)  echo '请输入 1 到 4 之间的数字'
    ;;
esac

运行结果如下:

[root@aliyun test]# ./test.sh
输入 1 到 4 之间的数字:
你输入的数字为:
3    # 标准输入
3    # 输出

break

break命令允许在未达到循环结束条件时强制跳出所有循环,终止执行后面的所有循环

continue

continue 命令类似 break 命令,都是在未达到循环结束条件时强制跳出循环的。不过,不同的是,continue 并不是跳出所有循环,而仅仅只是跳出当前循环

Shell 函数

Linux shell 支持用于定义函数,然后在 shell 脚本中可以随便调用。其格式如下:

[ function ] funname [()]
{
	action;
	...
	[return int;]
}

说明:

  • 可以带 function fun() 定义,也可以直接 fun() 定义,不带任何参数
  • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果作为返回值
  • return 后跟数值 ( 0 ~ 255 )

有如下实例:

#!/bin/bash

function Func(){                 
    printf "请输入两个数字:\a"  
    read a_num b_num             
    echo -e "$a_num + $b_num = \c"                                                                                                
    return $(($a_num+$b_num))  
}                                
                                 
Func                             
echo "$?" 

运行结果如下:

[root@aliyun test]# ./test.sh
请输入两个数字:10 20
10 + 20 = 30
[root@aliyun test]# ./test.sh
请输入两个数字:100 200
100 + 200 = 44

在上述实例中,细心地朋友可能会发现,第二次的运行结果并不正确
此处需要注意:

  • shell中通过 return 返回是有限制的,最大返回255,超过255,则从0开始计算
  • $? 仅对其上一条指令负责,一旦函数返回后其返回值没有立即保存,那么不能使用 $? 来获取,会找不到这个返回值

函数参数

在shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值。这个用法类似于脚本参数的传递方式,同样使用这个形式以获取值

将上述实例进行修改:

#!/bin/bash

function Func(){                        
    echo -e "$1 + $2 = \c"                                                                                                
    return $(($1+$2))  
}                                
                                 
Func 10 20                            
echo "$?" 

运行结果如下:

[root@aliyun test]# ./test.sh
10 + 20 = 30

【注意】:$10 不能用来获取第10个参数,需要使用${10} 。当 n >= 10 时,需要使用 ${n} 来获取参数
此外,还有以下几个特殊字符用来处理参数:

参数处理说明
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数
$-显示Shell使用的当前选项
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误

Shell 输入 / 输出 重定向

默认情况下,Linux 系统命令大多是从标准输入读取,并将输出结果写入标准输出,而一般标准输入和标准输出就是终端。简单来讲,改变一条指令的输入 或 输出位置就是重定向

重定向命令列表如下:

命令说明
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 之间的内容作为输入

一般情况下,每个UNIX / Linux 进程都会打开三个文件,即在命令运行时始终会存在着三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到file
如果希望将 stderr 重定向到 file:command 2 > file
如果希望将stderr 追加到file文件末尾:command 2 >> file
如果希望将 stdout 和 stderr 合并后重定向到 file:command > file 2>&1
如果希望对 stdin 和 stdout 都重定向:command < file1 > file2

Here Document

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式Shell脚本或程序

# 基本格式
command << delimiter
	document
delimiter

作用:将两个 delimiter 之间的内容作为输入传递给 command
【注意】:

  • 对格式要求严格:结尾的 delimiter 需要顶格写,前面和后面都不能有任何字符,包括空格和 tab 缩进
  • 开始的 delimiter 前后的空格会被忽略掉

比如在终端中输入 cat << EOF,系统会提示继续进行输入,输入多行信息后再次输入EOF,中间输入的信息将会显示在屏幕上
有实例如下:

[root@aliyun test]# cat << EOF
> First Line
> Second Line
> Third Line EOF
> EOF
First Line
Second Line
Third Line EOF

说明:

  • >这个符号是终端产生的提示输入信息的标识符
  • EOF 只是一个标识而已,可以替换成任意的合法字符

又有实例 如:

#!/bin/bash
# ./test.sh 为当前文件

user_name="Adan-Xi"
cat << EOF > output1.sh
echo "Hello!"
echo $user_name    # 此处的变量将被展开
EOF

cat << "FOE" > output2.sh
echo "Hello "
echo $user_name    # 此处的变量将不会被展开
FOE

其输出如下:

[root@aliyun test]# ls
test.sh
[root@aliyun test]# ./test.sh
[root@aliyun test]# chmod +x output1.sh output2.sh
[root@aliyun test]# ls
output1.sh  output2.sh  test.sh
[root@aliyun test]# cat output1.sh 
echo "Hello!"
echo Adam-Xi
[root@aliyun test]# cat output2.sh 
echo "Hello "
echo $user_name
[root@aliyun test]# ./output1.sh
Hello!
Adam-Xi
[root@aliyun test]# ./output2.sh
Hello 
        # 此行输出为空

此处想借此例子说明,在这个重定向方式中,如果不想将 document 中的脚本变量展开,那么只需给delimiter加引号""即可

/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么就可以将输出重定向到 /dev/null:command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。
/dev/null 的作用是起到 禁止输出 的效果

Shell 文件包含

和其他语言一样,Shell 也可以包含外部文本,这样可以很方便的封装一些共用的代码作为一个独立的文件
其基本语法如下:

. filename    # 注意此处(.)和文件名间有一个空格
# 或者
source filename

实例如下:

#!/bin/bash
# common.sh

user_name="Adam-Xi"
user_id=2344
echo "I am common.sh"
#!/bin/bash
# test1.sh
source ./common.sh
echo $user_name
#!/bin/bash
# test1.sh
. ./common.sh
echo $user_id

其输出结果如下:

[root@aliyun test]# chmod +x test1.sh test2.sh
[root@aliyun test]# ll
[root@aliyun test]# ll
total 20
-rw-r--r-- 1 root root   68 Mar 25 12:53 common.sh
-rwxr-xr-x 1 root root   49 Mar 25 12:55 test1.sh
-rwxr-xr-x 1 root root   42 Mar 25 12:56 test2.sh
-rwxr-xr-x 1 root root 4637 Mar 25 12:52 test.sh
[root@aliyun test]# ./test1.sh
I am common.sh
Adam-Xi
[root@aliyun test]# ./test2.sh
I am common.sh
2344

【注意】:

  • 被包含的文件不一定需要可执行权限
  • 执行顺序是:先执行被包含文件中的内容,在执行包含文件中的内容

以上


THE END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值