shell基础笔记
2016-06-08 16:38
591 查看
什么是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
相关文章推荐
- android wifi 无线调试
- 运维入门
- 动态清空 nohup 输出文件
- install scrapy with pip and easy_install
- Linux Shell常用技巧
- Shell 脚本编程陷阱
- VBS脚本写的Windows硬件检测工具分享
- 用vbscript实现隐藏任务栏图标的脚本
- 用autoit编写第一个脚本(Hello World)
- VBS调用WMI快速关闭IE的脚本
- Oracle数据库执行脚本常用命令小结
- 收集的ROS防火墙脚本
- JSP脚本漏洞面面观
- shell字符串操作详解
- 不错的批处理脚本 第一部分
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- 不错的批处理脚本实例代码 第二部分
- 使用脚本和批处理清除电脑中的痕迹的代码第1/2页