linux shell编程-bash的奇技淫巧

本文主要讲bash脚本中容易出错和很少用但是用起来有意想不到效果的部分。

循环:

正常的for循环:

for i in a b c 1 2 3; do
    echo "$i"
done

数字序列循环:

for i in `seq 100`; do
    echo "$i"
done

其中的 `seq 100` 也可以换成 {1..100}

{开始..结尾}的这种形式可以表示连续的数列,可以从小到大也可以从大到小,但是可惜不像python的range()那样可以指定间隔量

C语言风格的for循环:

for (( i=1; i<100; i++ )); do
    echo "$i"
done

数学计算

双括号“(())”还可以用于数学计算:

(( a=123+456 ))
echo $a
# 579

在双括号中,变量并不需要用$符号来引用,英文单词天然是变量。

变量:

间接引用:

a=b
b=100
echo ${!a}
# 100

效果等同于 eval echo \$$a

字符串操作

变量值的字符长度:

a="abcdefg"
echo ${#a}
# 7

变量值字符截取:

a="abcdefg"
echo ${a:2}
# cdefg
echo ${a:2:3}
# cde

变量值字符删除:(#为从头部开始匹配,%为从尾部匹配,支持通配符“?*”)

a="abdcdefgh"
echo ${a#*d} # 删除字符串头部匹配“*d”的部分,通配符*代表匹配任意多个字符,一个#号代表通配符“*”保守匹配
# cdefgh
echo ${a##*d} # 两个#号表示贪婪匹配
# efgh
echo ${a%d*} # 同上,两个%时代表贪婪匹配
# abdc
a=b
b="abcdefg"
echo "${!a#abc}"
# defg

可以同时支持间接引用和字符删除

变量赋值安全

用于赋值前检查是否已经定义或赋值。

unset a
unset b
b=""    # a没有定义,b定义了但是空值
echo ${a-789}  # 如果没定义,则表达式采用默认值789
# 789
echo ${a:-789}    # 如果没定义或是空值,则表达式采用默认值789
# 789
echo ${b-789}     # 如果没定义,则表达式采用默认值789,b定义了
#
echo ${b:-789}    # 如果没定义或是空值,则表达式采用默认值789
# 789
echo $a        # 原变量并没有被赋值
#
echo $b        # 原变量并没有被赋值
#
b=123
echo ${b-789}  # 如果变量已经被赋值,则不改变原有值
# 123
unset a
echo ${a=789}    # 如果a没定义,则表达式采用默认值,并给a赋值
# 789
echo $a
# 789        # a已经被赋值了
a=""
echo ${a=789}
#
echo ${a:=789}    # 加冒号:的作用和之前一样
# 789
echo $a
# 789

前面讲了用“-”和“=”的,还有一种用“+”的,用于当变量已经被赋值的情况下采用默认值,举一反三,不赘述了。

位置变量

$0是文件名,$#代表参数个数,$1,$2等等表示执行该脚本或函数后面跟的位置参数,$1代表第一个参数,依次类推,需要注意的是,第9个以后的参数应该这么表示:

${10}

这表示第10个参数,必须用花括号括起来,否则就变成第1个变量后面加个字符“0”了。因为这个有的人以为第9个以后的位置变量就不可用了,是错的。

[email protected]和$*都表示所有的变量,但是区别是前者将每个作为一个字符串,是多个字符串的结合,而后者将所有变量组合成一个字符串,用空格分隔。

这样不同会在for循环里面造成使用的区别,在for循环里面,如果加上引号 for i in "[email protected]" 和 for i in "$*" 是不同的,前者还是会依次把参数代入循环,而后者会吧所有参数作为字符串一次性代入:

echo ‘
for i in "[email protected]"; do
    echo "$i"
done
for i in "$*"; do
    echo "$i"
done
‘ > myscript.sh
chmod 755 myscript.sh
./myscript.sh abc 123 def

结果是:

abc
123
def
abc 123 def

那么[email protected]加引号和不加引号有区别么?

大部分情况下结果看起来是一样的,但会在某些情况下造成麻烦,因为for循环会用换行符“\n”和空格来拆分变量,所以如果调用脚本所带的参数中带有空格或者换行符,不加引号的时候会把这个参数拆开了依次代入,而加了引号就可以避免这种情况。

echo ‘
for i in "[email protected]"; do
    echo "$i"
done
for i in [email protected] ; do
    echo "$i"
done
‘ > myscript.sh
chmod 755 myscript.sh
./myscript.sh abc "123 def"

结果是:

abc
123 def
abc
123
def

for循环使用数组

将数组的值依次代入循环,可以用${arr[@}和${arr[*]}这两种方法,区别和加引号的区别同上面位置参数的使用相同。

字符串匹配

shell的字符串匹配通常是这样的:

[ "abc" = "abc" ]
echo $?
# 0

若字符串相同则返回0,否则返回1。除了全匹配外,通过双方括号“[[]]”还可以用正则表达式匹配

[[ "abc234def" =~ ^abc[0-9]{3}[a-z]+$ ]]
echo $?
# 0

注意这里正则表达式不能用引号括起来,而且只支持基本的正则,不支持如“\b \S”之类的扩展。

原文地址:http://www.cnblogs.com/foxgab/p/6901782.html

如果觉得本文对您有帮助,请扫描后面的二维码给予捐赠,您的支持是作者继续写出更好文章的动力!

时间: 2024-10-28 09:52:28

linux shell编程-bash的奇技淫巧的相关文章

Linux Shell编程之二选择结构

Shell编程学习之二 一.bash的条件测试 测试方法或者说测试书写: test EXPR [ EXPR ] [[ EXPR ]] 例如:测试变量 User_Name 的之是否为root test $User_Name="root" [ $User_Name == "root" ] [[ $User_Name == "root" ] 根据比较时操作数的类型,测试类型分为: 测试类型 运算符 运算符所代表的意义 示例 整形测试 -gt -lt -

Linux Shell编程之五字符串的处理

shell编程之字符串处理 在 shell 中,由于是一种弱类型的语言,在没有事先申明变量类型的情况下,所有的变量都是字符串.所以对字符串的处理就显得相当重要了. 下面介绍常见的对字符串处理的操作. 一.字符串切片 ${string_var:offest:length},类似于数组元素的提取. # 这里的string_var是一个变量,offest 是字符串的开始偏移量,length是切去字符串的长度 var=dhcpd:x:177:177:DHCP server:/:/sbin/nologin

关于linux shell编程,alias rm=&#39;cp [email&#160;protected] ~/backup; rm [email&#160;protected]&#39;

书上的这个例子需要在ubuntu的低版本的系统才支持,现在基本上都不支持了,想实现也很简单自己写一个脚本先备份再删除. alias也只是做了一次替换alias rm='cp [email protected] ~/backup; rm [email protected]' rm text.txt被转换成了cp  [email protected] ~/backup; rm [email protected] text.txt即cp  ~/backup; rm  text.txt可以看到text.

Linux Shell 编程实战技巧

目前,越来越多的企业应用会部署在 Linux 系统上的,而 Linux Shell 脚本可以极大地帮助我们完成这些应用的运维任务.这使得 Linux Shell 开发技能成为开发人员的一项重要的.有竞争力的技能.本文就笔者的实际开发经验,以 Korn Shell 为例分享了脚本开发中的常见问题及相关技巧. 避免定时任务脚本的常见问题 很多脚本在实际使用的时候往往是以定时任务的方式运行,而非手工运行.但是实现同样功能的脚本在这两种运行方式下可能遇到的问题不尽相同. 以定时任务方式运行的脚本往往会遇

京峰Linux Shell编程从入门到精通

课程介绍:Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令并把它送入内核去执行. -------------------课程目录------------------- <Shell编程从入门到精通> ├1.linux下shell编程基础入门_(new).mp4├2.Shell编程之变量及LAMP导航菜单编写_(new).mp4├3.Shell编程之IF条件语句各种案例演练_(new).mp4├4.使用if条件语句编写MySQL备份脚本_(new).mp4

linux shell编程

1.什么是shell 2. 还是hello world程序 3. shell中的变量 3.1 系统变量 3.2 用户定义变量 3.2.1 用户定义变量规则 3.2.3 shell如何使用变量 3.2.3 全局变量 vs 局部变量 4. shell编程中的控制结构 4.1 条件判定 4.1.1 简单条件判定 4.1.2 组合判定 4.2  if - else 4.3 for 4.4 while 4.5 case 5. shell中的函数 5.1 函数声明和定义 5.2 函数调用 6. shell脚

Linux Shell编程入门

从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作.在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用.深入地了解和熟练地掌握Shell编程,是每一个Linux用户的必修 功课之一. Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh).Bourne

“Linux Shell编程”视频学习笔记

一.Linux Shell基础编程 视频1 1.1.查看你系统shell信息 $ cat /etc/shell 命令可以获取Linux系统里面有多少种shell程序 $ echo $SHELL 命令可以查看当前你所使用的shell是哪一个 1.2.查看文件信息,ls $ ls -l 查看文件信息:文件类型.文件权限.文件硬链接数.文件所属用户.文件所属组.文件大小.文件最近修改时间.文件名 1.3.改变文件权限,chmod 只有root用户或者文件的所有者能改变文件的权限 例子:$ chmod

Linux Shell编程基础

在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐藏  -R 显示文件夹内的内容  -c 按照最后一次修改时间排序  -t 按照修改时间排序输出 echo 显示  -n 不换行 touch  创建一个文件,或者修改文件的访问时间和修改时间 touch -a file 只更改访问时间 -m之更改修改实际那 -t指定特定时间 cp  复制文件 -a 保