zoukankan      html  css  js  c++  java
  • shell基础笔记

    什么是shell脚本

    我自己对shell脚本的理解就是一系列的shell命令加入逻辑关系,实现类似“批处理”的功能。而不是简单的命令的堆砌,那样的shell脚本bug重重.

    脚本开头需加#!/bin/bash (python 用#!/usr/bin/env python) 作为解释器,若不指定解释器,则需要对应的解释器来执行脚本

    [root@server24 shell]# bash test.sh
    [root@server24 shell]# python test.py

    bash脚本的执行

    当shell脚本以非交互的方式运行时,他先会查找环境变量ENV,该变量指定了一个环境文件(通常是 .bashrc),然后从该环境变量文件开始执行,当读了ENV文件后,SHELL开始执行shell脚本中的内容。

    rename 更名

    格式:rename old_name new_name file

    [root@server24 shell]# ll
    total 8
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_10.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_1.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_2.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_3.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_4.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_5.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_6.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_7.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_8.jpg
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_9.jpg
    [root@server24 shell]# for i in `ls *.jpg`; do rename  ".jpg" ".png" $i; done
    [root@server24 shell]# ll
    total 8
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_10.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_1.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_2.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_3.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_4.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_5.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_6.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_7.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_8.png
    -rw-r--r-- 1 root root   0 Jun  6 13:20 echo_33804139_9.png

    ${}

    ${}虽然只有三个字符,但是功能特别强大。下面简单示例其功能
    假设定义两个变量test,result
    result=${test:-UNSET} 其表示的意思是:当test没有赋值时,将UNSET赋值给result,防止变量因为无定义,而导致最终结果无值。但并不给test赋值

    [root@server24 shell]# result=${test:-'None'}
    [root@server24 shell]# echo $result
    None
    [root@server24 shell]# echo $test
    
    [root@server24 shell]# 

    result=${test:=UNSET} 其表示的意思是: 当test没有赋值时,将UNSET赋值给test。防止变量无定义

    [root@server24 shell]# result=${test:='None'}
    [root@server24 shell]# echo $result
    None
    [root@server24 shell]# echo $test
    None
    [root@server24 shell]# 

    计算变量长度方法及性能比较

    常见的计算变量长度的方法有

    echo ${#test}
    echo $test | wc -w
    echo $(expr length “$test”)

    对如上三种方法进行性能测试(将计算变量时间扩大10000倍)

    time for i in `seq 10000`;do count=${#chars} ; done
    real    0m1.049s
    user    0m1.047s
    sys 0m0.000s
    time for i in `seq 10000`;do count=`echo "$chars" | wc -m` ; done
    real    0m32.815s
    user    0m6.768s
    sys 0m23.580s
    time for i in `seq 10000`;do count=`echo expr length "$chars"` ; done
    real    0m12.342s
    user    0m1.212s
    sys 0m6.831s

    从上面结果显示,虽然三种计算方法拥有同样的执行功能,但在性能(速度)上千差万别,所以一般在shell编程中劲量使用内置操作或函数完成,而不是使用外部调用命令。

    变量的数值计算

    (()) let expr bc $[]
    (()) 一般置于$((….))语法中,如同引用双引号功能

    let 效率无(())高

    [root@server22 ~]# i=2
    [root@server22 ~]# let i=i+3
    [root@server22 ~]# echo $i
    5

    expr 将其后的串解释为表达式并计算其值,运算符前后必需有空格,特殊字符需要用转义字符

    [root@server22 ~]# expr 2+2
    2+2
    [root@server22 ~]# expr 2 * 2
    expr: syntax error
    [root@server22 ~]# expr 2 * 2
    4
    使用 expr $[$a*$b] 则不需要空格
    
    [root@server22 ~]# expr $[2*3]
    6

    拓展:expr的其他用法

    使用expr可判断其拓展名,若为真,返回非0: expr “$1” : “.*.pub”
    
    [root@server22 ~]# expr "test.pub" : ".*.pub"
    8
    [root@server22 ~]# expr "test.txt" : ".*.pub"
    0
    使用expr也可判断是否为整型
    
    [root@server22 ~]# expr g + 0
    expr: non-numeric argument

    bc 支持小数的运算

    [root@server22 ~]# echo 5.43+4 |bc  #中间空格可有可无
    9.43
    [root@server22 ~]# echo `seq -s "+" 10`| bc
    55  #1..10累加
    [root@server22 ~]# echo "obase=2;256"| bc
    100000000   ##进制转换
    [root@server22 ~]# echo "scale=2; 5.23 / 3.4 " | bc
    1.53   #保留两位小数

    附加一个在练习脚本时遇到的一个小问题

    简单数值计算

    #!/bin/bash
    function error() {
            echo 'input error'
            exit 1
    }
    
    [ $# -eq 3 ] || error
    expr $1 + 0 > /dev/null 2>&1
    [ $? -ne 0 ] && error
    #echo $2
    [ "${2}" != '+' ] && [ $2 != '-' ] && [ "${2}" != '*' ] && [$2 != '/' ] && [ ${2} != '**' ]  && [ "$2" != '%' ]  &&  error
                    expr $3 + 0 > /dev/null 2>&1
                    [ $? -ne 0 ] && error
    
    echo $(($1 $2 $3))
    [root@server24 shell]# ./guo_test_1.sh 5 * 8
    ./guo_test_1.sh: line 11: [: too many arguments
    40

    在执行脚本时,运算符遇到*、**等特殊字符时就会报错,在传参时明明做了字符转义,字符串比较时又使用了其特殊用法,最后计算时又恢复了其字面意思。搞不懂了

    ====================修改于2016年7月24日=======================

    将之前脚本重新执行了一下,观察得到:运算符在第一次的判断语句中是按照字面意思去执行,但是在第二次判断中,使用了其特殊用法,导致整个判断语句终止。在后面的执行过程中与判断无关,所以计算时还会按照我们设定的去运算。为什么第二次会变成那样呢?原来在脚本里面第一次判断时,我加了双引号表示传入的参数为一个字符串,而第二次没有加,所以将所有变量值打印出来,因此将脚本修改如下:

    #!/bin/bash
    function error() {
            echo 'input error'
            exit 1
    }
    
    [ $# -eq 3 ] || error
    expr $1 + 0 > /dev/null 2>&1
    [ $? -ne 0 ] && error
    [ "$2" != '+' ] && 
    [ "$2" != '-' ] && 
    [ "$2" != '*' ] && 
    [ "$2" != '/' ] && 
    [ "$2" != '**' ]  
    && [ "$2" != '%' ]  &&  error
    expr $3 + 0 > /dev/null 2>&1
    [ $? -ne 0 ] && error
    
    echo $(($1 $2 $3))

    在尝试过程中曾用case语句去执行,但是这种方法有点繁琐。

    #!/bin/bash
    function error() {
            echo "input error"
            exit 1
    }
    [ $# -eq 3 ] || error
    expr $1 + 0 > /dev/null 2>&1
    [ $? -ne 0 ] && error
    expr $3 + 0 > /dev/null 2>&1
    [ $? -ne 0 ] && error
    case $2 in
            '*')
            echo $(($1 $2 $3))
            ;;
            '**')
            echo $(($1 $2 $3))
            ;;
            '+')
            echo $(($1 $2 $3))
            ;;
            '-')
            echo $(($1 $2 $3))
            ;;
            '/')
            echo $(($1 $2 $3))
            ;;
            '%')
            echo $(($1 $2 $3))
            ;;
            *)
            error
            ;;
    esac
    [root@server22 shell]# ./compu_1.sh 3 ** 4
    81
    [root@server22 shell]# ./compu_1.sh 3 * 4
    12
    [root@server22 shell]# ./compu_1.sh 3 / 4
    0
    [root@server22 shell]# ./compu_1.sh 3 % 4
    3
    [root@server22 shell]# ./compu_1.sh 3 + 4
    7
    [root@server22 shell]# ./compu_1.sh 3 - 4
    -1

  • 相关阅读:
    java调用oracle存储过程
    高富帅屌丝买房差异大 看看都该买什么房
    c#控制IE浏览器自动点击等事件WebBrowser,mshtml.IHTMLDocument2
    .net 实现微信公众平台的主动推送信息
    HTML+CSS面试知识点分享(一)
    JS面试知识点分享(一)
    HTML+CSS面试知识点分享(二)
    jQuery选择器学习理解
    PB程序系统错误处理记录
    sql server2000 直接读取excel2003文件的sheet
  • 原文地址:https://www.cnblogs.com/guoew/p/10391055.html
Copyright © 2011-2022 走看看