Bash 第七讲 函数 数组 读取文件 重定向

10 篇文章 0 订阅
8 篇文章 0 订阅

Bash 函数

函数可以有效减少您重复编写程序段的工作量,可随时重复调用。

函数声明

首选常用格式,以函数名称开头。

function_name() {
commands
}

以 Function 开头,后接函数名。

function function_name() {
commands
}

两种格式的单行压缩,请仔细对照。

function_name() {commands;}
function function_name() {commands;}

注:

  • 请仔细观察空格,严格遵守语法格式。
  • commands是函数主体,即命令集。
  • 使用单行压缩函数时,;必须跟随函数主体中的最后一个命令。
  • 您最好始终保持功能性名称的描述性,以方便您在封装完毕之后调用。
示例:
#!/bin/bash

W3Cschool(){
 echo "Welcome to W3Cschool"
}

W3Cschool

执行后得到以下结果:

Welcome to W3Cschool
变量作用域

在 Bash 中,在默认情况下所有变量都定义为全局变量,即使在函数内部声明也是如此。
您可以使用local关键字在函数内部声明局部变量,该变量只能够在该函数内部使用。同其他编程语言一样,这意味着您可以声明相同名称的全局变量。

#!/bin/bash

str1="abc"
str2="bcd"

fun(){
    local str1="123"
    str2="234"
    echo "Inside function:str1_value is ${str1},str2_value is ${str2}."
}

echo "Before executing function:str1_value is ${str1},str2_value is ${str2}."

fun

echo "After executing function:str1_value is ${str1},str2_value is ${str2}."

执行后得到以下结果:

Before executing function:str1_value is abc,str2_value is bcd.
Inside function:str1_value is 123,str2_value is 234.
After executing function:str1_value is abc,str2_value is 234.

注:

  • 由执行结果得出。
    在变量名相同的情况下,局部变量的优先级在函数内部高于全局变量。可以理解为就近原则。
    全局变量可以在函数内部更改它的值。
返回值

在 Bash 函数中,其返回值是执行的最后一个语句的状态。1-255(十进制)范围内表示失败,除此之外表示成功。
您可以使用return语句指定返回状态,并将其分配给$?。该语句会终止函数的调用。如下所示:

#!/bin/bash

fun(){
    echo "result"
    return 66
}

fun
echo $?

执行后得到以下结果:

result
66

若您想要从函数中返回任意实际的值,最简单的选择是将函数的执行结果分配给一个全局变量,如下所示:

#!/bin/bash

fun(){
    fun_result="value"
}

fun
echo $fun_result

执行后得到以下结果:

value

还有一个更好的选择是将值发送到 stdout 再打印输出,如下所示:

#!/bin/bash

fun(){
    local fun_result="value"
    echo "$fun_result"
}

fun
echo $fun_result

执行后得到以下结果:

value

注:
利用 $()机制将函数执行结果分配给变量fun_result,以此保存函数的执行结果。

参数传递

若您想要将任意数量的参数传递给 Bash 函数,只需要将它们放在调用的函数名后面,以空格分隔,以" "将参数转义。
注:

参数传递的顺序位为 $1$2···$n,在传参时应严谨的根据需要排序以达到您所期望的效果。
$#保存传递给函数的函数的位置参数或数量。
$*$@保存传递给参数的所有位置参数或参数。
示例:
#!/bin/bash

fun(){
    echo "Welcome to $1"
}

fun "W3Cschool"

执行后得到以下结果:

Welcome to W3Cschool

Bash 数组

数组声明

索引数组
使用declare加-a选项,将变量来声明数组,语法如下:

#声明数组
declare -a Array_Name

#创建数组元素
Array_Name[index_1]=value_1
Array_Name[index_2]=value_2

#或

Array_Name=(
    [index_1]=value_1
    [index_2]=value_2
)

注:

  • 在 Bash 中命名数组的规则与变量的命名规则相同。
  • Array_Name是数组名称。
  • index是为正整数的索引。
    关联数组
    使用declare加-A选项来声明数组,语法如下:
#声明数组
declare -A Array_Name

#创建数组元素
Array_Name[index_1]=value_1
Array_Name[index_2]=value_2

#或

Array_Name=(
    [index_1]=value_1
    [index_2]=value_2
)

数组初始化

Array_Name=(element_1 element_2 element_3)

注:

  • 此处索引从0开始。
  • =两侧无空格。
    打印数组
declare -p Array_Name
数组运算

访问元素
您要想访问一个元素,首先需要知道该元素的索引下标,然后使用以下语法进行访问获取。

${Array_Name[index]}

如果您使用@或*作为索引进行访问获取,那么将会得到数组中的所有元素。

#!/bin/bash

declare -a arr=("welcome" "to" "W3Cschool")

echo "@"
for i in "${arr[@]}"
do
echo "$i"
done

echo "*"
for i in "${arr[*]}"
do
echo "$i"
done

执行后得到以下结果:

@
welcome
to
W3Cschool

*
welcome to W3Cschool

注:

  • @和 *两者的区别主要体现在循环结果的不同。
    打印数组键
    您还可以检索和打印在数组中使用的键。语法如下:
${!Array_Name[index]}

示例:

#!/bin/bash

declare -a arr=( "Welcome" "To" "W3Cschool" )

echo "${!arr[@]}"

执行后得到以下结果:

0 1 2

查找数组长度
数组长度即数组中的元素个数,语法如下:

