由浅到深理解shell

1. shell中的特殊变量

变量名含义
$0shell或shell脚本的名字
$*显示所有的参数(以一对双引号给出参数列表)
$@显示所有的参数(将各个参数分别加双引号返回)
$#传递给脚本参数的个数
$_代表上一个命令的最后一个参数
$$代表所在命令的PID
$!代表最后执行的后台命令的PID
$?代表上一个命令执行后的状态
bash -n shell.sh    # 查看是否有语法错误
bash -x shell.sh    # 单步执行

2. 变量类型

  • 本地变量
  • 环境变量: export – 导出一个环境变量
  • 局部变量
  • 位置变量
cut -d ' ' -f 2     #截取以空格为单位,第二个区间的信息
cut -c 12-20        #截取12到20位之间的信息
lines=$(wc -l $1|cut -d ' ' -f 1)
echo "$1 一共有$lines行" '$lines' "$lines"
echo $lines
shift   # 轮岗
shift 2     # 踢走2个参数

3. bash的循环语句

for   : 遍历有限的元素列表
while , until : 遍历未知的元素列表

3.1. for语句的格式

for var_name in list    # do如果与for在同一行,则用;隔开
do
    循环体
done    # 结束标志

示例

for userNo in {10..30}  # {10..30}生成10到30之间的数
do
    echo $userNo
done

for userNo in $(seq 10 15);do # $(seq 10 15)生成10到15之间的数
    echo user$userNo
done

for (( i = 0; i < 10; i++ )); do
    echo user$userNo
done

for str in "This is a string";do    #若无引号,则按空格分割,依次循环
    echo $str
done

3.2. while语句的格式

while [[ 1 ]]; do
    echo 1;
done

4. 逻辑运算

注:如果将命令执行成功与否当成条件,则if语句后必须只跟命令本身,而不能引用(用``或$())

