Shell Script Language
The basic grammer of shell script.
ref: shell tutorial
Intro
不同的Shell实现会有不同的方言,不过这很少见。 这里只介绍最标准的Shell Script语法,, 能够被最常用的Shell(如Bash)接受
Variable
assign variables in bash:
foo=bar
- Note that
foo = bar
will not work since it is interpreted as calling thefoo
program with arguments=
andbar
. In general, in shell scripts the space character will perform argument splitting.- 因此不要加空格
- Note that
access the value of the variable:
$foo
- 等价于
${foo}
, 花括号可以精确地界定变量名称的范围。
- 等价于
可以用
read
命令从标准输入接受数据并赋值:read val
example:
1
2
3
4
5! /usr/bin/env bash
echo -n "Enter your name:"
read name
echo "hello $name"
exit 0
String
Strings in bash can be defined with
'
and"
delimiters, but they are not equivalent.Strings delimited with
'
are literal strings and will not substitute variable values whereas"
delimited strings will.1
2
3
4
5foo=bar
echo "$foo"
prints bar
echo '$foo'
prints $foo
Array
array initialization −
1
array_name=(value1 ... valuen)
assign
1
array_name[index]=value
access Array Values
1
{array_name[index]}
Quoting Mechanism
metacharacters
Unix Shell provides various metacharacters which have special meaning while using them in any Shell Script and causes termination of a word unless quoted.
1 | * ? [ ] ' " \ $ ; & ( ) | ^ < > new-line space tab |
quoting
The following table lists the four forms of quoting −
Sr.No. | Quoting & Description |
---|---|
1 | Single quote All special characters between these quotes lose their special meaning. |
2 | Double quote Most special characters between these quotes lose their special meaning with these exceptions −$`$'"\ |
3 | Backslash Any character immediately following the backslash loses its special meaning. |
4 | Back quote (aka backtick) Everything you type between backticks is evaluated (executed) by the shell before the main command, and the output of that execution is used by that command, |
The Single Quotes: 其内容不转义, 相当于在每个字符前加 backslash
The Double Quotes: 其内容转义
The Backslash: 取消其后面的一个字符的转义
The Backquotes:将其内容视作 command 并执行, 与后文的CMD substitution类似
1
var=`command`
1
2
3
4
5
6DATE=`date`
echo $DATE
等价于后文的CMD substitution
echo $(DATE)
常见语法
条件语句
- As with most programming languages, bash supports control flow techniques including
if
,case
,while
andfor
.
if
syntax:
1 | if [ expression ] |
1 | if [ expression 1 ] |
紧凑形式: ;
(同一行上多个命令的分隔符)
example:
1 | if [ -f ~/.bashrc ]; then |
1 | !/bin/sh |
case
syntax:
1 | case word in |
example:
1 | !/bin/sh |
1 | !/bin/sh |
select in && case in
select in语句自带循环
1 | select variable in value_list |
- variable: 表示变量
- value_list: 取值列表
- in: Shell关键字
select in 通常和 case in 一起使用,在用户输入不同的编号时可以做出不同的反应
example:
1 | !/bin/sh |
该命令的while版本:
1 | while [ "$item" != "Finish" ]; |
循环语句
break
: 从for/while/until循环退出
for
syntax:
1 | for var in word1 word2 ... wordN |
example:
1 | for FILE in $HOME/.bash* |
1 | for f in *.png |
while
syntax:
1 | while condition |
example:
1 | quit=n |
1 | a=0 |
命令组合
分号串联:
1 | command1 ; command2 ; ... |
条件组合: 1
statement1 && statement2 && statement3 && ...
1 | statement1 || statement2 || statement3 || |
语句块
1 | { |
或
1 | { |
test expression 或 [ expression ]
[
(akatest
) command the and[[ ... ]]
test construct are used to evaluate expressions[
是一条命令, 与test
等价,大多数shell都支持。在现代的大多数sh实现中,[
与test
是builtin命令[]
将其operand直接当作argument
[[
,是关键字,许多shell(如ash bsh)并不支持这种方式[[]]
将其operand进行参数引用,算术扩展和CMD substitution, 不需要手动转义等
test
test expression:
1 | test 1 -lt 2 |
[ expression ]
:
1 | echo "Starting program at $(date)" # Date will be substituted |
与文件有关的条件测试
文件测试运算符的形式及功能
option | parameter | function |
---|---|---|
-r | 文件名 | 如文件存在并且是用户可读的,则测试条件为真 |
-w | 文件名 | 如文件存在并且是用户可写的,则测试条件为真 |
-x | 文件名 | 如文件存在并且是用户可执行的,则测试条件为真 |
-f | 文件名 | 如文件存在并且是普通文件,则测试条件为真 |
-d | 文件名 | 如文件存在并且是目录文件,则测试条件为真 |
-p | 文件名 | 如文件存在并且是命名的FIFO文件,则测试条件为真 |
-b | 文件名 | 如文件存在并且是块特殊文件,则测试条件为真 |
-c | 文件名 | 如文件存在并且是字符特殊文件,则测试条件为真 |
-s | 文件名 | 如文件存在并且文件长度大于0,则测试条件为真 |
-t | 文件描述符 | 如文件被打开且文件描述符是与终端设备相关的,则测试条件为真,默认文件描述符是1 |
字符串测试
option | parameter | function |
---|---|---|
-z | s1 | 如果字符串s1的长度为0,则测试条件为真 |
-n | s1 | 如果字符串s1的长度大于0,则测试条件为真 |
s1 | 如果字符串s1不是空字符串,则测试条件为真 | |
=或== | s1=s2 | 如果s1等于s2,则测试条件为真,“=”前后应有空格 |
!= | s1!=s2 | 如果s1不等于s2,则测试条件为真 |
< | s1<s2 | 如果按字典顺序s1在s2之前,则测试条件为真 |
> | s1>s2 | 如果按自定顺序s1在s2之后,则测试条件为真 |
数值测试
parameter | function |
---|---|
n1 -eq n2 | 如果整数n1等于n2,则测试条件为真 |
n1 -ne n2 | 如果整数n1不等于n2,则测试条件为真 |
n1 -lt n2 | 如果如果n1小于n2,则测试条件为真 |
n1 -le n2 | 如果如果n1小于或等于n2,则测试条件为真 |
n1 -gt n2 | 如果n1大于n2,则测试条件为真 |
n1 -ge n2 | 如果n1大于或等于n2,则测试条件为真 |
逻辑操作
parameter | function |
---|---|
! expr | 逻辑表达式求反 |
expr1 –a expr2 | 两个逻辑表达式“And“ |
expr1 –o expr2 | 两个逻辑表达式“Or“ |
Function
syntax
1 | function_name(){ |
example:
1 | mcd () { |
return
exit
: 不仅会退出函数, 还会退出执行该函数的shellreturn code
:仅仅退出函数. 和command的return code同
Function Call from Prompt
令shell加载函数定义:
可以将函数定义在主目录下的
.profile
,这样每次登陆后,在命令提示符后面输入函数名字就可以立即调用:1
func para1 para2
将函数定义写在一个文件( say
test.sh
), 然后执行它
令shell删除函数定义:
1
unset -f function_name
- 该命令也可用来令shell删除变量定义
- 反之,
set
可以用来定义变量
output
Commands will often return output using
STDOUT
, errors throughSTDERR
return code
- Commands have Return Code to report errors in a more script-friendly manner.
- 0 usually means everything went OK; anything different from 0 means an error occurred.
return code
, 你可以指定返回任何值
return code as bool value
Return codes can be used to conditionally execute commands using
&&
(and operator) and||
(or operator) .Commands can also be separated within the same line using a semicolon
;
.The
true
program will always have a 0 return code and thefalse
command will always have a 1 return code.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17false || echo "Oops, fail"
Oops, fail
true || echo "Will not be printed"
true && echo "Things went well"
Things went well
false && echo "Will not be printed"
true ; echo "This will always run"
This will always run
false ; echo "This will always run"
This will always run