目录
1.shell脚本的执行方法
2.shell的变量类型
3.shell特殊变量
4.变量子串的常用操作
5.批量修改文件名实践
6.变量替换
7.在shell中计算字符串长度的方法
8.变量的数值计算:(()) 的用法
9.待续
1.shell脚本的执行方法返回目录
当shell脚本以非交互的方式运行时,它会先查找环境变量ENV,该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当读取了ENV文件后,SHELL才开始执行shell脚本中的内容。
shell脚本的执行通常可以采用以下三种方法:
第一种方法是脚本文件本身没有可执行权限时,通常使用的方法;
第二种方法需要先将脚本文件的权限改为可执行,然后通过脚本路径就可以直接执行;
第三中方法是在当前shell环境中直接执行,而不是新创建一个子shell,当我们需要在一个脚本中使用另一个脚本中的变量的时候就使用第三种方法,例如创建如下脚本,其中定义了chars变量:
通过上面三种方法执行:
可以看出方法1,2执行脚本是系统会自动新创建一个子shell,执行之后,其变量不会在当前shell有效,而第三种方法是告诉系统让这个脚本直接在当前shell执行,显然其定义的变量chars在当前shell中也是有效的,所以需要在某个脚本中使用另外一个脚本中的变量时,需要使用第3中方法执行脚本。
2.shell的变量类型 返回目录
shell中的变量分为环境变量和全局变量
环境变量也称为全局变量,可以在创建他们的shell及其派生的任意子进程shell中使用。局部变量只能使用在创建它们的shell函数或脚本中使用。
环境变量用于定义Shell的运行环境,保证shell命令的正确执行,shell通过环境变量来确定登录用户名,命令路径,终端类型,登录目录。环境变量可以在命令行中设置,但用户退出时这些变量值也会丢失,因此最好在用户家目录下的.bash_ptofile文件会全局配置/etc/profile文件或者/etc/profile.d中定义,将环境变量放入profile中,每次用户登录,这些变量值都将被初始化。
传统上,所有环境变量均为大写。环境变量用于用户进程前,必须用export命令导出。
有一些环境变量,比如HOME,PATH,SHELL,UID,USER等在用户登录之前就已经被/bin/login程序设置了,通常环境变量的定义并保存在用户的家目录下的./bash_profile文件中。
已经定义的变量可以用unset在取消定义。
本地变量定义的三种方式:
var_name=value
var_name='value'
var_name="value"
下面看看这三种方式的区别
第一种方法是直接定义变量内容,但是内容必须连续,中间不能有空格字符;
接着看下面:
第二种方法通过单引号定义变量,只会原样输出字符串内容,而不会对字符串中的变量和特殊字符进行解析,适合定义单纯字符显示;
第一种和第三种,输出时,会对内容进行解析,输出解析后的内容,有于第一种方法不能定义不连续的变量,所以通常在需要解析的时候都加上双引号,而很少使用第一种方法,第一种方法一般仅仅用来定义连续的数字或者路径。
3.shell的特殊变量 返回目录
位置变量
$/$0$ 获取当前执行脚本的文件名,包括路径;
$/$n$ ,获取当前执行的shell脚本的第n个参数,n=1,...,9,如果 n 大于9, 使用大括号${10};
$/$*$ 获取当前shell的所有参数,将命令行参数视为单个字符串,相当于$"/$1/$2/$3.../$n"$;
$/$$# 获取当前shell脚本或者命令行参数的总个数;
$/$$@ 这个程序的所有参数 $"/$1" "/$2" "/$3" "...", $这是将参数传递给其他程序的最佳方式,因为它会保留所有内嵌在每个参数里的任何空白。
进程状态变量
$/$/$$ 获取当前shell的进程号(PID)
$/$$? 获取上一个指令的返回值(0 为成功,非零为失败)
4.变量子串的常用操作 返回目录
编号 | 表达式 | 说明 |
1 | ${#string} | 返回$string的长度 |
2 | ${string:position} | 在$string中,从位置position之后开始提取子串 |
3 | ${string:position:length} | 在$string中,从位置position之后开始提取长度为$length的子串 |
4 | ${string#substring} | 从变量$string开头删除最短匹配$substring子串 |
5 | ${string##substring} | 从变量$string开头删除最长匹配$substring子串 |
6 | ${string%substring} | 从变量$string结尾删除最短匹配$substring子串 |
7 | ${string%%substring} | 从变量$string结尾删除最长匹配$substring子串 |
8 | ${string/substring/replace} | 使用$replace来代替第一个匹配的$substring |
9 | ${string//substring/replace} | 使用$replace来代替所有匹配的$substring |
10 | ${string/#substring/replace} | 如果$string前缀匹配$substring,就用$replace来代替匹配的字符串$substring |
11 | ${string/%substring/replace} | 如果$string后缀匹配$substring,就用$replace来代替匹配的字符串$substring |
举例说明如下:
5.批量修改文件名实践 返回目录
例如有下面的文件:
现在想要将后缀前部改为大写JPG:
方法一:
#!/bin/bash for obj in $(ls *.jpg) do mv ${obj} $(echo ${obj/%jpg/JPG}) done
方法二:
rename 's/jpg$/JPG/' *.jpg
6.变量替换 返回目录
运算符号 | 作用 |
${value:-word} | 如果变量名存在且非null,返回变量值;否则,返回word字符串 用途:如果变量未定义,则返回默认值 |
${value:=word} | 如果变量名存在且非null,返回变量值;否则,设置这个变量值为word 用途:如果变量未定义,,则设置变量为默认值,并返回默认值 |
${value:?"not defined"} | 如果变量名存在且非null,返回变量值;否则显示“not defined”,并退出当前命令或脚本。 用途:用于捕捉由于变量未定义而导致的错误,并退出程序。 |
${value:+word} | 如果变量名存在且非null,返回word,否则返回null。 用途:测试变量是否存在。 |
示例如下:
7.在shell中计算字符串长度的方法返回目录
建立一个字符串:
注意:使用 wc -m 的方法会计算换行符,因为echo会在输出完字符串之后自动加上一个换行符,使用echo -n 会去掉换行符:
比较上面三种方法的效率:
time :
获取一个程序的执行时间,可以获取到实际运行时间以及程序在用户态和内核态分别的时间,大部分的性能测试,可能只需要关注实际(real)时间
看到上面三种获取字符串长度的速度相差几十倍到上百倍,一般调用外部命令处理,与内置功能性能相差很大。所以在shell编程,尽量使用内置操作或函数完成。
8.变量的数值计算:(())的用法 返回目录
(1) (())用法:(此法很常用,且效率高)
用于执行的整数运算,支持的运算符与C语言中的基本一致,除了特别注意 "**" 在 (()) 中表示幂运算,而C语言不支持,如 ((2**3)) 结果是 8.
示例:
注意:1)**表示幂运算
2)上面涉及的变量元素必须为整型,不能是小数和字符,涉及小数的后面使用 bc 可以实现。
(()) 内部的变量可以不用加 $/$$ 符号 :
各种shell运算的脚本例子:
实践:用shell脚本编写一个实现加,减,乘,除的计算器:
9 待续