shell定义
Shell 脚本是一个包含一连串 shell 命令语句的文本文件,通常以 .sh 为扩展名,可被当作一个独立的程序来执行,从而实现数据的批量处理。其通常由 shell header (shebang) 和 body (命令语句) 两部分组成。
Shell header
#!/bin/bash
set -e
set -u
!/bin/bash → shebang,表示执行该脚本所用的解释器。整个脚本必须以这行开始,且必须放在脚本的开头。
set -e (可选) → 如果任何语句的执行结果不是true则退出脚本 (遇到错误立即终止脚本) ,从而可以及时地修改脚本而大大地提高工作效率。
如果使用 set +e 则表示遇到错误报错但继续执行后续脚本。
set -u (可选) → 如果使用未定义的变量则报错并退出脚本。
Body
代码的主体部分描述 “需要做什么,如何去做”。例如定义变量,列出一系列需要执行的命令等,shell 会按照我们所写的顺序依次执行各个命令。当然,我们可以用#来做注释,来增加复杂代码的可读性。
echo "Hello world!" #此处为注释,不会显示在输出结果中
echo "This is my first shell script!"
path=$HOME
echo "List the content of the path $path"
echo "Contents:"
ls -l $path
如何执行 shell 脚本
直接用 sh 或 bash 命令执行脚本,如:
$ bash MyFirstShellScript.sh
$ sh ./MyFirstShellScript.sh
$ sh /path/to/script/MyFirstShellScript.sh
赋予脚本可执行权限,直接执行脚本,如:
$ chmod u+x MyFirstShellScript
$ chmod 755 MyFirstShellScript
$ ./MyFirstShellScript
$ /path/to/script/MyFirstShellScript.sh
Shell 变量
shell 变量定义
Shell 变量可以存储一定的信息 (输入文件,参数的值,输入文件目录,输出结果目录和),从而在后续的命令中对这些信息进行处理。Shell 变量的值实际上都是字符串(没有定义的变量默认是一个空字符串。Shell 变量可以不需要任何声明而直接定义,变量名由字母、数字和下划线组成,大小写敏感;并且定义变量时等号两边不能有空格,否则会被认为是命令。在变量名前加 $ 来获取变量的值。
shell 变量种类
- 系统变量:由操作系统创建,如:$PATH, $HOME, $BASH 等。
- 自定义变量:由用户创建:如上例中的 $path。
$ echo $HOME
/root
$ echo $BASH
/bin/bash
$ path=$HOME
$ echo $path
/root
命令替换
使用$() 或 `` 来实现命令替换,即执行一个 shell 命令然后把输出结果存到一个变量中。使用方式:var=$(command) 或 var=command
。
$ echo "Today is $(date "+%Y-%m-%d")"
Today is 2017-04-16
$ path=$HOME
$ command_output=`ls $HOME`
$ echo $command_output
Desktop Documents Downloads Music MyFirstShellScript.sh Pictures Public Videos
${} 的高级应用:取路径、文件名、后缀、字符串和替换
规律
#是从左面开始匹配
%是从右面开始匹配
使用一个符号 (# 或 %) 是最小匹配
使用两个符号 (## 或 %%) 是最大匹配
* 用来去掉不需要的字符
可以自己指定分割符号与 #, % 和 * 配合来决定取哪部分来替换
可以自己指定起始位置来决定提取哪部分字符串
可以使用 /str1/str2 来替换特定字符串
$ var=/home/username/data/test.txt.bac
$ echo ${var}
/home/username/data/test.txt.bac
$ echo ${var#*/}
#去掉第一个 / 及其左边的字符串
home/username/data/test.txt.bac
$ echo ${var##*/}
#去掉最后一个 / 及其左边的字符串
test.txt.bac
$ echo ${var%/*}
#去掉最后一个 / 及其右边的字符串
/home/username/data
$ echo ${var%%/*}
#去掉第一个 / 及其右边的字符串 (输出结果为空)
$ echo ${var#*.}
#去掉第一个 . 及其左边的字符串
txt.bac
$ echo ${var##*.}
#去掉最后一个 . 及其左边的字符串
bac
$ echo ${var%.*}
#去掉最后一个 . 及其右边的字符串
/home/username/data/test.txt
$ echo ${var%%.*}
#去掉第一个 . 及其右边的字符串
/home/username/data/test
$ echo ${var:0:5}
#取第0位后的5个字节
/home
$ echo ${var:5:9}
#取第5位后的9个字节
/username
$ echo ${var/username/cat}
#将 username 替换为 cat
/home/cat/data/test.txt.bac
$ echo ${#var}
#取变量的长度
引用
引用是指用引用符号将字符串引起来,以防其中的特殊字符被 shell 解释为其它含义。我们可以通过引用来控制‘命令替换’或把含有空格 (或其它特殊字符) 的字符串做为一个整体进行参数传递。
Shell 中三种常见的引用形式:
' ' (单引号) 所有字符保持原义但字符串中不能出现单引号本身 (全引用)
z 除 $, ` 和 \ 以外的所有字符保持原义 (部分引用)
\ (反斜线) 转义字符,使接下来的一个字符保持原义
单引号和双引号的区别:
在引用内容为纯文本时,二者没有本质差别。
如果想要获取变量的值时,则需要使用双引号。
$ test="world"
$ echo "Hello $test"
Hello World
$ echo 'Hello $test'
Hello $test
转义
在某些情况下,我们需要保留特殊字符的原义,这时就需要用 \ 来转义。举个例子:
$ var="Hello world"
$ echo "The content of variable '\$var' is \"$var\""
The content of variable '$var' is "Hello world"
Shell 脚本中的参数传递
Shell 脚本可以从命令行获取参数,这些参数被存入变量 $1, $2, $3 ... 中,这些变量被称为特殊变量。
特殊变量 含义
$# 从命令行传递给脚本的参数个数
$0 当前执行脚本的名字
$n 从命令行传递给脚本的参数,从左到右被存入变量:$1, $2, $3 ... $9
$* 从命令行传递给脚本的所有参数
$@ 从命令行传递给脚本的所有参数
$$ 当前 shell 进程的 PID
$? 上一个执行命令的返回值
#!/bin/bash
set -e
set -u
echo "number of arguments: $#"
echo "script name is: $0"
echo "first argument is: $1"
echo "second argument is: $2"
echo "all arguments are: $*"
echo "all arguments are: $@"
echo "process number of the current process is: $$"
echo "exit value of the last command executed: $?"
执行脚本
sh test.sh hello world
显示结果
number of arguments: 2
script name is: test.sh
first argument is: hello
second argument is: world
all arguments are: hello world
all arguments are: hello world
process number of the current process is: 106836
exit value of the last command executed: 0