Shell初体验(二) —— Shell语法之变量、注释和字符串

2023-07-16  本文已影响0人  刀客传奇

版本记录

版本号 时间
V1.0 2023.07.17 星期一

前言

Shell脚本相信大家都用过,Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 脚本(shell script),是一种为 shell 编写的脚本程序。大家平时说的和用到的都是指的是shell脚本编程,不是指开发shell自身。这个模块我们就一起来看下shell脚本编程。感兴趣的可以看下面几篇文章。
Shell初体验(一) —— Shell入门(一)

变量

1. 变量的命名

一个命名的简单示例

name="dodo"

变量的命名要遵循下面规则

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线 _
  • 不能使用标点符号
  • 不能使用bash里的关键字(可用help命令查看保留关键字)

2. 变量类型

运行shell时,会同时存在三种变量:

3. 只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
先看一个简单的示例

#!/bin/bash

host="www.xxx.com"
readonly host
host="www.aaa.com"

下面我们就执行这个脚本,就会发现报错了

./test.sh: line 5: host: readonly variable

报的是第5行错误,提示信息是host是只读变量

4. 删除变量

使用unset命令可以删除变量,语法:

unset variable_name

下面是一个简单示例

#!/bin/bash

host="www.xxx.com"
unset host
echo $host

我们执行这个脚本./test.sh就会发现没有任何输出,因为使用unset删除了变量。

5. 变量的使用

变量的使用需要在变量前加上美元符号$,下面就是一个简单示例:

#!/bin/bash

host="www.xxx.com"
echo ${host}
或
echo $host

执行脚本,都会有下面输出:

www.xxx.com

需要说明的是:{}这个大括号是非必须的,但是加上是一个好习惯。加花括号是为了帮助解释器识别变量的边界。

可以看下面这个示例

#!/bin/bash

host="www.xxx.com"
echo "This is a $hostname"

这里host变量没有用大括号,解析器就会把hostname当成一个变量,所以就会有下面的输出

This is a 

下面我们加上大括号

#!/bin/bash

host="www.xxx.com"
echo "This is a ${host}name"

接着运行下脚本

This is a www.xxx.comname

可以看见,host被识别为一个已定义变量,可以正常的输出了。

注释

以 # 开头的行就是注释,会被解释器忽略。
Shell脚本的注释可以使用command + /,想去掉注释同理。

字符串

1. 字符串的表示

字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号

string='abcdefg'

单引号字符串的限制:

双引号

#!/bin/bash

string="abcdefg"
str="\"$string\"是前7个字母"
echo $str
//输出
"abcdefg"是前7个字母

双引号的优点:

2. 字符串的长度

语法:字符串的长度使用${#string},string是字符串变量名。

看下面一个示例

#!/bin/bash

string="abcdefg"
echo ${#string}
//输出
7

变量为字符串时,${#string} 等价于 ${#string[0]}

#!/bin/bash

string="abcdefg"
echo ${#string[0]}
//输出
7

3. 子字符串

可以通过下面语法获取字符串中的子字符串

语法:${string:index:length},这里string是字符串变量,index是下角标,length是要截取的字符串长度。

可以通过下面示例获取子字符串

#!/bin/bash

string="abcdefg"
echo ${string:0:3}
//输出
abc

可以看见,输出从索引0开始的长度为3的子字符串

4. 字符串的拼接

字符串的拼接,可以使用单引号,也可以使用双引号。
双引号拼接

#!/bin/bash

name="liLei"
greeting="hello, nice to meet you, ${name}!"
echo $greeting
#!/bin/bash

name="liLei"
greeting="hello, nice to meet you, "$name"!"
echo $greeting

上面俩种拼接方式的输出都是一样的

hello, nice to meet you, liLei!

单引号拼接

#!/bin/bash

name="liLei"
greeting='hello, nice to meet you, '$name'!'
echo $greeting
hello, nice to meet you, liLei!

再看下面这种形式

#!/bin/bash

name="liLei"
greeting='hello, nice to meet you, ${name}!'
echo $greeting
hello, nice to meet you, ${name}!

后面这种样式,可以说明单引号里这么引用变量是无效的,会被当成字符串,原样输出。

5. 查找字符中字符的位置

expr index方法

语法:expr index string1 string2,在string1中找到string2的位置。

我们看下下面简单示例:

#!/bin/bash

string="hello world"
result=`expr index "$string" ll`
echo $result

我们运行脚本会发现报错了

expr: syntax error

这个提示很好理解,提示意思就是expr有语法错误,但是仔细检查了好几遍并没发现有什么错误。接着我们在终端运行下面命令。

man expr

可以看见一个命令的使用说明,往下拉可以看见下面提示:

STANDARDS
     The expr utility conforms to IEEE Std 1003.1-2008 (“POSIX.1”).

     The extended arithmetic range and overflow checks do not conflict with POSIX's requirement that arithmetic be done using signed longs, since they
     only make a difference to the result in cases where using signed longs would give undefined behavior.

     According to the POSIX standard, the use of string arguments length, substr, index, or match produces undefined results.  In this version of expr,
     these arguments are treated just as their respective string values.

HISTORY
     An expr utility first appeared in the Programmer's Workbench (PWB/UNIX).  A public domain version of expr written by Pace Willisson <pace@blitz.com>
     appeared in 386BSD-0.1.

意思就是

根据POSIX标准,使用字符串参数length,substr,index或match会产生不确定的结果。
在此版本的expr中,这些参数被视为它们各自的字符串值。也就是没有这些方法。

继续查了下资料

bash: "expr index string1 string2" gives "syntax error"
In a bash script, I was trying to use the command
 
expr index string1 string2

to find the position of string2 in string1, but this does not work on OS X while it works ok on several Linux machines. Reading the man page, I realized expr does something quite different on OS X than on Linux. 

https://discussions.apple.com/thread/923299
The expr in Linux is generally GNU expr. Mac OS X uses BSD expr which does not have the index command.

那说明这个index方法在Mac OS上已经不能用了。大家有别的系统的可以在自己机器上尝试下,我就不给大家试了。

awk

我们可以使用awk去匹配,看下面这个示例

#!/bin/bash

echo "This is a test" | awk '{printf("%d\n", match($0, "is"))}'

这个示例很清晰,就是找字符串"This is a test""is"的索引,这里可以看见"is"出现了2次,我们运行下,如下输出:

3

可以看见是找到了,并且索引为3,也就是找到的是"This"中的"is",是符合预期的,且索引是从1开始的。所以:

  • 这里是求子字符串所在的第一个符合条件的索引
  • 找到则返回指定的正值,找不到符合的则返回0
  • 如果可以找到,那索引是从1开始的

后记

本文讲述了Shell中的变量和字符串,感兴趣的给个赞或者关注,有问题的话,欢迎批评留言指正。

上一篇下一篇

猜你喜欢

热点阅读