[TOC]linux
建立 helloWorld.sh
文件,写入以下内容:git
#!/bin/bash echo "hello world"
其中 #!
告诉系统其后路径所指定的程序是解释此脚本文件的 Shell 程序,常见的 Shell 程序有如下几类(可经过命令 cat /etc/shells
查看):github
其中 Bash 在平常工做中被普遍使用,同时也是大多数 Linux 系统默认的 Shell。shell
执行该 sh 脚本数组
# 增长可执行权限 ➜ chmod u+x helloWorld.sh # 运行脚本 ➜ ./helloWorld.sh 或 ➜ sh hellowWorld.sh
单行注释bash
#
开头的行是注释多行注释ide
方式一:用一对 {}
括起来,定义成一个函数,没有地方调用即达到注释的效果。函数
方式二:测试
:<<EOF 注释内容... 注释内容... 注释内容... EOF
变量定义ui
=
两边不能有空格;help
命令查看保留关键字)。以下示例:
VAR1="whoru" VAR2=100 var3=/data/www var4_name="root"
访问变量 $VAR1
或 $(var1)
,其中,加花括号是为了帮助解释器识别变量的边界。
设置变量只读 readonly VAR1
删除变量(不适用于只读变量!) unset VAR1
""
或单引号 ''
表示
# 字符串拼接 name="xiaoming" var2="hello, "$name # 输出 hello, xiaoming # 获取字符串长度 string="abcd" echo ${#string} # 输出 4 # 提取子字符串 msg="zhangsan is a good man" echo ${msg:1:4} # 输出 hang
bash 支持一维数组(不支持多维数组),而且没有限定数组的大小。
数组元素的下标由 0 开始,获取数组元素要用到下标。
定义:
array1=(value0 value1 value2 value3) 或 array2[0]=value0 array2[1]=value1 array2[2]=value2
读取
# 指定下标的元素 echo ${array2[2]}; // 输出 value2 # 获取数组全部元素 echo ${array2[*]}; // 输出 value0 value1 value2 echo ${array2[@]}
获取数组元素个数
echo ${#array2[@]}; // 输出 3 echo ${#array2[*]};
取得数组中指定下标元素的字符长度
echo ${#array2[2]};
在执行 Shell 脚本时,能够向脚本传递参数,脚本内获取参数的格式为 $n
,这里的 n 指传递给脚本的第 n 个参数。
以下脚本文件 demo.sh
:
#!/bin/bash echo "执行的文件名:$0"; echo "第一个参数为:$1"; echo "第二个参数为:$2"; echo "第三个参数为:$3";
执行该文件,并传递参数,以下:
➜ ./demo3.sh param1 param2 param3 执行的文件名:./demo3.sh 第一个参数为:param1 第二个参数为:param2 第三个参数为:param3
其中,$0
是一个特殊变量,表明当前脚本文件名,还有几个相似的变量以下:
变量 | 说明 |
---|---|
$# | 传递给脚本的参数个数。 |
$* | 以一个单字符串的形式显示全部向脚本传递的参数,如 "$1 $2 ... $n" |
$@ | 与 $* 相同,可是使用引号把每一个参数包裹起来,如 "$1" "$2" ... "$n" |
$? | 最后一个执行的命令的退出状态:0 正常;1 或其它任何值,表示有错误 |
$$ | 脚本运行的当前进程ID号 |
$! | 最后一个后台命令的进程号。 |
原生 bash 不支持简单的数学运算,可是能够经过其余命令来实现,例如 awk 和 expr,其中 expr 最经常使用。
假定有两个变量:a=10
b=20
运算符 | 说明 | 举例 |
---|---|---|
+ |
加法 | `expr $a + $b` 结果为 30。 |
- |
减法 | `expr $a - $b` 结果为 -10。 |
* |
乘法 | `expr $a \* $b` 结果为 200。 |
/ |
除法 | `expr $b / $a` 结果为 2。 |
% |
取余 | `expr $b % $a` 结果为 0。 |
= |
赋值 | a=$b 将把变量 b 的值赋给 a。 |
== |
用于比较两个数字是否相同 | [ $a == $b ] 返回 false。 |
!= |
用于比较两个数字是否不相同 | [ $a != $b ] 返回 true。 |
注意:
2+2
是错误的,必须写成 2 + 2
;` `
包裹起来;关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
假定有两个变量:a=10
b=20
运算符 | 说明 | 举例 |
---|---|---|
-eq |
检测两个数是否相等 | [ $a -eq $b ] 返回 false。 |
-ne |
检测两个数是否不相等 | [ $a -ne $b ] 返回 true。 |
-gt |
检测左边的数是否大于右边的 | [ $a -gt $b ] 返回 false。 |
-lt |
检测左边的数是否小于右边的 | [ $a -lt $b ] 返回 true。 |
-ge |
检测左边的数是否大于等于右边的 | [ $a -ge $b ] 返回 false。 |
-le |
检测左边的数是否小于等于右边的 | [ $a -le $b ] 返回 true。 |
假定有两个变量:a=10
b=20
运算符 | 说明 | 举例 |
---|---|---|
! |
非运算,表达式为 true 则返回 false,不然返回 true。 | [ ! false ] 返回 true。 |
-o |
或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a |
与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
假定有两个变量:a=10
b=20
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
假定有两个变量:a="abc"
b="efg"
运算符 | 说明 | 举例 |
---|---|---|
= |
检测两个字符串是否相等 | [ $a = $b ] 返回 false。 |
!= |
检测两个字符串是否不相等 | [ $a != $b ] 返回 true。 |
-z |
检测字符串长度是否为 0(空) | [ -z $a ] 返回 false。 |
-n |
检测字符串长度是否不为0(非空) | [ -n "$a" ] 返回 true。 |
str | 检测字符串是否为不为空 | [ $a ] 返回 true。 |
运算符 | 说明(若是是,则返回 true) | 举例 |
---|---|---|
-b |
检测文件是不是块设备文件 | [ -b $file ] |
-c |
检测文件是不是字符设备文件 | [ -c $file ] |
-d |
检测文件是不是目录 | [ -d $file ] |
-f |
检测文件是不是普通文件(既不是目录,也不是设备文件) | [ -f $file ] |
-g |
检测文件是否设置了 SGID 位 | [ -g $file ] |
-k |
检测文件是否设置了粘着位(Sticky Bit) | [ -k $file ] |
-p |
检测文件是不是有名管道 | [ -p $file ] |
-u |
检测文件是否设置了 SUID 位 | [ -u $file ] |
-r |
检测文件是否可读 | [ -r $file ] |
-w |
检测文件是否可写 | [ -w $file ] |
-x |
检测文件是否可执行 | [ -x $file ] |
-s |
检测文件是否为非空(文件大小是否大于0)文件 | [ -s $file ] |
-e |
检测文件(包括目录)是否存在 | [ -e $file ] |
大多使用关系运算符检查关系
# 语法格式 if condition1 then command1 ... elif condition2 then command2 else commandN fi
# 语法格式 case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; *) commandDefault ;; esac
用于不断执行一系列命令,也用于从输入文件中读取数据;命令一般为测试条件。其格式为:
# 语法格式 while condition do command done
执行一系列命令直至条件为 true 时中止,它与 while 循环
在处理方式上恰好相反。
# 语法格式 until condition do command done
# 语法格式 for var in item1 item2 ... itemN do command1 command2 ... commandN done
# 语法1 while : do command done # 语法2 while true do command done # 语法3 for (( ; ; ))
break
跳出整个循环,执行循环体后面的代码,支持 break n
退出多层嵌套循环continue
结束当前循环,一样支持 continue n
退出多层命令 | 说明 |
---|---|
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 之间的内容做为输入。 |
关于文件描述符:
0
一般是标准输入(STDIN),Unix程序默认从 stdin
读取数据。1
标准输出(STDOUT),Unix程序默认向 stdout
输出数据。2
标准错误输出(STDERR),Unix程序会向 stderr
流中写入错误信息。示例:
# 将 stdout 和 stderr 合并后重定向到 file ➜ command > file 2>&1
这是一个特殊的文件,写入到它的内容都会被丢弃;若是尝试从该文件读取内容,也什么也读不到。咱们一般将命令的输出重定向到它,起到“禁止输出”的效果。
如:
# 屏蔽 stdout 和 stderr ➜ command > /dev/null 2>&1
# 将两个 delimiter 之间的内容(document) 做为输入传递给 command。 command << delimiter document delimiter
说明:
delimiter
必定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。delimiter
先后的空格会被忽略掉。[ function ] funcName [()] { command; [return int;] }
说明:
function
关键字非必须;return
非必须;默认返回最后一条命令的执行结果;funcName
;func() { echo "第一个参数为 $1 !" echo "第二个参数为 $2 !" ... echo "第十个参数为 ${10} !" ... } # 调用并传参 func param1 param2 param3
说明:
$n
的形式来获取参数的值,例如:$1 表示第一个参数,$2 表示第二个参数;${n}
来获取参数。用于字符串的输出,基本格式 echo string
。
使用示例:
# 显示普通字符 echo "It is a test" # 输出 It is a test # 显示转义字符 echo "\"It is a test\"" # 输出 "It is a test" # 显示变量 #!/bin/sh NAME="xiaoming" echo "$NAME It is a test" # 输出 xiaoming is a test # 显示换行 echo -e "OK! \n" # -e 开启转义 echo "It is a test" # 显示不换行 echo -e "OK! \c" # -e 开启转义 \c 不换行 echo "It is a test" # 显示结果定向至文件 echo "It is a test" > myfile # 显示命令执行结果 echo `date`
模仿 C 程序库(library)里的 printf() 程序,主要用于格式化输出。
默认 printf
不会像 echo
自动添加换行符,咱们能够手动添加 \n
。
其基本语法格式为:
printf format-string [arguments...]
说明:
format-string
为格式控制字符串arguments
为参数列表。示例:
➜ printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg ➜ printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 ➜ printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 ➜ printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 姓名 性别 体重kg 郭靖 男 66.12 杨过 男 48.65 郭芙 女 47.99
其中:
%s
%c
%d
%f
都是格式替代符;%-10s
指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,若是不足则自动以空格填充,超过也会将内容所有显示出来。%-4.2f
指格式化为小数,其中.2指保留2位小数。更多使用示例:
# 没有引号也能够输出 ➜ printf %s abcdef # 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用 ➜ printf %s abc def abcdef ➜ printf "%s\n" abc def abc def # 若是没有 arguments,那么 %s 用NULL代替,%d 用 0 代替 ➜ printf "%s and %d \n" and 0
用于检查某个条件是否成立,它能够进行数值、字符和文件三个方面的测试(详见第3节对应的运算符部分)。
基本使用示例:
cd /bin if test -e ./bash then echo '文件已存在!' else echo '文件不存在!' fi
被包含的文件不须要可执行权限。
# 方式一 . another_file.sh # 方式二 source another_file.sh
更新:https://github.com/whorusq/linux-learning/edit/master/shell_basic_guide.md