文章目录
shell解释器类型
- cat /etc/shells:查看系统中所有可用的shell解释器;
- echo $SEHLL:查看当前的shell解释器;
- #!:sh 文件中告知系统当前脚本使用的是哪种shell脚本;
执行命令脚本的三种方法
- ./脚本文件路径:./exa.sh;
- sh 脚本文件路径:sh exa.sh;
- source 脚本文件路径:source exa.sh;
变量
- 定义变量时,变量名不加 “$” 符号,变量名和等号之间不能有空格;
- 还可以用语句给变量赋值,如:for file in
ls /etc
或 for file in $(ls /etc),将 /etc 下目录的文件名循环出来; - 使用一个定义过的变量,只要在变量名前面加 “$" 符号即可,变量名外面的花括号是可选的,是为了帮助解释器识别变量的边界;
- readonly 命令可以将变量定义为只读变量,unset 命令可以删除变量;
- read -p “提示语” 变量:用于将用户的输入赋给指定的参数;
字符串
单引号字符串:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用;
- 字符串拼接时,只能将变量放在单引号外面;
双引号字符串:
- 双引号里可以有变量;
- 双引号里可以出现转义字符;
- 字符串拼接时,可以将字符串放在双引号里面或外面,在里面时变量最好用大括号包起来;
- 获取字符串长度:${#egstring};
- 获取子字符串:${egstring:i:n},从egstring的第i个位置开始截取n个字符;
注释
- 单行注释:“#” 开头即可;
- 多行注释:“:<<flag” 开头,flag结尾,flag可以是任何标志;
:<<eof 注释内容…… 注释内容…… …… eof
数组
- 数组名=(值1 值2 … 值n):值用空格隔开,或是用换行隔开,或是直接通过下标赋值,初始化时不需要定义数组大小;
- ${数组名[下标]}:读取指定下标的值;
- ${数组名[@]}:获取数组中所有的元素;
- ${#数组名[@/*/n]}:三种方式都可以获取数组的长度;
脚本命令参数
- “命令名 参数1 参数2 ……”
- $0:当前shell脚本的文件名,包含文件路径;
- n : 参 数 位 置 的 变 量 , 注 意 两 位 数 的 位 置 参 数 要 用 包 起 来 , n:参数位置的变量,注意两位数的位置参数要用{}包起来, n:参数位置的变量,注意两位数的位置参数要用包起来,{11};
- $#:统计参数个数;
- ∗ : 以 一 个 字 符 串 显 示 所 有 向 脚 本 传 递 的 参 数 , 如 " *:以一个字符串显示所有向脚本传递的参数,如 " ∗:以一个字符串显示所有向脚本传递的参数,如"*" 用「"」括起来的情况,以"$1 $2 … $n"的形式传递所有参数,即只有一个参数;
- @ : 以 一 个 字 符 串 显 示 所 有 向 脚 本 传 递 的 参 数 , 如 " @:以一个字符串显示所有向脚本传递的参数,如 " @:以一个字符串显示所有向脚本传递的参数,如"@" 用「"」括起来的情况,以"$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数,即有n个参数;
- $?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误;
基本运算符
算术运算符
- 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk,expr,[];
- expr 是一款表达式计算工具,使用它能完成表达式的求值操作;
- 表达式和运算符之间要有空格;
- 完整的表达式要被
包含;
- 乘号(*)前边必须加反斜杠()才能实现乘法运算;
- 条件表达式要放在方括号之间,并且要有空格,例如: [ a = = a== a==b] 是错误的,必须写成 [ $a == $b ];
- eg:val=
expr 2 + 2
,result=$[a+b];
关系运算符
- 关系运算符只支持数字,不支持字符串,除非字符串的值是数字;
- -eq:equal,是否相等;
- -ne:not equal,是否不相等;
- -gt:grater than,是否大于;
- -lt:less than,是否小于;
- -ge:grater equal,是否大于或等于;
- -le:less equal,是否小于或等于;
- eg:if [ $a -ne $b ];
逻辑运算符
- !:非;
- &&:与;
- ||:或;
- -a:and,与;
- -o:or,或;
- eg:[ $a -lt 20 -a $b -gt 100 ] 返回 false;
字符串运算符
- =:字符串是否相等;
- !=:字符串是否不相等;
- -z:字符串长度是否为0,[ -z $a ];
- -n:字符串长度是否不为0,[ -n $a ]
文件测试运算符
- -b file:检测文件是否为块设备;
- -c file:检测文件是否字符块设备;
- -f file:检测文件是否为普通文件;
- -d file:检测文件是否为目录;
- -g file:检测文件是否设置了SGID位,超级组;
- -u file:检测文件是否设置了SUID位,超级用户;
- -p file:检测文件是否为管道;
- -k file:检测文件是否设置了粘着位(Sticky Bit);
- -e file:检测文件是否存在;
- -s file:检测文件是否为空;
- -S file:检测文件是否为socket;
- -L file:检测文件是否存在并且为一个符号链接;
- -r/w/x file:判断当前用户对该文件是否有读/写/执行权限;
printf命令
- 语法:printf format-string [arguments…];
- eg:printf “%-10s %-8s %-4.2f\n” 杨过 男 48.6543;
- %s:输出一个字符串;
- %d:整型输出;
- %c:输出一个字符;
- %f:输出实数,以小数形式输出;
- %-10s:格式化为 10 宽度的字符串,- 表示左对齐,没有则表示右对齐,任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来;
- %-4.2f:格式化为 4 位有效数字的小数,保留小数点后 2 位;
test命令
- test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试;
- test 命令相当于条件表达式中的 ”[]" 的作用;
- eg:if test -e ./bash;
shell 流程控制
if语句:
- 语法
if [ condition ]; then command; fi; if [ condition ] then command fi if [ condition ]; then command1; else command2; fi; if [ condition1 ] then command1 elif [ condition2 ] then command2 else command3 fi
- sh 流程控制不可为空,如果else没有语句执行,就不需要写这个分支;
for语句:
- 语法
for var in item1 item2 ... itemN; do command1; command2… done; for var in item1 item2 ... itemN do command1 command2 ... commandN done
- 当变量值在列表里,for 循环即执行一次所有命令,使用变量名获取列表中的当前取值;
- 命令可为任何有效的 shell 命令和语句;
- in 列表可以包含替换、字符串和文件名;
while语句:
- 语法
while condition do command done
- 常用于从文件中读取数据
until语句:
- 语法
until condition do command done
- until 循环执行一系列命令直至条件为 true 时停止;
case语句:
- 语法
case v in mod1) command1 command2 ... commandN ;; mod2) command1 command2 ... commandN ;; esac
- 取值后面必须为单词 in,每一模式必须以右括号结束;
- 用两个分号 “;;” 表示 break,即执行结束,跳出整个 case … esac 语句;
- 取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ”;;“;
- 如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令;
- break 跳出所有循环;
- continue 跳出当前循环;
函数
- 语法
[ function ] funname(){ command [return int] }
- function 关键字可有可无;
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值,return后跟数值n(0-255);
- 函数返回值在调用该函数后通过 $? 来获得;
- 所有函数在使用前必须定义,这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用,调用函数仅使用其函数名即可;
- 调用函数时可以向其传递参数,在函数体内部,通过 $n 的形式来获取参数的值;
- 当n>=10时,需要使用${n}来获取参数;
- 其他命令符号参考前面脚本命令;
- eg:
funWithParam(){ echo "第一个参数为 $1 !" echo "第十个参数为 ${10} !" echo "参数总数有 $# 个!" echo "作为一个字符串输出所有参数 $* !" } funWithParam 1 2 3 5 6 7 8 9 34 73
重定向输入输出
重定向命令列表
命令 | 说明 |
---|---|
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),1 是标准输出(STDOUT),2 是标准错误输出(STDERR);
- 同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中;
command1 < infile > outfile
- 如果希望 stderr 重定向到 file,可以这样写:
$ command 2>file
- 如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
$ command > file 2>&1
Here Document
- Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序;
- 基本的形式如下:
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 commandcommand << delimiter document delimiter
- 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进,开始的delimiter前后的空格会被忽略掉;
/dev/null 文件
- 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null
- /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到;
- /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果;
文件包含
- 语法
. filename # 注意点号(.)和文件名中间有一空格
或
source filename - Shell 也可以包含外部脚本,这样可以很方便的封装一些公用的代码作为一个独立的文件;
其他
- echo自动添加换行符,\c表示不换行