Shell基础简介

目录

Shell脚本

printf函数

变量基础

变量

特殊变量:

变量替换

字符串类型

字符串连接

字符串操作

数组类型

定义

读取

长度

删除操作

切片访问

模式替换

数组遍历

运算符说明

算术运算符

关系运算符

布尔运算符

字符串运算符

文件测试运算符

条件语句

if语句

case语句

for循环

while循环

until循环

shell函数

Echo输出控制

字颜色

字背景颜色

控制选项说明


Linux下命令行程序叫做 Shell,除解释用户的输入命令,还可以:

  • 调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果;

  • 在多个程序之间传递数据,把一个程序的输出作为另一个程序的输入;

  • Shell 本身也可以被其他程序调用。

Shell脚本

Shell是一种脚本语言(常见的解释器有bash、sh、csh等),支持基本的编程元素,如:

  • if...else 选择结构,case 开关语句,for、while、until 循环;

  • 变量、数组、字符串、注释、加减乘除、逻辑运算等概念;

  • 函数,包括用户自定义的函数和内置函数(例如 printf、export、eval 等)。

Shell脚本也可以包含外部脚本(其他脚本文件),将外部脚本的内容合并到当前脚本。

. filename

#或

source filename

  • 两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格

  • 被包含脚本不需要有执行权限。

printf函数

除用echo输出外,printf有更强的控制方式:

  • 与c中的printf类似,但是参数不用括号,参数间用空格风格

  • 参数比控制字符多时,也会按顺序输出;

  • 参数比控制字符少时,%s用NULL代替,%d用0代替;

如:

printf '%s %d' a  #输出:a 0

printf 'Test: %s %s' a b c d e #输出:

    Test: a b

    Test: c d

    Test: e

变量基础

创建shell脚本时,必须在文件第一行指定要使用的shell:

#!/bin/bash

set -e # 遇到执行错误,退出(默认继续执行下一条)

set -u # (set -o nounset),使用未初始话变量时,脚本自动退出

脚本创建完成后,就需要执行脚本

  • chmod u+x添加X权限,调用文件执行;如./file.sh

  • 通过过sh file.sh来执行:不需要添加执行权限;

  • root用户可通过点号(.)来执行(不需执行权限),如:

. /lib/init/vars.sh

变量

  • 直接赋值即定义:count=100 #等号两边不能有空格

  • 通过$来引用变量:$count或${count}

  • readonly修饰只读变量:readonly count=100

  • unset删除变量:unset count

如:

count=1

count=`expr $count+1`

特殊变量

