Shell
变量包括自定义变量和环境变量:
Shell
程序不能访问到;PATH
,所有 Shell
程序都能访问到,也可以通过 env
查看所有环境变量。wohu@ubuntu-dev:~$ env | grep -i shell
SHELL=/bin/bash # 当前用户 Shell 类型
wohu@ubuntu-dev:~$ env | grep HOME
HOME=/home/wohu # 当前用户主目录
wohu@ubuntu-dev:~$ env | grep LANG
LANG=en_US.UTF-8 # 操作系统字符集
GDM_LANG=en_US
LANGUAGE=en_US
wohu@ubuntu-dev:~$
变量名 | 说明 |
---|---|
$PWD | 脚本执行的当前所在目录 |
$UID | 当前操作的系统用户 ID |
$$ | 当前操作用户的 PID |
$# | 当前脚本的参数个数 |
$* | 当前脚本的所有参数 |
$0 | 当前执行程序的名称 |
$n | 当前程序的第 N 个参数 |
$HOME | 当前程序的 home 目录 |
$USER | 查询当前程序使用的操作用户 |
变量名由字母、数字、下划线组成,只能以字母或者下划线开头,不能使用 Shell
的保留字。不能使用空格、不能使用标点符号。
hello.sh
脚本,扩展名不影响执行:#!/bin/bash
#自定义变量 hello
hello="Hello world!"; //注意等号两边不能有空格
echo $hello;
给 hello.sh
脚本赋予执行权限:chmod +x hello.sh
。
调用脚本 ./hello.sh
,hello.sh
的前面需要加上 ./
,这是因为不加上的话会去 PATH
下查找是否有对应的命令可以执行,而 PATH
下只有 /bin
、/sbin
、/usr/bin
、/usr/sbin
,通常当前目录不在 PATH
下,就会提示 comman not found
,所以要用 ./
告诉系统在当前目录下查找。
# 变量名=值
如:A=1 等号两边不要有空格,如果值中间存在空格,请使用单引或者双引号:A='张 三'
# 撤销变量
unset A
# 定义静态变量,静态变量不可以二次赋值,静态变量不可以 unset 撤销
readonly B=2
使用 unset
命令可以删除变量:
unset variable_name
例如:
#!/bin/bash
hello="Hello world!"
echo "hello="$hello
unset hello
echo "hello="$hello
输出结果:
[oracle@195 ~]$ ./hello.sh
hello=Hello world!
hello=
普通的变量作用域为当前的执行程序,程序外部不可使用当前定义的变量。通过 export
可以把变量升级为全局环境变量,这样当前系统所有程序都可以使用这个环境变量。
export name="wohu"
测试文件,会输出 “wohu”
#!/bin/bash
echo $name
由于定义了全局变量,所以执行脚本可以正常输出 $name
变量的值,反之脚本中定义的局部变量,在其它脚本中不能引用。
Shell
中最常用的数据类型就是字符串和数字,除此之外也没有数据类型了,在 Shell
中字符串可以用单引号或者双引号来包围,如: '/home/ubuntu'
、"/home/ubuntu"
、/home/ubuntu
也可以没有引号包围。
两者的区别在于:
如:echo 'hello ${name}'
,会输出:hello ${name}
;
如:
wohu@ubuntu-dev:~$ name="wohu"
wohu@ubuntu-dev:~$ echo "hello ${name}"
hello wohu
wohu@ubuntu-dev:~$
综上,当有变量时最好是使用双引号包围字符串,且变量最好有 {}
包围,明确变量名,这也是最佳编程实践。
获取字符串长度的方式有两种:
${#string_name}
expr length string_name
示例:
#!/bin/bash
hello="Hello world!"
echo "length of hello is:"${#hello}
expr length "$hello"
输出结果:
length of hello is:12
12
使用 #
截取右边字符,方式为 ${hello#*chars}
,例如:
#!/bin/bash
hello="Hello world!"
echo ${hello#*o}
输出:
world!
表明截取了从左到右第一个 o
右边的字符串,*chars
代表忽略 chars
左边任意长度的字符串(包括 chars
)。如果不写星号,那么就不会忽略 chars
左边的字符串。
#!/bin/bash
hello="Hello world!"
echo ${hello#o}
输出:
Hello world!
使用 %
截取左边字符串,方式为:${hello%chars_}_
_。与 _#_
不同的是,这里_在右边,代表忽略 chars
右边的任意长度字符串,来截取 chars
左边的字符串,其用法跟 #
类似。
看个例子:
#!/bin/bash
hello="Hello world!"
echo ${hello%o*}
输出:
Hello w
Shell
数组只能是一维的,不支持多维数组,并且 Shell
是弱类型的,数组中的类型不一定只有一种,且不限制数组的长度大小,理论上可以是无限大小。
#!/bin/bash
#创建数组
array=(a b c d e)
#获取数组长度
length1=${#array[@]}
echo "length1=${length1}"
#另一种获取数组长度方法
length2=${#array[*]}
echo "length2=${length2}"
#获取第三个元素
echo ${array[2]}
#删除第二个元素
unset array[1]
#输出整个数组
echo ${array[@]}
#for 遍历整个数组
for i in ${array[@]}
do
echo $i
done;
#删除整个数组
unset array
#查看是否已删除
for i in ${array[@]}
do
echo $i
done;
输出:
length1=5
length2=5
c
a c d e
a
c
d
e
包括:+
、-
、*
、/
、%
、=
、==
、!=
,这些跟我们其他编程语言遇到的是一样的,举个简单例子。
#!/bin/bash
a=1;
b=2;
c=`expr $a + $b`;
echo "total is: ${c}";
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
输出:
total is: 3
运算符 | 说明 |
---|---|
-eq | 判断两个数据是否相等 |
-nq | 判断两个数据是否不相等 |
-gt | 判断左边的数据是否大于右边的数据 |
-lt | 判断左边的数据是否小于右边的数据 |
-ge | 判断左边的数据是否大于等于右边的数据 |
-le | 判断左边的数据是否小于等于右边的数据 |
#!/bin/bash
a=100;
b=99;
if [ $a -eq $b ]
then
echo "A"
else
echo "B"
fi
输出:B
运算符 | 说明 |
---|---|
&& | 逻辑与,左右两边的表达式都为 true 才 true,有一个为 false 则为 false |
接下来看下程序
#!/bin/bash
a=100;
b=99;
c=90;
if [[ $a -gt $b && $a -gt $c ]]
then
echo "A"
elif [[ $b -gt $a && $b -gt $c ]]
then
echo "B"
else
echo "C"
fi
输出:A
运算符 | 说明 |
---|---|
! | 非运算,对表达式取反,如:[ !false ] 返回 false |
-o | 或运算,左右两边的表达式存在 true 则为 true,都为 false 则为 false |
-a | 与运算,左右两边的表达式存在 false 则为 false,都为 true 则为 true |
接下来看下程序
#!/bin/bash
a=100;
b=99;
c=90;
if !((a == b))
then
echo "a 与 b 不相等"
else
echo "a 与 b 相等"
fi
if [ $a -gt $b -a $a -gt $c ]
then
echo "A"
elif [ $b -gt $a -a $b -gt $c ]
then
echo "B"
else
echo "C"
fi
输出:
a 与 b 不相等
A
-a
与 -o
用法相同。
运算符 | 说明 |
---|---|
= | 检测两个字符串是否相等,相等返回 true |
!= | 检测两个字符串是否不相等,不相等则返回 true |
-z | 检测字符串长度是否为 0,为 0 则返回 true |
-n | 检测字符串长度是否为 0,不为 0 则返回 true |
$ | 检测字符串是否为空,不为空则返回 true |
#!/bin/bash
a="zoom"
b=""
if [ -n $a ]
then
echo "a 长度不为 0"
else
echo "a 长度为 0"
fi
if [ -z $b ]
then
echo "b 长度为 0"
else
echo "b 长度不为 0"
fi
if [ $b ]
then
echo "b 不为空字符串"
else
echo "b 是空字符串"
fi
输出:
a 长度不为 0
b 长度为 0
b 是空字符串
#!/bin/bash
if conditionA
then
exprA
elif conditionB
then
exprB
else
exprC
fi
这就是 if-elif-else
,最后别忘了 fi
作为结尾。Shell
的 if
不能有空语句,即什么都不做的条件表达式。还有一点是 condition
一般用中括号 []
,Java
都是用小括号 ()
。
for
循环语句的基本语法是:
#!/bin/bash
for loop in item1 item2 ... itemN
do
condition1
condition2
...
conditionP
done
其中,for loop in 1 2 3 4 5
可被替换成 for loop in {1..5}
。以及 类似于 C 中的 for
条件语句写法:for((i=0;i<=5;i++))
。
#!/bin/bash
for((i=0;i<=5;i++))
do
echo "num is ${i}"
done
输出:
num is 0
num is 1
num is 2
num is 3
num is 4
num is 5
基本语法是:
#!/bin/bash
while conditionA
do
commandA
done
看个例子:
#!/bin/bash
i=0
while(( i<=5 ))
do
echo "num is ${i}"
let i++
done
while
语句还可以用来接收用户输入,用法是:
while read choose
无限循环是经常会用到的一个语法,下面列举了无限循环的三种实现方式:
*)
表示默认模式,相当于 default
,;;
表示命令序列结束,相当于 break
。
!/bin/bash
case $1 in
"1")
echo "张三"
;;
"2")
echo "李四"
;;
*)
echo "王二"
;;
esac
basename 路径 后缀
功能描述:basename
命令会删掉所有的前缀包括最后一个 /
字符,然后将字符串显示出来。
wohu@ubuntu-dev:~/git_demo$ basename /home/wohu/git_demo/
git_demo
wohu@ubuntu-dev:~/git_demo$
wohu@ubuntu-dev:~/git_demo$ basename /home/wohu/git_demo/demo.sh .sh
demo
wohu@ubuntu-dev:~/git_demo$
dirname 文件绝对路径
功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)。
wohu@ubuntu-dev:~/git_demo$ dirname /home/wohu/git_demo/demo.sh
/home/wohu/git_demo
wohu@ubuntu-dev:~/git_demo$
#!/bin/bash
printnum()
{
echo "my first function"
}
echo "call funtion start"
printnum
echo "call funtion end"
输出:
call funtion start
my first function
call funtion end
这个是不带参数没有返回值的例子,接下来我们来看看不带参数没有返回值的例子:
#!/bin/bash
plusnum()
{
a=1
b=3
return $((a+b))
}
plusnum
echo "a+b="$?
从上面我们可以看出,在调用函数后,通过 $?
可以拿到返回结果。而调用方式是直接用函数名即可,不需要加上括号,这点跟 Java 和其他面向对象的编程语言都有所不同。
下面再看一个有参数的函数:
#!/bin/bash
plusnum()
{
a=$1
b=$2
return $((a+b))
}
plusnum 99 100
echo "a+b="$?
从上面我们可以看到函数 plusnum 中通过 $1
和 $2
获取传入的参数,在相加后返回结果,调用时直接跟在函数后面,并不像 Java 的函数传参。
注意事项:
Shell
脚本是逐行运行。不会像其它语言一样先编译。$?
系统变量获得,可以显式地加 return
返回,如果不加,将以最后一条命令运行结果,作为返回值。return
后跟数值 n
(0~255)。示例:
#!/bin/bash
function sum()
{
s=0
s=$[ $1 + $2 ]
echo "$s"
}
# read 读取控制台的输入,n1, n2 用于接收输入内容,
# -p:指定读取值时的提示符;
# -t:指定读取值时等待的时间(秒)
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
# 调用方法
sum $n1 $n2;