Bash 脚本 命令使用详解

Bash 脚本 命令使用详解什么是Bash简介Bash(GNUBourne-AgainShell)是一个为GNU计划编写的Unixshell,它是许多Linux平台默认使用的shell。shell是一个命令解释器,是介于操作系统内核与用户之间的一个绝缘层。准确地说,它也是能力很强的计算机语言,被称为解释

大家好,欢迎来到IT知识分享网。

什么是 Bash
简介
Bash(GNU Bourne-Again Shell)是一个为 GNU 计划编写的 Unix shell,它是许多 Linux 平台默认使用的 shell。

shell 是一个命令解释器,是介于操作系统内核与用户之间的一个绝缘层。准确地说,它也是能力很强的计算机语言,被称为解释性语言或脚本语言。它可以通过将系统调用、公共程序、工具和编译过的二进制程序”粘合“在一起来建立应用,这是大多数脚本语言的共同特征,所以有时候脚本语言又叫做“胶水语言”。

事实上,所有的 UNIX 命令和工具再加上公共程序,对于 shell 脚本来说,都是可调用的。Shell 脚本对于管理系统任务和其它的重复工作的例程来说,表现的非常好,根本不需要那些华而不实的成熟紧凑的编译型程序语言。

运行 Bash 脚本的方式:
#!/bin/bash
#这一行是表示使用 /bin/bash 作为脚本的解释器
#这行要放在脚本的行首并且不要省略。

# 使用shell来执行
sh hello.sh

# 使用bash来执行
bash hello.sh

# 使用.来执行
. ./hello.sh

# 使用source来执行
source hello.sh

