Shell介绍与入门
1. 什么是Bash?
Bash是一个为GNU计划编写的Unix Shell, 也是许多Linux平台默认使用的Shell。
Shell是一个命令解释器,是介于操作系统内核和用户之间的一个绝缘层。同时, Shell也是一种解释性语言或脚本语言。它通过将系统调用、公共程序、工具和编译过的二进制程序"粘合"在一起来建立应用, 也称"胶水语言"。
2. 为什么学Bash?
对于任何想适当精通一些系统管理的人来说, 掌握Shell脚本的编写都是最基本的。
3. Bash脚本的运行方式:
# 使用shell来执行 $ sh script.sh # 使用bash来执行 $ bash script.sh # 赋予脚本的所有者该执行权限,允许该用户执行该脚本 $ chmod u+rx script.sh # 执行命令,这将使用脚本第一行指定的shell来执行,如果指定shell不存在,将使用系统默认shell来执行 $ ./script.sh
4. 清空/var/log下的log文件:
#!/bin/bash # 初始化一个变量 LOG_DIR=/var/log cd $LOG_DIR cat /dev/null > messages cat /dev/null > wtmp echo "Logs cleaned up." exit
5. Bash中的特殊字符
1). # 注释
行首以"#"开头(除"#!"之外)的是注释。"#!", 用于指定当前脚本的解释器(使用绝对路径)
#!/bin/bash echo "The # here dose not begin a comment." echo 'The # here dose not begin a comment.' echo The \# here dose not begin a comment. echo The # 这里开始一个注释 echo ${PATH#*:} # 参数替换,不是一个注释 echo $(( 2#101011 )) # 数制转换(使用二进制表示),不是一个注释
2). ; 命令分隔符
使用";"可以在同一行上写多个命令
echo hello; echo world
3). ;; case语句选项终止标记
使用";;"可以终止case选项
#!/bin/bash varname=b case "$varname" in [a-z]) echo "alphabet"
;; [0-9]) echo "number"
;; esac
4). . 点号 等价于source命令
. script.sh source script.sh
5). " 双引号
将转义字符视为普通字符, 允许Shell变量、Shell命令替换
6). ' 单引号
将转义字符都是为普通字符, 不允许Shell变量、Shell命令提换
7). / 斜线
文件名路径分隔符, 除法运算符
8). \ 反斜线
取消转义字符的特殊含义
9). ` 反冒号
命令替换
10). : 冒号
i. 空命令, 与Shell内建的命令true作用相同
#!/bin/bash while : # while true do echo "endless loop" done
#!/bin/bash condition=5 if condition>0 then : # 什么都不做,退出分支 else echo "$condition" fi
ii. 变量扩展/字串替换
$ : > file # 文件“file”现在被清空了 # 与 cat /dev/null > file 的作用相同 # 然而,这并不会产生一个新的进程, 因为“:”是一个内建命令
11). ? 测试操作符
等价于C语言中的三元操作符
#!/bin/bash a=10 (( t=a<2?8:9 )) echo $t echo $((a<2?8:9))
12). $ 变量替换
13). $( ) 命令替换
14). () 小括号
i. 命令组
在括号中的命令列表, 将会作为一个子Shell来执行(子Shell中的变量在父Shell中不可见):
#!/bin/bash a = 123 ( a=321; ) echo $a # 123
ii. 初始化数组
#!/bin/bash array=(1 2 3 4 5) echo ${array}
15). {} 大括号
i. 文件名扩展
mv file{,.bak}
注意: 大括号中, 不允许有空白, 除非这个空白被引用或转义!
ii. 代码块
等同于与一个匿名函数, 但其内声明的变量, 在之后的代码仍可见
#!/bin/bash a=123 { a=321; } echo $a # 321
16). [] 中括号
i. 条件测试
[ 是Shell内建test命令的一部分, 不是/usr/bin/test中的外部命令的一个链接
#!/bin/bash a=5 if [ $a -lt 10 ] ; then echo $a else echo 10 fi
注意: [[ ]] 双中括号也可用于条件测试:
[[ 2 -lt 1 ]] || echo "false" [[ 1 -lt 2 ]] && echo "true"
ii. 数组元素
#!/bin/bash array=(1 2 3 4 5) array[3]=10 echo ${array[3]}
17). <, > 尖括号
i. 重定向
> 标准输出重定向, &> 标准输出、标准错误输出重定向, >&2标准输出重定向到标准错误输出, >> 追加
18). | 竖线 管道
cat file | tr 'a-z' 'A-Z'
19). - 破折号
i. 选项, 前缀
-eq, -le, -ge, ...
ii. 用于重定向stdin, stdout
#!/bin/bash BACKUPFILE=backup-$(date +%m-%d-%Y) # 在备份文件中嵌入时间. archive=${1:-$BACKUPFILE} # 如果在命令行中没有指定备份文件的文件名, #+ 那么将默认使用"backup-MM-DD-YYYY.tar.gz". tar cvf - `find . -mtime -1 -type f -print` > $archive.tar gzip $archive.tar echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"." exit 0
20). ~ 波浪号
i. 用户主目录
6. 变量替换
echo $HOME echo "$HOME" echo '$HOME'
注: 如果没有引号, 将自动删除输出中多余的空白符!
7. 变量赋值 =
注意: 赋值操作前后不能有空白!
8. 特殊变量
i. 局部变量: 只在代码块或函数中可见
ii. 环境变量: Shell中定义的变量
iii. 位置参数: $0, $1, ... $9, ${10}, ${11},...
$*, $@