Shell 简介
Shell是用户和 Linux操作系统之间的接口, 也可以看作是命令行的解释器.
常见的 Shell Script解释器有:
- sh: 即 Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。
- bash: Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。
- zsh: zsh是由Paul Falstad于1990年创建的,它是一个Bourne风格的shell,它包含了bash中的功能,甚至更多。 例如,zsh具有拼写检查功能,可以监视登录/注销,某些内置编程功能(如字节码),支持语法中的科学计数,允许浮点运算和更多功能。
Shell 脚本文件开头一般会声明用哪种脚本解释器:
#!/bin/bash |
如何切换Shell
切换到 zsh:
chsh -s /bin/zsh |
切换到 bash:
chsh -s /bin/bash |
变量, 数据类型
- 变量定义:
var=value
注意等号两边没有空格,推荐用双引号把右值引用起来 - 调用已经定义的变量
$var
或${var}
; - declare的使用点这里.
- Shell提供语法检测变量是否赋值:
${var:-value}
: 如果var存在且非空, 整个表达式的值是var; 如果var为空或者未定义, 表达式的值是value;${var:=value}
: 如果var存在且非空, 整个表达式的值是var; 如果var为空或者未定义, 表达式的值是value, 并且给var赋值;${var:+mesg}
: 测试var, 如果var存在且非空,则${var:+mesg}的返回值为mesg;如果var为空或未定义,则返回null
- 如果是把一个命令的结果赋值给某变量:
var=`date`
#或者
var=$(date)
内置变量
- HOME, PS1, 等等
$0
: 脚本自身的名称$1
~$n
: 每个参数, 例如$1
是第一个参数$#
: 所有参数的数量$*
: 所有参数的组成的字符串,比如命令test.sh param1 param2
, 其$*
的值是”param1 param2”;$@
: 所有参数, 和上面不同的是:$@
是由多个子字符串组成的,$@
的内容是”param1”, “param2” 这两个字符串;$?
: 上个命令退出状态码, 0表示成功$$
: 当前Shell进程的PID$!
: Shell最后运行的后台Process的PID
数值计算
var1=$((1 + 3)) |
数组
@
和*
可以获取数组所有元素:${my_array[*]}
,${my_array[@]}
- 数组长度:
${#array[*]}
, #号在shell里表示长度
arr1[0]="cy" |
字符串
- 定义:
str="hello"
- 拼接:
str=$str"world"
- 字符串长度:
${#str}
- 替换:
${源字符串/查找字串/替换字串}
: 一个’/‘表示替换第一个’//‘表示替换所有,当查找出中出现了:”/“需要转义成”\/“
常用的字符串替换:
arr=(${string//,/ })
可以实现把逗号分隔的字符串转成数组
字符串续行
shell字符串续行符 “\”,来把一行长字符串分解成多行:
Example1: echo将输出一行 "continuation lines" |
常用类型比较
包括文件/字符串/数字比较
文件比较
-e filename
如果 filename 存在,则为真-d filename
如果 filename 为目录,则为真-f filename
如果 filename 为常规文件,则为真-L filename
如果 filename 为符号链接,则为真
Example:
if [ ! -f /tmp/foo.txt ]; then |
字符串比较
-z string
如果 string 长度为零,则为真-n string
如果 string 长度非零,则为真string1 = string2
如果 string1 与 string2 相同,则为真string1 != string2
如果 string1 与 string2 不同,则为真"$str" == "This's String"
变量比较字符串"$sub" =~ " $string "
变量$sub是否包含在字符串$string里, 注意两个空格
判断字符串是空串:
if [ "$str" == "" ];then |
数字比较
num1 -eq num2
数字比较, 等于则为真num1 -ne num2
数字比较, 不等于则为真num1 -lt num2
小于num1 -gt num2
大于num1 -ge num2
大于或等于
Shell Scripts中的符号总结
井号
#
井号: 求长度
- 字符串的长度:
${#string}
- 数组的长度:
${#array[*]}
大中小括号
()
小括号, 三种用途- 命令组:
(cmd1; cmd2)
括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被括号外的命令使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。 - 命令替换:
$(cmd)
等同于`cmd`
,原理是 shell先扫描一遍命令行,发现了该行里有$(cmd)
结构,便将$(cmd)
中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。例如airportd_pid=$(ps -ef | grep airportd | grep -v grep | awk '{print $2}')
- 定义数组:
array=(a b c d)
- 命令组:
$(())
双小括号: 数值计算, 不支持浮点型。例如$((exp))
结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1(false),而一个非零值的表达式所返回的退出状态码将为0(true)。若是逻辑判断,表达式exp为真则为1,假则为0。例1:
echo $(( groupnum*100 ))
例2: 数值与运算符可以没有空格,变量的使用时也可以不使用$num
while ((num<100))
do
echo "$num"
((num=num*2))
done[]
中括号: 见”if-then-else”[[ ]]
双中括号: 可以视作[]
的升级版版, 对字符串提供了高级特性, 比如支持正则:if [[ $var != "x*" ]]
{}
花括号: 变量替换, 例如${var}
反引号
反引号用于命令替换, 同上面的$(cmd)
, 例如: count=`echo $var | sed 's/^-//'`
这行命令截去var前置的负号
控制流程和语句
顺序执行
cmd1 ; cmd2
: 命令顺序执行,命令之间不存在关系,互不影响cmd1 && cmd2
: cmd1返回0(成功)那么才执行cmd2cmd1 || cmd2
: cmd1返回非0(不成功)那么才执行cmd2
grouping commands
(cmd1; cmd2)
(cmd1; cmd2)
:注意cmd2后面没有分号,()
将command group置于sub-shell(子shell) 中去执行,也称 nested sub-shell。
括号内对环境变量的修改,不会影响括号外面。
{cmd1; cmd2;}
{cmd1; cmd2;}
:注意最后一个语句后有分号,{}
则是在同一个shell内完成,也称 non-named command group。
Shell的函数跟 non-named command group 是类似的,每个命令之间可以用分号或者换行符隔开。
if-then-else
[
和]
前后都要有空格,if
与[
之间也需要有空格(好操蛋的语法):
if [ -d /root/fff ]; then |
if [ $a == "true" ]; then
中的then可以写在第二行, 下面的语法也是正确的:
if [ status ] |
多重条件if判断:
if [ "$bool1" == true ] || [ "$bool1" == true ] && [ "$bool1" != true ]; then echo 7; fi #1, no output, due to && IS NOT higher precedence than || |
if in one line
if [status]; then do_something; else do_something; fi
for-do-done
for var in 1 2 3; do |
for in one line
循环语句写为一行: for var in a b c; do echo $var; done
while
注意中括号[
前后的空格:
$i=0 |
switch
case $var in |
函数
shell中的函数都不带参数, 在函数内用$1
…$2
作为参数
doSomething() { |
重定向
详见: [[../21.Operating-System/Linux.01.常用命令行#命令重定向]]
Example:
command > outfile 2>&1 &
command < infile > outfile
- Here document:
wc -l << EOF
hello
world
EOF
Learn Shell in Y Minutes
【Learn Shell in Y Minutes】 是一个很有意思的项目, 用一段简单的代码介绍 Shell中的各种语法,
地址: Learn X in Y Minutes: Scenic Programming Language Tours
# 定义数组 |