# 还可以赋予脚本所有者执行权限,允许该用户执行该脚本
chmod u+rx hello.sh
./hello.sh
bash特殊字符(上)
注释(#)
行首以 # 开头(除#!之外)的是注释。#! 是用于指定当前脚本的解释器,我们这里为 bash,且应该指明完整路径,所以为 /bin/bash

分号(;)
使用分号 ; 可以在同一行上写两个或两个以上的命令。

点号(.)
等价于 source 命令
bash 中的 source 命令用于在当前 bash 环境下读取并执行 FileName.sh 中的命令。

source test.sh

. test.sh
引号
双引号(”)
“STRING” 将会阻止(解释)STRING 中大部分特殊的字符。后面的实验会详细说明。

单引号(’)
‘STRING’ 将会阻止 STRING 中所有特殊字符的解释,这是一种比使用”更强烈的形式。后面的实验会详细说明。

Bash 脚本 命令使用详解

反引号(`)
命令替换
反引号中的命令会优先执行,如:

cp `mkdir back` test.sh back
ls
先创建了 back 目录,然后复制 test.sh 到 back 目录。

冒号(:)
空命令
等价于“NOP”(no op,一个什么也不干的命令)。也可以被认为与 shell 的内建命令 true 作用相同。“:”命令是一个 bash 的内建命令,它的退出码(exit status)是(0)。

#!/bin/bash

while :
do
echo “endless loop”
done
等价于

#!/bin/bash

while true
do
echo “endless loop”
done
可以在 if/then 中作占位符:

#!/bin/bash

condition=5

if [ $condition -gt 0 ]
#gt表示greater than,也就是大于,同样有-lt(小于),-eq(等于)
then : # 什么都不做,退出分支
else
echo “$condition”
fi
变量扩展/子串替换
在与 > 重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。

: > test.sh # 文件“test.sh”现在被清空了
# 与 cat /dev/null > test.sh 的作用相同
# 然而,这并不会产生一个新的进程, 因为“:”是一个内建命令
在与 >> 重定向操作符结合使用时,将不会对预先存在的目标文件 : >> target_file 产生任何影响。如果这个文件之前并不存在,那么就创建它。

问号(?)
测试操作符
在一个双括号结构中,? 就是 C 语言的三元操作符,如:

vim test.sh
输入如下代码,并保存:

#!/bin/bash

a=10
(( t=a<50?8:9 ))
echo $t
运行测试

bash test.sh
8
美元符号($)
引用变量

bash特殊字符(下)
小括号(( ))
在括号中的变量,由于是在子 shell 中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子 shell 中创建的变量。如:

vim test20.sh
输入代码:

#!/bin/bash

a=123
( a=321; )

echo “$a” #a的值为123而不是321,因为括号将判断为局部变量
运行代码:

bash test20.sh
a = 123
在圆括号中 a 变量,更像是一个局部变量。

2.初始化数组
创建数组

vim test21.sh
输入代码:

#!/bin/bash

arr=(1 4 5 7 9 21)
echo ${arr[3]} # get a value of arr
运行代码:

bash test21.sh
7
大括号({ })
文件名扩展
复制 t.txt 的内容到 t.back 中

vim test22.sh
输入代码:

#!/bin/bash

if [ ! -w ‘t.txt’ ];
then
touch t.txt
fi
echo ‘test text’ >> t.txt
cp t.{txt,back}
运行代码:

bash test22.sh
查看运行结果:

ls
cat t.txt
cat t.back
注意: 在大括号中,不允许有空白,除非这个空白被引用或转义。

代码块
代码块,又被称为内部组,这个结构事实上创建了一个匿名函数(一个没有名字的函数)。然而,与“标准”函数不同的是,在其中声明的变量,对于脚本其他部分的代码来说还是可见的。

vim test23.sh
输入代码:

#!/bin/bash

a=123
{ a=321; }
echo “a = $a”
运行代码:

bash test23.sh
a = 321
变量 a 的值被更改了。

中括号([ ])
条件测试
条件测试表达式放在 [ ] 中。下列练习中的 -lt (less than)表示小于号。

vim test24.sh
输入代码:

#!/bin/bash

a=5
if [ $a -lt 10 ]
then
echo “a: $a”
else
echo ‘a>=10’
fi
运行代码:

bash test24.sh
a: 5
数组元素
在一个 array 结构的上下文中,中括号用来引用数组中每个元素的编号。

vim test25.sh
输入代码:

#!/bin/bash

arr=(12 22 32)
arr[0]=10
echo ${arr[0]}
运行代码:

bash test25.sh
10
尖括号(< 和 >)
重定向
test.sh > filename:重定向 test.sh 的输出到文件 filename 中。如果 filename 存在的话,那么将会被覆盖。

test.sh &> filename:重定向 test.sh 的 stdout(标准输出)和 stderr(标准错误)到 filename 中。

test.sh >&2:重定向 test.sh 的 stdout 到 stderr 中。

test.sh >> filename:把 test.sh 的输出追加到文件 filename 中。如果 filename 不存在的话,将会被创建。

竖线(|)
管道
分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法。

破折号(-)
波浪号(~)
目录
表示 home 目录。
特殊变量
位置参数
从命令行传递到脚本的参数:$0,$1,$2,$3…

$0 就是脚本文件自身的名字,$1 是第一个参数,$2 是第二个参数,$3 是第三个参数,然后是第四个。9 之 后 的 位 置 参 数 就 必 须 用 大 括 号 括 起 来 了 , 比 如 , 9 之后的位置参数就必须用大括号括起来了,比如,9之后的位置参数就必须用大括号括起来了,比如,{10},11 , {11},11,{12}。

$# : 传递到脚本的参数个数
$* : 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9 个
$$ : 脚本运行的当前进程 ID 号
$! : 后台运行的最后一个进程的进程 ID 号
$@ : 与 $* 相同,但是使用时加引号,并在引号中返回每个参数
$: 显示 shell 使用的当前选项,与 set 命令功能相同
$? : 显示最后命令的退出状态。 0 表示没有错误,其他任何值表明有错误。

位置参数实例

vim test30.sh
#!/bin/bash

# 作为用例, 调用这个脚本至少需要10个参数, 比如:
# bash test.sh 1 2 3 4 5 6 7 8 9 10
MINPARAMS=10

echo

echo “The name of this script is \”$0\”.”

echo “The name of this script is \”`basename $0`\”.”

echo

if [ -n “$1” ] # 测试变量被引用.
then
echo “Parameter #1 is $1″ # 需要引用才能够转义”#”
fi

if [ -n “$2” ]
then
echo “Parameter #2 is $2”
fi

if [ -n “${10}” ] # 大于$9的参数必须用{}括起来.
then
echo “Parameter #10 is ${10}”
fi

echo “———————————–“
echo “All the command-line parameters are: “$*””

if [ $# -lt “$MINPARAMS” ]
then
echo
echo “This script needs at least $MINPARAMS command-line arguments!”
fi

echo

exit 0

运行代码:

bash test30.sh 1 2 10

The name of this script is “test.sh”.
The name of this script is “test.sh”.

Parameter #1 is 1
Parameter #2 is 2
———————————–
All the command-line parameters are: 1 2 10

This script needs at least 10 command-line arguments!
基本运算符
算数运算符

vim test.sh

#!/bin/bash

a=10
b=20

val=`expr $a + $b`
echo “a + b : $val”

val=`expr $a – $b`
echo “a – b : $val”

val=`expr $a \* $b`
echo “a * b : $val”

val=`expr $b / $a`
echo “b / a : $val”

val=`expr $b % $a`
echo “b % a : $val”

if [ $a == $b ]
then
echo “a == b”
fi
if [ $a != $b ]
then
echo “a != b”
fi

运行

bash test.sh

a + b : 30
a – b : -10
a * b : 200
b / a : 2
b % a : 0
a != b

原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
注意使用的反引号(esc 键下边)
表达式和运算符之间要有空格 $a + $b 写成 a + a+a+b 不行
条件表达式要放在方括号之间,并且要有空格 [ $a == b ] 写 成 [ b ] 写成 [b]写成[a==$b] 不行
乘号(*)前边必须加反斜杠()才能实现乘法运算

关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

#!/bin/bash

a=10
b=20

if [ $a -eq $b ]
then
echo “$a -eq $b : a == b”
else
echo “$a -eq $b: a != b”
fi

逻辑运算符

#!/bin/bash
a=10
b=20

if [[ $a -lt 100 && $b -gt 100 ]]
then
echo “return true”
else
echo “return false”
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
echo “return true”
else
echo “return false”
fi

字符串运算符

#!/bin/bash

a=”abc”
b=”efg”

if [ $a = $b ]
then
echo “$a = $b : a == b”
else
echo “$a = $b: a != b”
fi
if [ -n $a ]
then
echo “-n $a : The string length is not 0”
else
echo “-n $a : The string length is 0”
fi
if [ $a ]
then
echo “$a : The string is not empty”
else
echo “$a : The string is empty”
fi

结果

abc = efg: a != b
-n abc : The string length is not 0
abc : The string is not empty

文件测试运算符

实例:

#!/bin/bash

file=”/home/shiyanlou/test.sh”
if [ -r $file ]
then
echo “The file is readable”
else
echo “The file is not readable”
fi
if [ -e $file ]
then
echo “File exists”
else
echo “File not exists”
fi

结果

The file is readable
File exists

思考
浮点运算,比如实现求圆的面积和周长。
expr 只能用于整数计算,可以使用 bc 或者 awk 进行浮点数运算。

#!/bin/bash

radius=2.4

pi=3.14159

girth=$(echo “scale=4; 3.14 * 2 * $radius” | bc)

area=$(echo “scale=4; 3.14 * $radius * $radius” | bc)

echo “girth=$girth”

echo “area=$area”

以上代码如果想在环境中运行,需要先安装 bc。

sudo apt-get update
sudo apt-get install bc

流程控制
if else
if
if 语句语法格式:

if condition
then
command1
command2

commandN
fi

if else
if else 语法格式:

if condition
then
command1
command2

commandN
else
command
fi

if-elif-else 语法格式:

if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

for 循环
for 循环一般格式为:

for var in item1 item2 … itemN
do
command1
command2

commandN
done

while 语句
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while condition
do
command
done

无限循环
无限循环语法格式:

while :
do
command
done
或者
while true
do
command
done

或者

for (( ; ; ))

until 循环
until 循环执行一系列命令直至条件为真时停止。 until 循环与 while 循环在处理方式上刚好相反。 一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。 until 语法格式:

until condition
do
command
done

case
Shell case 语句为多选择语句。可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case 语句格式如下:

case 值 in
模式1)
command1
command2

commandN
;;
模式2)
command1
command2

commandN
;;
esac

取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

下面的脚本提示输入 1 到 4,与每一种模式进行匹配:

echo ‘Enter a number between 1 and 4:’
echo ‘The number you entered is:’
read aNum
case $aNum in
1) echo ‘You have chosen 1’
;;
2) echo ‘You have chosen 2’
;;
3) echo ‘You have chosen 3’
;;
4) echo ‘You have chosen 4’
;;
*) echo ‘You did not enter a number between 1 and 4’
;;
esac

输入不同的内容,会有不同的结果,例如:

Enter a number between 1 and 4:
The number you entered is:
3
You have chosen 3

跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell 使用两个命令来实现该功能:break 和 continue。

break 命令

break 命令允许跳出所有循环(终止执行后面的所有循环)。

下面的例子中,脚本进入死循环直至用户输入数字大于 5。要跳出这个循环,返回到 shell 提示符下,需要使用 break 命令。

#!/bin/bash
while :
do
echo -n “Enter a number between 1 and 5:”
read aNum
case $aNum in
1|2|3|4|5) echo “The number you entered is $aNum!”
;;
*) echo “The number you entered is not between 1 and 5! game over!”
break
;;
esac
done

执行以上代码,输出结果为:

Enter a number between 1 and 5:3
The number you entered is 3!
Enter a number between 1 and 5:7
The number you entered is not between 1 and 5! game over!

continue
continue 命令与 break 命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 对上面的例子进行修改:

#!/bin/bash
while :
do
echo -n “Enter a number between 1 and 5: “
read aNum
case $aNum in
1|2|3|4|5) echo “The number you entered is $aNum!”
;;
*) echo “The number you entered is not between 1 and 5!”
continue
echo “game over”
;;
esac
done

运行代码发现,当输入大于 5 的数字时,该例中的循环不会结束,语句 echo “Game is over!” 永远不会被执行。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31899.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信