shell简介
Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。
他不是Unix/Linux系统内核的一部分,但是他调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序。
可以说,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度。
Shell的两种执行命令的方式:
- 交互式:解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
- 批处理:用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。
几种常见的Shell
Shell是一种脚本语言,就必须有解释器来执行这些脚本。
Unix/Linux
上常见的Shell脚本编译器有bash
、sh
、csh
、ksh
等,习惯上把它们称为一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。
bash
:是Linux标准默认的shell,内部命令一共有40种。
sh
:是Unix标准默认的shell。(bash完全兼容sh,所以用sh写的脚本可以不加修改的在bahs中执行)。
ash
:是Linux中占用系统资源最少的一个shell,只包含24个内部命令,因而使用起来不方便。
csh
:是Linux比较大的内核,共有52个内部命令。
第一个Shell脚本
#!/bin/bash
echo "Hello World !"
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。
运行Shell脚本有两种方法
1、作为可执行程序
将上边的代码保存为test.sh
,并cd
到相应目录:
chmod +x ./test.sh #给该脚本增加可执行的权限
./test.sh # 执行脚本
注意:通过这种方式运行bash脚本,第一行一定要写对,好让系统查找到正确的解释器。
2、作为解释器参数
/bin/sh test.sh
/bin/php test.php
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
#!/bin/bash
# Author : JonnyYue
echo "What is your name?"
read PERSON
echo "Hello ,$PERSON"
chmod +x ./test.sh
$./test.sh
输出:
What is your name?
mozhiyan
Hello, mozhiyan
Shell变量
定义变量
定义变量时,变量名不加美元符号。
变量名 = “value”
注意:变量名和等号之间不能有空格。
变量名的命名规则遵循如下规则:
- 首个字母必须有字母(a-z、A-Z)
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号。
- 不能使用
bash
里的关键字
使用变量
使用一个已经定义过的变量,只需要在变量名前面加上美元符号$就可以了。
a="hello"
echo $a
echo ${a}
变量名后面的{}
是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
${name}is a boy
如果不给name加上花括号,解释器就会把nameis 当作一个变量。
重新定义变量
已定义的变量,可以被重新定义。
your_name="tom"
echo $your_name
your_name="alibaba" #不能加$
echo $your_name
只读变量
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
删除变量
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
变量类型
有三种类型:
- 局部变量
- 仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
- 环境变量
- 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
- shell变量
- shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
特殊变量
变量 | 含义 |
---|---|
$0 |
当前脚本的文件名 |
$n |
传递给脚本或函数的参数。n是一个数字,表示第几个参数。 |
$# |
传递给脚本或函数的参数个数 |
$* |
传递给脚本或函数的所有参数 |
$@ |
传递给脚本或函数的所有参数 |
$? |
上个命令的退出状态,或函数的返回值。 |
$$ |
当前Shell进程的ID。对于Shell脚本,就是这些脚本所在的进程ID |
命令行参数
运行脚本时传递给脚本的参数称为命令行参数。
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
运行结果:
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2
*和@的区别
∗
和@
都表示传递给函数或脚本的所有参数,不被双引号(" “)包含时,都以"1"“2” … “$n” 的形式输出所有参数。
但是当它们被双引号(” ")包含时,“∗"会将所有的参数作为一个整体,以"1 2…n"的形式输出所有参数;”@“会将各个参数分开,以"1” “2”…“n” 的形式输出所有参数。
下面的例子可以清楚的看到 ∗和@ 的区别:
#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\$@=" $@
echo "\"\$@\"=" "$@"
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \$@"
for var in $@
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"
执行 ./test.sh "a" "b" "c" "d"
,看到下面的结果::
$*= a b c d
"$*"= a b c d
$@= a b c d
"$@"= a b c d
print each param from $*
a
b
c
d
print each param from $@
a
b
c
d
print each param from "$*"
a b c d
print each param from "$@"
a
b
c
d
退出状态
$?
可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。
退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。
Shell 替换
如果表达式中包含特殊字符,Shell将会进行替换。比如转义字符
下面的转义字符都可以用在echo
中:
转义字符 | 含义 |
---|---|
\\ |
反斜杠 |
\a |
警报,响铃 |
\b |
退格(删除键) |
\f |
换页(FF),将当前位置移到下页开头 |
\n |
换行 |
\r |
回车 |
\t |
水平制表符(tab键) |
\v |
垂直制表符 |
可以使用echo -e
来禁止转义,默认也是不转义的。
命令替换
命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。
命令替换的语法:
`command` # 注意是反引号,而不是单引号。
#!/bin/bash
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"
运行结果:
Date is Thu Jul 2 03:59:57 MST 2009
Logged in user are 1
Uptime is Thu Jul 2 03:59:57 MST 2009
03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
变量替换
变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。
可以使用的变量替换形式:
形式 | 说明 |
---|---|
${var} |
变量本来的值 |
${var:-word} |
如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 |
${var:=word} |
如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 |
${var:?message} |
如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。 若此替换出现在Shell脚本中,那么脚本将停止运行。 |
${var:+word} |
如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
#!/bin/bash
echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"
echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"
unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"
var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"
echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"
运行结果:
Variable is not set
1 - Value of var is
Variable is not set
2 - Value of var is Variable is not set
3 - Value of var is
This is default value
4 - Value of var is Prefix
Prefix
5 - Value of var is Prefix