Shell高级编程学习笔记(基础篇)
目录
1.shell脚本的执行方法 2.shell的变量类型 3.shell特殊变量
4.变量子串的常用操作 5.批量修改文件名实践 6.变量替换
7.在shell中计算字符串长度的方法 8.变量的数值计算:(()) 的用法
9. 变量的数值计算:let的用法 10.变量的数值计算:expr的用法
15.逻辑操作符 16.利用shell知识制作单级及多级菜单
待续。。。
1.shell脚本的执行方法 返回目录
当shell脚本以非交互的方式运行时,它会先查找环境变量ENV,该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当读取了ENV文件后,SHELL才开始执行shell脚本中的内容。
shell脚本的执行通常可以采用以下三种方法:
- bash script-name 或者 sh script-name
- path/script-name 或者 ./script-name(当前路径下执行)
- source script-name 或 . script-name(注意符号“.”与 script-name之间有空格)
第一种方法是脚本文件本身没有可执行权限时,通常使用的方法;
第二种方法需要先将脚本文件的权限改为可执行,然后通过脚本路径就可以直接执行;
第三中方法是在当前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. 变量的数值计算:let的用法 返回目录
与 ((表达式)) 功能一致,但是没有 (()) 的计算效率高,所以常用 (()),而不去使用let.
10.变量的数值计算:expr的用法 返回目录
expr命令一般用于整数计算,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令计算器。
expr 的语法不是很好,所以不常用,这里标记,保证看到别人使用的时候,自己能够看懂。
下面介绍expr比较好用两个技巧
1)检查某个文件是否是某一类型或扩展名:
2)判断一个变量是否是整数:
写出判断一个输入是否为整数的脚本:
11.变量的数值计算:bc的用法 返回目录
bc支持科学计算
使用shell编写输出杨辉三角的脚本:
#!/bin/bash export LANG="zh_CN.GB18030" #本文内容来自《老男孩linux运维实战培训中心》shell 编程部分学生练习资料 #如果脚本后面没有参数,提示输入一个参数
if ( test -z $ );then
read -p "Input max int lines:" MAX
else
MAX=$
fi #判断参数的合法性
#将参数中的数字全部替换为空,然后判断替换后的内容是否为空
#若不为空,表明参数中含有非数字的其他非数字内容,则不合法
#“[ ]”的功能与test一致,可以 man test 查看
[ -n "$(echo ${MAX}|sed 's/[0-9]//g')" ] && \
echo "The number you input must be int(1-9)" && exit #将输入限制在小于10
[ ! ${MAX} -lt ] && \
echo "The number you input must be int(1-9)" && exit #start
a[]=
for ((i=;i<MAX;i++))
do
for ((j=$i;j>;j--))
do
((a[$j]+=a[$j-]))
done for ((j=;j<=MAX-i;j++))
do
if ((MAX<=));then
echo -en "\t"
else
echo -n " "
fi
done for ((j=;j<=i;j++))
do
if [ ${MAX} -le ];then
echo -en "\t\t"${a[$j]}
else
echo -en ${a[$j]}
fi
done
echo
done
运行结果:
12.条件测试的多种方法 返回目录
语法格式:
格式1:test expression
格式2:[ expression ]
格式3:[[ 测试表达式 ]]
注:中括号与表达式之间前后都有空格
格式1与格式2是等价的;格式3为扩展的test命令,在 [[ ]] 中可以使用通配符进行模式匹配,如&&,||,>, <等操作符可以应用于[[ ]]中,但不能应用于[ ]中;对整数的关系运算,也可以使用Shell的算术运算符 (()).
关于各种测试操作符只需要在终端man test 即可得到详细描述:
常用的文件测试操作符号 | 说明 |
-f file | 若文件存在且为普通文件则真 |
-d file | 若文件存在且为目录则真 |
-s file | 若文件存在且不为空(文件大小非0)则真 |
-e file | 若文件存在则真,区别于-f |
-r file | 若文件存在且可读则真 |
-w file | 若文件存在且可写则真 |
-x file | 若文件存在且可执行则真 |
-L file | 若文件存在且为链接文件则真 |
f1 -nt f2 | 若文件f1 比文件 f2 新则真 |
f1 -ot f2 | 若文件f1 比文件 f2 旧则真 |
13.字符串测试操作符 返回目录
字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为0,字符串是否为null等
“=”比较两个字符串是否相同,与 “==”等价,如 if [ "$\$a$"="$\$b$" ],其中 $\$a$ 这样的变量最好用双引号括起来。
常用字符串测试操作符 | 说明 |
-z "string" | 若string长度为0,则真 |
-n "string" | 若string长度步为0,则真 |
“string1”= ”string2“ | 若string1等于string2则真,可以使用“==”代替“=” |
“string1”!= ”string2“ | 若string1不等于string2则真 |
注意:测试符“==”,“=”,“!=”好前后均需与测试字符串之间留空格!!!
14.整数二元比较操作符 返回目录
在[ ]中使用的比较符 | 在(())和[[]]中使用的比较符 | 说明 |
-eq | == | 相等 |
-ne | != | 不等 |
-gt | > | 大于 |
-ge | >= | 大于或等于 |
-lt | < | 小于 |
-le | <= | 小于或等于 |
15.逻辑操作符 返回目录
在[]中的使用 | 在[[]]中的使用 | 说明 |
-a | && | 与,两端均为真则真 |
-o | || | 或,两端有一个为真则真 |
! | ! | 非,相反则真 |
16.利用shell知识制作单级及多级菜单 返回目录
17.case结构条件语句 返回目录
语法:
case "字符串变量" in
值1)指令1...
;;
值2)指令2...
;;
*)指令
;;
esca
给字符串显示不同的颜色:
shell脚本中echo可以显示不同颜色的字符,格式如下:
echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"例如:echo -e "\033[41;36m something here \033[0m"其中41的位置代表底色, 36的位置是代表字的颜色1、字背景颜色和文字颜色之间是英文的";"2、文字颜色后面有个m3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
下面利用case来该给定的字符串加上不同的颜色:
#!/bin/bash
#Paint given chars with given color
usage="Usage:chars {black|red|green|yellow|blue|purple|white}"
[[ $# -ne ]] &&{
echo "${usage}"
exit
}
BLACK="\033[1;30m"; RED="\033[1;31m" ;GREEN="\033[1;32m"; YELLOW="\033[1;33m"
BLUE="\033[1;34m"; PRUPLE="\033[1;35m"; WHITE="\033[1;37m"
COLOR_END="\033[0m" chars=$
selected_color=$ case ${selected_color} in
black) res=${BLACK}
;;
red) res=${RED}
;;
green) res=${GREEN}
;;
yellow) res=${YELLOW}
;;
blue) res=${BLUE}
;;
purple) res=${PURPLE}
;;
white) res=${WHITE}
;;
*) echo 'Input color is not supported'
echo ${usage}
exit
;;
esac echo -e "${res}"$"${COLOR_END}"
18. 当型循环和直到型循环 返回目录
while条件语句,条件满足一直执行command
while condition
do
command
done
until语法,条件满足就退出,目前很少用,作为了解
until condition
do
command
done
#!/bin/bash
i=
while (($i>=))
do
echo $i
((i--))
done
使用until实现上面同样的功能:
#!/bin/bash i=
until [ $i -eq ]
do
echo $i
(( i-- ))
done
在实践中经常需要使用while来处理日志文件,下面实际中使用while读取文本的方法:
#
exec <FILE
while read line
do
cmd
done #
cat ${FILE} | while read line
do
cmd
done #
while read line
do
cmd
done<FILE
19.for循环 返回目录
for循环语法结构1:
for var in var_list
do
cmd1
cmd2
...
done
在此结构中, “in var_list”可以省略,省略时,相当于in "$@",例如 for i 就相当于for i in "$@".
for循环语法结构2:
for ((exp1;exp2;exp3)) #与C语言一样
do
cmd1
cmd2
...
done
#!/bin/bash
for i in
do
echo $i
done
下面代码实现同样的功能:
#!/bin/bash
for i in {..}
do
echo $i
done
#!/bin/bash
for i in $(seq -s " " - )
do
echo $i
done
获取当前目录下的所有文件名,打印
#!/bin/bash
for i in $(ls)
do
echo $i
done
打印9*9乘法表:
#!/bin/bash
for a in $( seq )
do
for b in $( seq )
do
if [ $a -ge $b ];then
echo -en "$a x $b = $((a*b)) "
fi
done
echo " "
done echo
Shell高级编程学习笔记(基础篇)的更多相关文章
- Java编程学习笔记(基础篇)
一.Java中的数据类型 1.基本数据类型:四类 八种 byte(1) boolean(1) short(2) char(2) int(4) float(4) long(8) double(8) 2. ...
- Python学习笔记基础篇——总览
Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...
- Unix环境高级编程学习笔记——fcntl
写这篇文正主要是为了介绍下fcntl,并将我自己在学习过程中的一些理解写下来,不一定那么官方,也有错误,希望指正,共同进步- fcntl: 一个修改一打开文件的性质的函数.基本的格式是 int fcn ...
- Python学习笔记——基础篇【第一周】——变量与赋值、用户交互、条件判断、循环控制、数据类型、文本操作
目录 Python第一周笔记 1.学习Python目的 2.Python简史介绍 3.Python3特性 4.Hello World程序 5.变量与赋值 6.用户交互 7.条件判断与缩进 8.循环控制 ...
- Asp.net MVC4高级编程学习笔记-视图学习第一课20171009
首先解释下:本文只是对Asp.net MVC4高级编程这本书学习记录的学习笔记,书本内容感觉挺简单的,但学习容易忘记,因此在边看的同时边作下了笔记,可能其它朋友看的话没有情境和逻辑顺序还请谅解! 一. ...
- java学习笔记-基础篇
Java基础篇 1—12 常识 13 this关键字 14参数传递 16 继承 17 访问权限 28—31异常 1—12 常识 1.文件夹以列表展示,显示扩展名,在地址栏显示全路径 2.javac编译 ...
- Java学习笔记——基础篇
Tips1:eclipse中会经常用到System.out.println方法,可以先输入syso,然后eclipse就会自动联想出这个语句了!! 学习笔记: *包.权限控制 1.包(package) ...
- Python学习笔记——基础篇【第七周】———FTP作业(面向对象编程进阶 & Socket编程基础)
FTP作业 本节内容: 面向对象高级语法部分 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 参考:http://www.cnblogs.com/wupeiqi/ ...
- Javascript高级编程学习笔记(73)—— 表单(1)表单基础
表单 JS最初的一个用途就是帮助服务器分担处理表单的责任 时至今日,虽然web应用以及JS都有了长足的发展,但是表单依然是现在web应用中比较重要的部分. 因为默认的表单控件很丑,所以有时候我们会使用 ...
随机推荐
- MT【230】一道代数不等式
设$a,b,c>0,$满足$a+b+c\le abc$证明:$\dfrac{1}{\sqrt{1+a^2}}+\dfrac{1}{\sqrt{1+b^2}}+\dfrac{1}{\sqrt{1+ ...
- 修复Mysql主从不同步shell
使用第三方工具MySQL Enterprise Monitor,MySQL企业版监控工具.MONyog – MySQL Monior and Advisor,MONyog大家都不陌生,windows下 ...
- luogu2024 食物链 (并查集)
把一个点拆成三个,分别对应它的同类.它的猎物和它的天敌,这样的话(以下的相等都是并查集意义上的): 如果令a,b同类,那么a的猎物不能是b的同类,a的天敌不能是b的同类 如果令a吃b,那么a的同类不能 ...
- 洛谷P5163 WD与地图
只有洛谷的毒瘤才会在毒瘤月赛里出毒瘤题...... 题意:三个操作,删边,改变点权,求点x所在强连通分量内前k大点权之和. 解:狗屎毒瘤数据结构乱堆...... 整体二分套(tarjan+并查集) + ...
- 动态分配内存 new
a=]; ;i<=n;i++) a[i]=]; 感觉比malloc好用. 动态初始化后,值并非全为0,注意!
- ffmpeg处理视频与声音
1.ffmpeg将mp4分解成多张jpg图片 要在游戏中播放视频,引擎竟然不支持.琢磨了一下,干脆将视频图片提取出来,然后用Animation动画类来播放这些图片,这样也能实现播放视频的效果.还是ff ...
- mysql 日志清理
1.查看binlog日志 show binary logs; 2.删除某个日志文件之前的所有日志文件purge binary logs to 'bin.000106'; 3.再看show binary ...
- MyEclipse导入Maven项目以及Maven转化为Dynamic Web Module(转)
MyEclipse导入Maven项目(这个博主写的比较详细)https://blog.csdn.net/w12345_ww/article/details/52094756 Maven转化为Dynam ...
- 比特币VS美元兑换查询网址
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- nginx-1.12.1编译参数详情
一下nginx-1.12.1编译参数详情 #/usr/local/nginx/sbin/nginx -V nginx version: nginx/1.12.1 built by gcc 4.4.7 ...