4.1 bash

  1. 弱类型
  2. 变量=值
  3. 任何变量无需事先声明,可直接使用
    值默认为字符型:a=abc === b=”vsf” #双引号可省略

  4. 赋值: a=1
    增强型赋值:+=,-=,*=,/=,

    a= [ [ <script id="MathJax-Element-1" type="math/tex">[</script>a+1] === let a+=1 === let a++

  5. 字符原理: export PATH=$PATH::user/local/bin

4.2 算数运算

  1. bash会对数字进行隐式的类型转换

    let VAR_name=Integer_Value
    declare VAR_name=Integer_Value
  2. 操作符:+,-,,/,%,*(次方),皆为双目运算符:至少需要两个操作数
let res=$num1*$num2

let num1=$num1+9   ===     let num1+=9
除法没有小数部分,会直接省去,术语:元整除法

3. bash算数运算的方式

let a=$b+$c    #let必须实现将结果赋值于一个变量

$[$a+$b]     #不需赋值,直接引用结果

$(($a+$b))		#推荐方式,但与$[$a+$b]无显著区别

`` or $()      #中间可进行命令运行

expr:可引用,参数之间必须有空格,否则无法识别

"The sum is `expr $a + $b`"   输出: The sum is 4

for var in `seq 10 15`; do === for var in $(seq 10 15);do === for var in {10..15};do
    #statements
}
done
  • 实现变量与字串的连接:{}
animal=pig
echo "There are lot $animals." 输出:There are lot .
echo "There are lot ${animal}s" 输出:There are lot pigs

4.3 逻辑运算: 与 或 非

命令都有其状态返回值:成功:0、真,失败:1-255
  1. bash条件测试:每个命令执行结果即为条件判断

    1. 比较操作: test EXPR
test num1 > num2
echo $?        # 0true1-255false
    2. [ EXPR ]
    3. [[ EXPR ]]
    注:2 与 3 差别不大

2. 比较运算: > , < , <= , >= , != , ==

测试类型:根据比较时的操作数的类型

    整型测试:整数比较
    字符测试:字符串比较
    文件测试:判断文件的存在性及属性等

    注:比较运算通常在同一种类型中运行

整型测试:

    -gt     [ $num1 -gt $num2 ]       大于
    -lt     [ $num1 -lt $num2 ]       小于
    -ge     [ $num1 -ge $num2 ]       大于等于
    -le     [ $num1 -le $num2 ]       小于等于
    -eq     [ $num1 -eq $num2 ]       等于
    -nq     [ $num1 -nq $num2 ]       不等于

字符串测试:(字串必须用引号引起来)
    双目操作符:

        >   [ "$str1" > "$str2" ]
        <
        >=
        <=
        ==
        !=

        =~ 字段的模式匹配,一般用[[  ]]

    注:做字串比较时,变量与字符串尽量加引号,变量加双引号,可防止变量为空时语法报错

    弹幕字符串:

        -n string   测试字符是否不空,不空为真
        -z string   测试字符是否为空,空为真

3. if:三种使用格式

  • 单分支的if
if 测试条件;then
    选择分支
fi

if ! id $userid &> /dev/null;then  # &> 只要返回状态码
    useradd $userid
fi
  • 双分支的if
if 测试条件;then
    选择分支
else
    选择分支
fi
  • 多分支的if
if 条件1;then
    分支1
elif 条件2;then
    分支2
...
else
    分支n
fi
  • 自定义shell进程的状态返回值

    若参数个数小于1,退出shell脚本

    if [ $# -lt 1 ]; then
        echo "Usage : `basename $0` ARG"
        exit 2 
    fi

    例:确认传入参数的最大值

        declare -i max=0
    
        for i in $*;do
            if [ $max -lt $i ]; then
                max=$i
            fi
        done
    
        echo "The max num is $max."

    注意:如果将命令执行成功与否当成条件,则if语句后必须只跟命令本身,而不能引用(用“或$())

练习:通过命令行给定一个文件路径,而后判断,如果此文件中存在空白行,则显示空白行的次数,否则则显示无空白行

    if grep "^[[:space:]]*$" $1;then

        或者

    if [ $(grep "^[[:space:]]*$" $1 | wc -l) -lt 1 ];then

练习:如果用户主机名为localhost,将其修改为www.wjb.com

    if [[ `hostname` == 'localhost' ]]; then
        hostname www.wjb.com
    fi

练习:如果当前的主机名为空,则将其修改为用户通过参数传递过来的用户名

    hostname=`hostname`
    if [[ -z $hostname ]]; then
        hostname $1
    fi

组合条件测试:在多个条件间实现逻辑运算

    与: [ condition1 -a condition2 ] 
         condition1 && condition2       condition 为命令行输入方式

    或: [ condition1 -o condition2 ]
         condition1 || condition2

    非: [ -not condition ]  or  [ !condition ]
         ! condition

练习:如果当前的主机名为空或者为localhost,将其修改为www.wjb.com

    hostname=`hostname`
    if [[ -z "$hostname" -o "$hostname" = 'localhost' ]]; then
        hostname www.wjb.com
    fi

命令行可直接测试bool: [ 'localhost' == 'local' ];echo $?   # 可查看语句执行状态返回值

>只能将正常信息重定向
&>可以将错误信息或者普通信息都重定向输出

练习:如果某用户存在,则显示id号(命令行操作不可用[]):

    if id "wjb" &> /dev/null;then
        id -u "wjb"
    fi

练习:如果某用户存在,且answer变量的值为yes,则显示用户的id号,否则,说用户选择了退出

    id 'wjb'
    retVal=$?

    if [[ "$retVal" -eq 0 -a "$answer" == 'yes' ]]; then
        id -u "wjb"
    else
        echo '用户选择了退出'
    fi

    上述方式等同于:

    if id 'wjb' &> test && [ $answer == 'yes' ]; then
        id -u "wjb"
    else
        echo '用户选择了退出'
    fi

练习:如果传入参数大于5,则count加1,最后输出count

    #!/bin/bash
    declare -i count=0
    list=$*
    echo $list
    for str in $list;do
        if [ "$str" -gt 5 ]; then
            let count++
        fi
    done
    echo $count

5. 文件测试常用功能

-a / -e file : 文件存在才则为真,否则则为假,也可能是目录等

    if [[ -a test ]]; then
        wc -l test
    fi

-f file : 存在并且为普通文件,则为真,否则为假
-d file : 存在并且为目录时为真,否则为假

-L / -h file : 存在并且为符号链接文件,则为真,否则为假

-b file : 存在并且为块设备时为真,否则为假
-c file : 存在并且为字符设备时为真,否则为假
-S file : 存在并且为套接字文件时为真,否则为假
-p file : 存在并且为命名管道文件时为真,否则为假
-s file : 存在并且文件不为空时为真,否则为假

-r file 
-x file
-w file

file1 -nt file2 : file1的 mtime 新于file2则为真,否则为假

file1 -ot file2 : file2的 mtime 新于file1则为真,否则为假

练习:如果wget命令对应的可执行文件存在且可执行,则下载百度首页于当前目录

#!/bin/bash
#
downUrl='www.baidu.com'
if [[ -x `which curl` ]]; then
    curl $downUrl -o baidu.txt
fi

练习:给定一个文件路径
1. 判断文件是否存在,不存在,则说明文件不存在,并直接结束脚本
2. 如果文件是普通文件,则显示为’regular file’
3. 如果文件是目录,则显示为’directory’
4. 如果文件为链接文件,则显示为’Symbolic file’
5. 否则显示为’unknown file’

#!/bin/bash
if [[ ! -e $1 ]]; then
    echo 'file is not exist'
fi

if [[ -L $1 ]]; then
    echo 'Symbolic file'
elif [[ -f $1 ]]; then
    echo 'regular file'
elif [[ -d $1 ]]; then
    echo 'directory'
else
    echo 'unknown file'
fi

bash编程之交互编程

read num1

增加提示信息:

    read -p "Please input an interger:" num1 
    等价于
    echo -n "Please input an interger:";read num1

添加超时判断,秒为单位:

    read -p "Please input an interger:" -t 3 num1

添加默认值:

    if [[ -z "$num1" ]]; then
        num1='root'
    fi

cat << EOF  # 可将EOF间的内容直接输出到屏幕
    ----------menu-------------
    ----------menu-------------
    ----------menu-------------
EOF

字段的模式匹配:

[[ "$var" =~ PATTERN ]]

例: 
    var='cpu'
    [[ "$var" =~ [Cc][Pp][Uu] ]]
    echo $?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值