注:
vi 文件名.sh
chmod +x ./文件名.sh
./文件名.sh
在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:
#!/bin/bash
在通常的shell脚本中,井号(#)用作注释行。shell并不会处理shell脚本中的注释行。但是,shell脚本文件的第一行是个例外,#后面的惊叹号会告诉shell用哪个shell来运行脚本。
第一个脚本:
#!/bin/bash
echo "hello, shell"
让shell找到你写的文件,有两种方式:
1) 将shell脚本文件所处的目录添加到PATH环境变量中;
2) 在提示符中用绝对或相对文件路径来引用shell脚本文件。
想运行脚本,还需要有执行此文件的权限,可以用 ls -l 文件名
查看权限,然后使用 chmod +x 文件名
赋予文件被执行的权限。下面就可以在文件所在的目录下用 ./文件名
来执行文件了。
#!/bin/bash
num=123
echo "$num"
echo "${num}"
#!/bin/bash
url="www.baidu.com"
readonly url
str="qwer"
unset str
1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
#!/bin/bash
str="\"qwer\"" # 转义字符
echo `$str`
echo $str
echo -e "this is a string! \n" # -e 开启转义
echo -e "this is a test \c string" # -e 开启转义,\c 不换行
string="abcdefg"
echo ${#string} # 获取字符串长度
echo ${#string0} # 获取字符串长度
echo ${string:1:4} # 截取字符串
echo `expr index "$string" ce` # 查找字符 c 或 e 的位置(哪个字母先出现就计算哪个)
echo `date`
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。如"\$*"用「"」括起来的情况、以"\$1 \$2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与\$*相同,但是使用时加引号,并在引号中返回每个参数。如"\$@"用「"」括起来的情况、以"\$1" "\$2" … "\$n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "传递到脚本的参数个数:$#"
echo "以字符串显示所有参数:$*"
echo "显示所有参数:$@"
#!/bin/bash
my_array=(A,b,"C",D)
my_array[4]="E"
echo "第一个元素:${my_array[0]}"
echo "第二个元素:${my_array[1]}"
echo "数组的所有元素:${my_array[*]}"
echo "数组的所有元素:${my_array[@]}"
echo "数组的长度:${#my_array[*]}"
echo "数组的长度:${#my_array[@]}"
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | \ |
- | 减法 |
|
\* | 乘法 |
|
/ | 除法 |
|
% | 取余 |
|
= | 赋值 | a=$b 把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | $a == $b 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | $a != $b 返回 true。 |
#!/bin/bash
a=10
b=20
add=`expr $a + $b`
subtract=`expr $b - $a`
mul=`expr $b \* $a`
division=`expr $b / $a`
remainder=`expr $b % $a`
echo "$b和$a 两个数 相加:$add,相减:$subtract,相乘:$mul,相除:$division,取余:$remainder"
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | \$a -eq \$b |
-ne | 检测两个数是否不相等,不相等返回 true。 | \$a -ne \$b |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | \$a -gt \$b |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | \$a -lt \$b |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | \$a -ge \$b |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | \$a -le \$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
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | ! false |
-o | 或运算,有一个表达式为 true 则返回 true。 | \$a -lt 20 -o \$b -gt 100 |
-a | 与运算,两个表达式都为 true 才返回 true。 | \$a -lt 20 -a \$b -gt 100 |
#!/bin/bash
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | \$a -lt 100 && \$b -gt 100 |
|| | 逻辑的 OR | \$a -lt 100 || \$b -gt 100 |
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | \$a = \$b |
!= | 检测两个字符串是否不相等,不相等返回 true。 | \$a != \$b |
-z | 检测字符串长度是否为0,为0返回 true。 | -z \$a |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | -n "\$a" |
$ | 检测字符串是否为空,不为空返回 true。 | \$a |
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | -b \$file |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | -c \$file |
-d file | 检测文件是否是目录,如果是,则返回 true。 | -d \$file 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | -f \$file |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | -g \$file |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | -k \$file |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | -p \$file |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | -u \$file |
-r file | 检测文件是否可读,如果是,则返回 true。 | -r \$file |
-w file | 检测文件是否可写,如果是,则返回 true。 | -w \$file |
-x file | 检测文件是否可执行,如果是,则返回 true。 | -x \$file |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | -s \$file |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | -e \$file |
#!/bin/bash
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
序列 | 说明 |
---|---|
\a | 警告字符,通常为ASCII的BEL字符 |
\b | 后退 |
\c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f | 换页(formfeed) |
\n | 换行 |
\r | 回车(Carriage return) |
\t | 水平制表符 |
\v | 垂直制表符 |
\ | 一个字面上的反斜杠字符 |
\ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
\0ddd | 表示1到3位的八进制值字符 |
#!/bin/bash
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
#!/bin/bash
a=10
b=20
if $a == $b
then
echo "a 等于 b"
elif $a -gt $b
then
echo "a 大于 b"
elif $a -lt $b
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
# if else 语句经常与 test 命令结合使用
if test $a -eq $b
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi
#!/bin/bash
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
#!/bin/bash
a=0
until ! $a -lt 10
do
echo $a
a=`expr $a + 1`
done
#!/bin/sh
site="runoob"
case "$site" in
"runoob") echo "菜鸟教程"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac
函数创建有两种格式,第一种格式采用关键字function,后跟分配给该代码块的函数名。第二种格式是函数名后跟空括号。
#!/bin/bash
# 格式一
function name {
commands
}
# 格式二
name() {
commands
}
使用函数,只需要在shell文本中指定需要使用的函数名就行了,但一定要在使用之前先定义函数,然后才能在使用的时候找到这个函数。
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "第二个数字: $1"
echo "两个数字分别为 $aNum 和 $1 !"
return $(($aNum+$1))
}
funWithReturn 5
echo "输入的两个数字之和为 $? !"
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量\$?来确定函数的退出状态码。
#!/bin/bash
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function: "
func1
echo "The exit status is: $?"
因为函数中的最后一条命令没有成功运行。无法知道函数中其他命令中是否成功运行。
#!/bin/bash
func1() {
echo "trying to display a non-existent file"
ls -l badfile
echo "This was a test of a bad command"
}
echo "testing the function: "
func1
echo "The exit status is: $?"
这个函数最后一条语句echo运行成功,该函数的退出状态码就是0,尽管其中有一条命令并没有正常运行。
bash shell使用return命令来退出函数并返回特定的退出状态码。
#!/bin/bash
# using the return command in a function
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?"
记住,函数一结束就取返回值;
记住,退出状态码必须是0~255。
如果在用\$?变量提取函数返回值之前执行了其他命令,函数的返回值就会丢失。记住,\$?变量会返回执行的最后一条命令的退出状态码。
第二个问题界定了返回值的取值范围。由于退出状态码必须小于256,函数的结果必须生成一个小于256的整数值。任何大于256的值都会产生一个错误值。
#!/bin/bash
# using the echo to return a value
function dbl {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(dbl)
echo "The new value is $result"
函数会用echo语句来显示计算的结果。该脚本会获取dbl函数的输出,而不是查看退出状态码。
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在\$0变量中定义,函数命令行上的任何参数都会通过\$1、\$2等定义。也可以用特殊变量\$#来判断传给函数的参数数目。
#!/bin/bash
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "Adding 10 and 15: "
value=$(addem 10 15)
echo $value
echo -n "Let's try adding just one number: "
value=$(addem 10)
echo $value
echo -n "Now trying adding no numbers: "
value=$(addem)
echo $value
echo -n "Finally, try adding three numbers: "
value=$(addem 10 15 20)
echo $value
#!/bin/bash
# trying to access script parameters inside a function
function func7 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(func7 $1 $2)
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
通过将\$1和\$2变量传给函数,它们就能跟其他变量一样供函数使用了。
#!/bin/bash
function func1 {
local temp=$[ $value + 5 ] # 不影响外部全局变量
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
#!/bin/bash
function testit {
local newarray
newarray=(;'echo "$@"')
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
该脚本用\$myarray变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数组变量。在函数内部,数组仍然可以像其他数组一样使用。
#!/bin/bash
function arraydblr {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@"))
newarray=($(echo "$@"))
elements=$[ $# - 1 ]
for (( i = 0; i <= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2 ]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(arraydblr $arg1))
echo "The new array is: ${result[*]}"
该脚本用\$arg1变量将数组值传给arraydblr函数。arraydblr函数将该数组重组到新的数组变量中,生成该输出数组变量的一个副本。然后对数据元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。
arraydblr函数使用echo语句来输出每个数组元素的值。脚本用arraydblr函数的输出来重新生成一个新的数组变量。
#!/bin/bash
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=$(factorial $temp)
echo $[ $result * $1 ]
fi
}
read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"
当一个函数需要重复使用时,可以单独写入一个文件。
创建两个shell脚本文件
test1.sh
#!/bin/bash
url="http://www.runoob.com"
function addem {
echo $[ $1 + $2 ]
}
test2.sh
#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh # 被包含的文件 test1.sh 不需要可执行权限。
# 或者使用以下包含文件代码
# source ./test1.sh
echo "菜鸟教程官网地址:$url"
result=$(addem 10 15)
echo "The result is $result"
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。