通过特殊变量可获取shell的参数:

  • $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。但是当它们被双引号(" ")包含时:

    • "$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;

    • "$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

  • shift:移动变量,将每个参数变量减一;如$3变为$2;

  • if [ -n "$1" ]:来判断参数是否已传递。

  • 更多的参数,需要加花括号引用:${10};

  • 获取最后一个参数:${!#}。

变量替换

根据变量的状态(是否为空、是否定义等)来改变它的值

三种类型变量

  • 局部变量:在脚本或命令中定义,仅在当前shell实例中有效。

  • 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量。shell脚本也可以定义环境变量。

  • shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。

字符串类型

字符串可用单双引号:

  • 单引号的限制:

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

    • 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

  • 双引号的优点:

    • 双引号里可以有变量

    • 双引号里可以出现转义字符

字符串连接

  • 直接联接两个字符串

    • newfile=${file}"new"

    • newfile=${file}${new}

  • 使用printf(使用反引号)可以进行更复杂的联接

    • newstr=`printf "%s%s" "$STR" "$USER"`

字符串操作

表达式

含义

${#str}

$str的长度

${str:position}

在$str中,从位置$position开始提取子串

${str:position:length}

在$str中,从位置$position开始提取长度为$length的子串

Position为0-n时表示从右边开始:

l${str:0-7}:取末尾7个字符

l${str:0-7:3}

${str#substring}

从变量$str的开头,删除最短匹配$substring的子串

${str##substring}

从变量$str的开头,删除最长匹配$substring的子串

${str%substring}

从变量$str的结尾,删除最短匹配$substring的子串

${str%%substring}

从变量$str的结尾,删除最长匹配$substring的子串

${str/old/new}

使用$new,来代替第一个匹配的$old

${str//old/new}

使用$new,代替所有匹配的$old

${str/#old/new}

替换开头.如果$str以$old开头,那么就用$new替换

${str/%old/new}

替换结尾.如果$str以$old结尾,那么就用$new替换

${VALUE%.*}:删除VALUE字符串中以分隔符“.”匹配的右边字符,保留左边字符。

${VALUE#*.}:删除VALUE字符串中以分隔符“.”匹配的左边字符,保留右边字符。

补充

  • “*”表示通配符,用于匹配字符串将被删除的字串。

  • “.”表示字符串中分隔符,可以为任意一个或多个字符。

  • “%”表示从左向右匹配,“#”表示从右向左匹配,“/”表示替换,都属于非贪婪匹配,即匹配符合通配符的最短结果。而“%%”、“##”和“//”,都属于贪婪匹配,即匹配符合通配符的最长结果。

数组类型

数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组)。初始化时不需要定义数组大小,数组元素的下标由0开始。数组用括号来表示,元素用"空格"符号分割开,语法格式如下:

array_name=(value1 ... valueN)

定义

myAry=(A B "CD"  1 2)

也可以使用下标来定义数组:

myAry[0]=value0

myAry[1]=value1

...

myAry[N]=valueN

读取

${myAry[index]}

echo ${myAry} 输出第一个元素

使用@ 或 * 可以获取数组中的所有元素

echo "数组的元素为: ${myAry[*]}"

echo "数组的元素为: ${myAry[@]}"

长度

获取数组长度的方法与获取字符串长度的方法相同

echo "数组长度: ${#myAry[*]}"

echo "数组元素个数: ${#myAry[@]}"

删除操作

清除某个元素:unset myAry[1],这里清除下标为1的数组;

清空整个数组:unset myAry;

切片访问

${array[@]:起始位置:长度}

  • 中间以":"隔开,

    • 起始位置省略从0开始;

    • 长度省略,就取后面所有的项;

  • 切片后返回的是字符串,可以通过 新数组=(${旧数组[@]:索引:长度})来获取

  • 起始位置可以为负数,但必须以放在()中,长度不能为负数

${myAry[@]::4}    #获取前四个元素

${myAry[@]:(-2)}    #获取后两个元素

newAry=${myAry[@]:1:4}    #生成新的切片

模式替换

${数组名[@或*]/模式/新值}

例如:${myAry[@]/2/98}

数组遍历

数组遍历我们使用for语句来演示:

for v in ${myAry[@]}; do

  echo $v;

done

运算符说明

算术运算符

原生bash不支持简单的数学运算,但可以通过其他命令(如 awk 和 expr)来实现 :

  • +、-、*、/、%

  • =、==、!=

 expr是一款表达式计算工具,使用它可以完成表达式的求值操作:

  • 在 expr中的 表达式与运算符之间要有空格,否则错误;

  • 在[ $a == $b ]与[ $a != $b ]中,要需要在方括号与变量以及变量与运算符之间也需要有空格, 否则错误。

如:

echo `expr $a + $b`

echo `expr $a \* $b`  #乘号要转义

val=`expr 10 - 3`    #表达式需要用反引号(`,~键那个)括起来

关系运算符

只支持数字(或值为数字的字符串)

  • -eq:两个数是否相等,相等返回 true。

  • -ne:两个数是否相等,不相等返回 true。

  • -gt:左边的数是否大于右边的。

  • -lt:左边的数是否小于右边的。

  • -ge:左边的数是否大等于右边的。

  • -le:左边的数是否小于等于右边的。

如:

[ 5 -eq 3 ] 返回 false

[ 5 -ne 3 ] 返回 true  #方括号与变量以及变量与运算符之间也需要有空格

布尔运算符

  • !:非, [ !false ]为true

  • -o:或

  • -a:与, [ $a -a $b ],都为true是为true

字符串运算符

  • =:两个字符串是否相等,相等返回 true。

  • !=:两个字符串是否相等,不相等返回 true。

  • -z:字符串长度是否为0,为0返回 true。

  • -n:字符串长度是否为0,不为0返回 true。

  • [ str ]:字符串是否为空,不为空返回 true。

如,以a="test"为例

[ -z $a ] 返回 false

[ $a ] 返回 true

文件测试运算符

检测文件的各种属性

  • -b file:文件是否是块设备文件,如果是,则返回 true。

  • -c file:文件是否是字符设备文件,如果是,则返回 true。

  • -d file:文件是否是目录,如果是,则返回 true。

  • -f file:文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。

  • -r file:文件是否可读,如果是,则返回 true。

  • -w file:文件是否可写,如果是,则返回 true。

  • -x file:文件是否可执行,如果是,则返回 true。

  • -s file:文件是否为空(文件大小是否大于0),不为空返回 true。

  • -e file:文件(包括目录)是否存在,如果是,则返回 true。

  • -g file:文件是否设置了 SGID 位,如果是,则返回 true

  • -k file:文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。

  • -p file:文件是否是具名管道,如果是,则返回 true。

  • -u file:文件是否设置了 SUID 位,如果是,则返回 true。

如:

[ -r $file ]     #是否可读

[ -e $file ]    #是否存在

条件语句

shell语句默认使用回车分隔(每条语句一行),若要在一行中输入多条语句可通过分号分隔实现:

if [ *** ]; then

while [ *** ]; do

针对数字与字符串判断有扩展特性,放在判断条件时与if/while等中间要保证有空格:

  • 双括号(( expression )):用于数学表达式,内部可是任意的数学计算或比较表达式

if (($COUNT ** 2 > 90)); then
    ((var2 = $var ** 2))
fi
  • 双方括号[[ expression ]]:expression两边要加空格,用于字符串处理   

a="aa"
b="bb"
if [[ "$a" > "$b" ]]; then
    echo "$a is large"
elif [[ "$a" < "$b" ]]; then
    echo "$a is small"
else
    echo "$a equal $b"
fi
  • 方括号[ expr ]:逻辑判断(见运算符说明部分)

    if [ -d file ] 条件检测

if语句

if [[ "$a" > "$b" ]]; then
    echo "$a is large"
elif [[ "$a" < "$b" ]]; then
    echo "$a is small"
else
    echo "$a equal $b"
fi

case语句

case 值 in

模式1)

    command...

    ;;

模式2)

    command...

    ;;

*)

    command...

    ;;

esac

  • 取值后面必须为关键字 in,每一模式必须以右括号结束。

  • 取值可以为变量或常数;匹配某一模式后,执行其后所有命令直至 ;;(双分号)。

  • 如果无一模式匹配,执行*后的命令。

如:

for a in root xugd test none; do

    echo $a

    case $a in

    root)

        echo admin

        ;;

    xugd | test ) #多个值可用|分隔

        echo normal

        ;;

#   *)

#       echo default

#       ;;

    esac

done

for循环

for循环有两种常用用法,for...in与for((赋值;条件;运算语句)) 

for var in list # for((赋值;条件;运算语句)) 

do

  commands

done

示例:循环十次

for((i=1;i<=10;i++));do 

    echo $(expr $i \* 3 + 1);

done

for i in $(seq 1 10)

do 

    echo $(expr $i \* 3 + 1);

done

#for i in {1..10};do

for i in 1 2 3 4 5;do    #直接把值列出即可(用空格分隔)

    echo $(expr $i \* 3 + 1);

done

示例:枚举文件

for file in /proc/*; do

    echo $file

done

for file in $(ls *.sh); do

    echo $file

done

while循环

while <condition>

do

action

done;

例:

i=10;

while [[ $i -gt 5 ]]; do

    echo $i;

    ((i--));

done; 

until循环

until <condition>

do 

action

done

例:

a=10;

until [[ $a -lt 0 ]];do

    echo $a;

    ((a—));

done; 

# break 命令不执行当前循环体内break下面的语句从当前循环退出。

# continue 命令是程序在本循体内忽略下面的语句,从循环头开始执行。

shell函数

Shell函数必须先定义后使用,function关键字是可选的:

[function] function_name () {

    list of commands

    [ return value ]

}

注意:

  • 调用函数只需要给出函数名,不需要加括号;

  • 函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值;

  • Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败;

  • 函数的参数可以通过 $n  得到;

  • 像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项。

Echo输出控制

通过echo可方便输出,并控制颜色格式:

  • -e 用来开启echo中的转义

  • 设置颜色的格式:

    • echo -e "\033[字背景颜色;文字颜色m字符串"

    • echo -e "\e[0m":恢复默认

输出红色字体 abc,背景色不变;然后还原

echo -e '\033[0;31;1m abc \033[0m'

  • 文字颜色后面有个m

  • 字符串前后可以没有空格,如果有的话,输出也是同样有空格

字颜色

范围:30—–37

  • echo -e “\033[30m 黑色字 \033[0m”

  • echo -e “\033[31m 红色字 \033[0m”

  • echo -e “\033[32m 绿色字 \033[0m”

  • echo -e “\033[33m 黄色字 \033[0m”

  • echo -e “\033[34m 蓝色字 \033[0m”

  • echo -e “\033[35m 紫色字 \033[0m”

  • echo -e “\033[36m 天蓝字 \033[0m”

  • echo -e “\033[37m 白色字 \033[0m”

字背景颜色

范围:40—–47

  • echo -e “\033[40;37m 黑底白字 \033[0m”

  • echo -e “\033[41;37m 红底白字 \033[0m”

  • echo -e “\033[42;37m 绿底白字 \033[0m”

  • echo -e “\033[43;37m 黄底白字 \033[0m”

  • echo -e “\033[44;37m 蓝底白字 \033[0m”

  • echo -e “\033[45;37m 紫底白字 \033[0m”

  • echo -e “\033[46;37m 天蓝底白字 \033[0m”

  • echo -e “\033[47;30m 白底黑字 \033[0m”

控制选项说明

  • \33[0m 关闭所有属性

  • \33[1m 设置高亮度

  • \33[4m 下划线

  • \33[5m 闪烁

  • \33[7m 反显

  • \33[8m 消隐

  • \33[30m — \33[37m 设置前景色

  • \33[40m — \33[47m 设置背景色

  • \33[nA 光标上移n行

  • \33[nB 光标下移n行

  • \33[nC 光标右移n行

  • \33[nD 光标左移n行

  • \33[y;xH设置光标位置

  • \33[2J 清屏

  • \33[K 清除从光标到行尾的内容

  • \33[s 保存光标位置

  • \33[u 恢复光标位置

  • \33[?25l 隐藏光标

  • \33[?25h 显示光标

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值