Shell简介
Shell自身是一个用C语言编写的程序,是用户来使用Unix或Linux的桥梁,用户的大部分工作都需要通过Shell来完成。只有熟练使用shell,才能熟练掌握linux。 可以说:Shell既是一种命令语言,又是一种程序设计语言。 Shell虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式来协调各个程序的运行。 因此,对于使用者来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。
这里归纳总结了一些常见常用重要的shell命令,方便在使用遗忘时查阅。
转义字符
| 转义字符 | 含义 |
|---|---|
| \ | 反斜杠 |
| \a | 警报,响铃 |
| \b | 退格(删除键) |
| \f | 换页(FF),将当前位置移到下页开头 |
| \n | 换行 |
| \r | 回车 |
| \t | 水平制表符(tab键) |
| \v | 垂直制表符 |
变量替换
变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值,可以使用的变量替换形式:
| 形式 | 说明 |
|---|---|
| ${var} | 变量本来的值 |
| ${var:-word} | 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 |
| ${var:=word} | 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 |
| ${var:?message} | 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。 |
| ${var:+word} | 如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
算术运算符列表
| 运算符 | 说明 | 举例 |
|---|---|---|
| + | 加法 | expr $a + $b 结果为 30。 |
| - | 减法 | expr $a - $b 结果为 10。 |
| * | 乘法 | expr $a \* $b 结果为 200。 |
| / | 除法 | expr $b / $a 结果为 2。 |
| % | 取余 | expr $b % $a 结果为 0。 |
| = | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
| == | 相等。用于比较两个数字,相同则返回 true。 | [ |
| != | 不相等。用于比较两个数字,不相同则返回 true。 | [ |
关系运算符列表
| 运算符 | 说明 | 举例 |
|---|---|---|
| -eq | 检测两个数是否相等,相等返回 true。 | [ |
| -ne | 检测两个数是否相等,不相等返回 true。 | [ |
| -gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ |
| -lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ |
| -ge | 检测左边的数是否大等于右边的,如果是,则返回 true。 | [ |
| -le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ |
文件测试运算符列表
| 操作符 | 说明 | 举例 |
|---|---|---|
| -b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
| -c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
| -d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
| -f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
| -g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
| -p file | 检测文件是否是具名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
| -u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
| -r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
| -w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
| -x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
| -s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
| -e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
布尔运算符列表
| 运算符 | 说明 | 举例 |
|---|---|---|
| ! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
| -o | 或运算,有一个表达式为 true 则返回 true。 | [ |
| -a | 与运算,两个表达式都为 true 才返回 true。 | [ |
特殊变量列表
| 变量 | 含义 |
|---|---|
| $0 | 当前脚本的文件名 |
| $n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
| $# | 传递给脚本或函数的参数个数。 |
| $* | 传递给脚本或函数的所有参数。 |
| $@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
| $? | 上个命令的退出状态,或函数的返回值。 |
| ? | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
数值测试
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
| 参数 | 说明 |
|---|---|
| -eq | 等于则为真 |
| -ne | 不等于则为真 |
| -gt | 大于则为真 |
| -ge | 大于等于则为真 |
| -lt | 小于则为真 |
| -le | 小于等于则为真 |
文件测试
| 参数 | 说明 |
|---|---|
| -e 文件名 | 如果文件存在则为真 |
| -r 文件名 | 如果文件存在且可读则为真 |
| -w 文件名 | 如果文件存在且可写则为真 |
| -x 文件名 | 如果文件存在且可执行则为真 |
| -s 文件名 | 如果文件存在且至少有一个字符则为真 |
| -d 文件名 | 如果文件存在且为目录则为真 |
| -f 文件名 | 如果文件存在且为普通文件则为真 |
| -c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
| -b 文件名 | 如果文件存在且为块特殊文件则为真 |
函数
Shell 函数的定义格式如下:
function_name () {
list of commands
[ return value ]
}
如果你愿意,也可以在函数名前加上关键字 function:
function function_name () {
list of commands
[ return value ]
}
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。 Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。 如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
删除变量一样,可以使用 unset 命令,删除函数也可以使用这个命令,不过要加上 .f 选项,如下所示
$unset .f function_name
重定向
命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。 命令输出重定向的语法为:
$ command > file
输入重定向 和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:
command < file
全部可用的重定向命令列表
| 命令 | 说明 |
|---|---|
| command > file | 将输出重定向到 file。 |
| command < file | 将输入重定向到 file。 |
| command >> file | 将输出以追加的方式重定向到 file。 |
| n > file | 将文件描述符为 n 的文件重定向到 file。 |
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
| n >& m | 将输出文件 m 和 n 合并。 |
| n <& m | 将输入文件 m 和 n 合并。 |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1
Shell文件包含
Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。 Shell 中包含脚本可以使用:
. filename
或
source filename
两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。
单引号
str='this is a string'
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的 单引号字串中不能出现单引号(对单引号使用转义符后也不行) 双引号
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
双引号里可以有变量 双引号里可以出现转义字符 字符串操作 拼接字符串
your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
获取字符串长度:
string="abcd"
echo ${#string} #输出:4
提取子字符串
string="alibaba is a great company"
echo ${string:1:4} #输出:liba
if
if condition
then
command1
command2
...
commandN
fi
写成一行(适用于终端命令提示符):
if `ps -ef | grep ssh`; then echo hello; fi
末尾的fi就是if倒过来拼写,后面还会遇到类似的
if else
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
if condition1
then
command1
elif condition2
command2
else
commandN
fi
for while
for
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
写成一行:
for var in item1 item2 ... itemN; do command1; command2… done;
C风格的for
for (( EXP1; EXP2; EXP3 ))
do
command1
command2
command3
done
while
while condition
do
command
done
无限循环
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
until
until condition
do
command
done
case
case "${opt}" in
"Install-Puppet-Server" )
install_master $1
exit
;;
"Install-Puppet-Client" )
install_client $1
exit
;;
"Config-Puppet-Server" )
config_puppet_master
exit
;;
"Config-Puppet-Client" )
config_puppet_client
exit
;;
"Exit" )
exit
;;
* ) echo "Bad option, please choose again"
esac
case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break
删除变量
使用 unset 命令可以删除变量。语法:
unset variable_name
显示结果重定向至文件
echo "It is a test" > myfile
原样输出字符串
若需要原样输出字符串(不进行转义),请使用单引号。例如:
echo '$name\"'
显示命令执行结果
echo `date`
printf 命令
printf 命令用于格式化输出 printf 不像 echo 那样会自动换行,必须显式添加换行符(\n)。
printf 命令的语法:
printf format-string [arguments...]
format-string 为格式控制字符串,arguments 为参数列表。
C语言printf()函数的不同:
printf 命令不用加括号
format-string 可以没有引号,但最好加上,单引号双引号均可。
参数多于格式控制符(%)时,format-string 可以重用,可以将所有参数都转换。
arguments 使用空格分隔,不用逗号。
命令行参数
运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。
@ 的区别
@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "
n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1
n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "
n" 的形式输出所有参数。