${#ARRAY_NAME[@]}

示例:

#!/bin/bash

declare -a arr=( "Welcome" "To" "W3Cschool" )

echo "The array contains    ${#arr[@]} elements"

执行后得到以下结果:

The array contains 3 elements

遍历数组
遍历数组的通用方法是 for 循环,如下所示:

#!/bin/bash

declare -a arr=( "Welcome" "To" "W3Cschool" )

for i in "${!arr[@]}"
do
echo The key value of element "${arr[$i]}" is "$i"
done

执行后得到以下结果:

The key value of element Welcome is 0
The key value of element to is 1
The key value of element W3Cschool is 2

添加或删除元素

  • 添加元素
Array_Name[index]="New Element"

示例:

#!/bin/bash

declare -a arr=( "Java" "Python" "PHP" "HTML" )

arr[4]="JavaScript"

echo "${arr[@]}"

执行后得到以下结果:

Java Python PHP JavaScript CSS SQL
  • 删除元素
unset ARRAY_NAME[index]

示例:

#!/bin/bash

declare -a arr=( "Java" "Python" "HTML" "CSS" "JavaScript" )

unset arr[1]

echo "${arr[@]}"

执行后得到以下结果:

Java HTML CSS JavaScript

删除数组
可以通过将数组名称作为参数传递给unset命令执行删除操作,如下所示:

#!/bin/bash

declare -a arr=( "Java" "Python" "HTML" "CSS" "JavaScript" )

unset arr

echo ${!arr[@]}

echo ${!arr[@]}

执行后返回空结果,数组已不存在。
数组切片
Bash 数组也可以从指定的起始索引切片至指定的结束索引,语法如下:

Slieced_Array=(${Array_Name[@]:m:n}")

示例:

#!/bin/bash

example_array=( "Java" "Python" "HTML" "CSS" "JavaScript" )

sliced_array=("${example_array[@]:1:3}")

for i in "${sliced_array[@]}"
do
echo $i
done

执行后得到以下结果:

Python
HTML
CSS

Bash 读取文件

以下示例均以 ReadFile.txt 文件为例。文件内容如下:

Welcome
To
Our
Website
-
W3Cschool

读取操作

您可以使用cat file_Name来读取文件。
语法:

value=`cat file_Name`

应用示例:

#!/bin/bash

value=`cat ReadFile.txt`  
echo "$value"

行后得到以下结果:

Welcome
To
Our
Website
-
W3Cschool

您也可以使用$(file_Name)来读取文件。
语法:

value=$(file_Name)

应用示例:

#!/bin/bash

value=$(<ReadFile.txt)
echo "$value"

执行后得到以下结果:

Welcome
To
Our
Website
-
W3Cschool

您还可以使用 while 循环来读取文件。
应用示例:

#!/bin/bash

i=1
while read line; do

#Reading each line
echo "No. $i : $line"
i=$((i+1))
done < ReadFile.txt

执行后得到以下结果:

No. 1 : Welcome
No. 2 : To
No. 3 : Our
No. 4 : Website
No. 5 : -
No. 6 : W3Cschool

注:

  • 在这里 i用于给循环迭代出的每一个字符串编号。
  • 使用 while 循环来读取文件的写法很灵活多样,但编写简便的代码语句是一个好习惯哦。

Bash 重定向

当一个命令执行时,通常从“标准输入”读取输入,在默认情况下,该“标准输入”为您的终端。以此类比,当一个命令将其输出写入到“标准输出”中,在默认情况下,该“标准输出”同为您的终端。重定向就是将发送目标:终端,更改成指定的文件。

输出重定向

由于>或>>会将输出从终端重定向到指定文件,因此均不会在终端打印输出。>和>>的功能区别,如下所示:
>会以命令中的写入内容覆盖原文件内容。如果指定的文件不存在,那么它将会创建一个以指定文件名命名的新文件,并执行写入操作。
示例:

#!/bin/bash

writefile=WriteFile.txt

$ echo "编程狮:www.w3cschool.cn" > $writefile

#使用 cat 命令打印文件内容
$ cat $writefile

执行后得到以下结果:

编程狮:www.w3cschool.cn

>>会将命令中的写入内容附加到原文件内容末尾。如果指定的文件不存在,那么它将会创建一个以指定文件名命名的新文件,并执行写入操作。
示例:

#!/bin/bash

writefile=WriteFile.txt

$ echo "编程狮:www.w3cschool.cn" > $writefile

$ echo "编程狮:www.w3cschool.cn" >> $writefile

#使用 cat 命令打印文件内容
cat $writefile

执行后得到以下结果:

编程狮:www.w3cschool.cn
编程狮:www.w3cschool.cn
输入重定向

与输出重定向一样,但是符号方向相反。语法展示如下:

command < file

接下来使用 wc命令读取文件行数配合演示示例。 示例:

$ wc -l < WriteFile.txt

注:

  • 此处不会输出文件名, < 仅知道从“标准输入”读取的内容。
深入理解

您需要理解以下三个文件概念:

  • stdin:标准输入文件,其文件描述符为0,默认由此读取数据。
  • stdout:标准输出文件,其文件描述符为1,默认向它输出数据。
  • stderr:标准错误文件,其文件描述符为2,默认向它写入错误信息。
#默认情况下
command > file
#将 stdout 重定向到 file

command < file
#将 stdin 重定向到 file

如果想要 stderr重定向到 file ,如下示例:

$ command 'stderr' > file
#或(注意二者的区别)
$ command 'stderr' >> file

注:

  • 'stderr’指代标准错误文件,非命令,请不要盲目复制使用。
    如果希望对stdin和stdout都进行重定向,将 file1 作为command 的输入,并将 command 的处理结果输出到 flie2 。
command < file1 > file2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值