Shell
是一个用 C 语言编写的应用程序,该应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,如可以让用户使用 Linux 命令。
Shell script
,是一种为 shell 编写的脚本程序。shell
和 shell script
是两个不同的概念,加以区分。后缀名一般是.sh
。
常见的Linux的shell,以及默认的解释路径如下:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
常用的shell为前两种,bash为LinuxOS 默认的,它是 Bourne Shell (sh)的扩展。 与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性。可以提供命令补全,命令编辑和命令历史等功能。它还包含了很多 C Shell 和 Korn Shell 中的优点,有灵活和强大的编辑接口,同时又很友好的用户界面。
最简单的shell脚本的文件如下:
1 2
| #!/bin/bash echo "Hello Aszero !"
|
其中第一行的#!
用来指定后面的shell脚本的解释程序路径,/bin/bash
就是解释Shell 程序路径。
执行shell脚本
现有一个shell脚本文件aszero.sh
1 2
| #!/bin/bash echo "Hello Aszero !"
|
如果在第一行声明了解释器的路径,linux shell中可以直接使用sh
命令运行shell脚本
作为可执行程序
可以参考以前说过的chmod
命令,可以改变文件的读写以及可执行权限,这里就可以把这个bash文件变成可执行文件。
1 2
| $ chmod -x ./aszero.sh $ ./aszero.sh
|
直接将文件作为解释器的参数去运行解释器
1 2
| $ /bin/bash ./aszero.sh
|
在shell脚本中写命令
用
符号或者$()包裹起来
1 2 3
| for file in `ls /etc`
for file in $(ls /etc)
|
Shell变量
定义变量
shell变量和熟知的其他语言的变量略微不同,如变量名不需要声明类型、不需要加特殊标识符号、变量名和值之间的等号不能有空格。命名只能使用英文字母,数字和下划线组成,首字符不能是数字。
1 2 3 4 5 6
| USER_NAME="aszero"
USER_NAME = "aszero" 100_USER_NAME="aszero" $USER_NAME="aszero"
|
使用变量
定义过的变量前加$
符号,即可使用变量。
1 2 3
| echo $USER_NAME
echo ${USER_NAME}
|
覆盖变量
变量定义之后,该变量非只读变量,就可以重新被定义覆盖原始值。只读变量不可被重新定义,否则报错。
1 2 3 4 5 6 7
| USER_NAME="aszero" echo ${USER_NAME} USER_NAME="Joacycode" echo ${USER_NAME}
readonly USER_NAME
|
删除变量
删除变量后变量就如同没有定义一样,输出空,注意不能删除只读变量。
1 2 3 4 5 6 7
| USER_NAME="aszero" _READONLY_NAME="aszero" unset USER_NAME
readonly _READONLY_NAME
unset _READONLY_NAME
|
Shell传参与运算
传参
脚本有些时候需要根据shell执行人的意志传入一些动态参数,满足不同场景下的执行方案。shell的传参和获取也非常便捷,入参就在调用的该shell文件后面增加,多个参数用空格分隔;获取参数时候用$n,$0表示文件名,其他数字按顺序表示入参。
1 2 3 4 5 6 7
| echo "文件名:$0" echo "第一个参数: $1" echo "第二个参数: $2"
|
参数 |
说明 |
$[N] |
文件名以及入参信息 |
$@ |
分别显示所有入参 |
$* |
一个字符串显示所有入参 |
$# |
入参数量 |
1 2 3 4 5 6
| echo "文件名:$#" echo "所有参数: $*" echo "所有参数: $@"
|
运算符
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
1 2 3
| A=99 B=999 STRING_TEST="ImZero"
|
算术运算符,shell中支持算术运算需要借助 expr 表达式
命令或者在mac中shell使用$((表达式))
,才能完成算术运算。
1 2 3
| VAL=`expr $A + $B`
VAL=$(($A + $B))
|
注意 算术运算的乘法*要使用转义字符,且运算符左右两边都要留有空格。
关系运算符,主要有相等 -eq
、不相等-ne
、大于(等于)-gt
-ge
、小于(等于)-lt
-le
几种关系,其中等于和不等于条件表达式可以用算术运算符表示。条件表达式需要用 []
包裹。
1 2
| echo [ $A -eq $B ] echo [ $A -ne $B ]
|
布尔运算符,与或非,分别用-a
-o
!
表示。
1 2 3 4
| echo [ $A -lt 100 -a $B -gt 1000 ]
echo [ $A -lt 100 -o $B -gt 1000 ]
|
逻辑运算符,与或,分别用&&
||
表示,条件逻辑运算要使用[[条件逻辑运算]]
双中括号
1 2 3 4
| echo [[ $A -lt 100 && $B -gt 1000 ]]
echo [[ $A -lt 100 || $B -gt 1000 ]]
|
关于单中括号、双中括号其他说明:在 []
表达式中,常见的 >
, <
需要加转义字符,逻辑运算符 ||
、&&
,它需要用 -a[and]
–o[or]
表示。[[]]
运算符只是 []
运算符的扩充,能够支持 >, < 符号运算不需要转义符,支持逻辑运算符||
&&
,不再使用 -a[and]
–o[or]
。
字符串运算符,检测当前字符串的语法糖符号,比如字符串为不为空,字符串长度是否为0,是否相等。
1 2 3 4
| echo [$STRING_TEST]
echo [-z $STRING_TEST]
|
文件测试运算符,文件测试运算符用于检测 Unix 文件的各种属性。常用的操作符如下:
操作符 |
说明 |
-d |
检测文件是否是目录,如果是,则返回 true。 |
-f |
检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-r |
检测文件是否可读,如果是,则返回 true |
-w |
检测文件是否可写,如果是,则返回 true |
-x |
检测文件是否可执行,如果是,则返回 true |
-s |
检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e |
检测文件(包括目录)是否存在,如果是,则返回 true。 |
Shell字符串
字符串定义
shell中字符串可以用单引号也可以用双引号,两者的用法还是有区别的。单引号表示字符串,内部不能包含变量,所有字符都会原样输出;双引号表示字符串,内部可以包含变量,出现转义字符。
1 2 3
| USER_NAME="aszero" USER_JOB='does something interesting' ASZERO_JOB="${USER_NAME} does something interesting"
|
字符串方法
获取字符串长度,使用方法:\${\#[String]}
。
1 2
| USER_NAME="aszero" echo ${#USER_NAME}
|
提取子字符串,使用方法:${[String]:Index:Length},从什么地方开始截取多少字符。
1 2
| USER_NAME="aszero" echo ${USER_NAME:0:2}
|
查找子字符串位置,使用方法:expr index "[String]" [String_child]
,执行命令用的``或者$()都可以。
1 2
| USER_NAME="aszero" echo `expr index "$USER_NAME" z`
|
Shell数组
shell支持一维数组,用括号来表示数组,数组元素用”空格”符号分割开
1 2 3 4 5 6
| STU_NAMES=("Ella" "Zrus" "Coco")
STU_NAMES[0]="Ella" STU_NAMES[1]="Zrus" STU_NAMES[2]="Coco"
|
输出数组
1 2 3 4
| echo ${STU_NAMES[@]}
echo ${STU_NAMES[n]
|
获取数组长度
Shell函数
定义函数
1 2 3 4
| [ function ] funname(){ action; [return int;] }
|
注意
- return后面跟数值0-255,不能超过这个范围,如果没有return,将以最后一条命令运行结果,作为返回值。
- 所有函数在使用前必须定义。
- 函数返回值在调用该函数后通过 $? 来获得,$? 仅对其上一条指令负责。
- 函数入参直接连在函数名后面,多个参数空格隔开。
1 2 3 4 5 6 7 8 9 10
| fn(){ echo "第一个函数参数:$1" echo "全部函数参数个数:$#" return 249 } fn 1 2 3 echo $?
|
Shell流程控制
if-else语句
1 2 3 4 5 6 7 8 9
| if condition then command1 elif then command2 else command3 fi
|
for循环
1 2 3 4 5 6 7
| for var in item1 item2 ... itemN do command1 command2 ... commandN done
|
输出/etc
下面所有的文件
顺序输出当前列表中的数字
1 2 3 4
| for loop in 1 2 3 4 5 do echo "The value is: $loop" done
|
Shell注释
1 2 3 4 5
| :<<EOF echo "多行注释" echo "多行注释" echo "多行注释" EOF
|
1 2 3 4 5
| fn(){ echo "多行注释" echo "多行注释" echo "多行注释" }
|
shell中常用的linux命令
read
basename
dirname
原创内容,欢迎交流转载请注明出处