eval命令

eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描

示例1:
[root@sea ~]#: cmd=whoami
[root@sea ~]#: echo $cmd
whoami   #无法将whoami 执行

[root@sea ~]#: eval $cmd
root  #可以将whoami 转换为命令执行

示例2:

[root@sea ~]#: n=5
[root@sea ~]#: echo {0..$n}
{0..5} #无法二次执行
[root@sea ~]#: eval echo {0..$n}
0 1 2 3 4 5 #置换后再次执行

变量替换

变量替换 说明
${var# 匹配规则} 头开始匹配(删除),最短的数据删除
${var##匹配规则} 从头开始匹配(删除),最长的数据删除 [贪婪匹配]
${var % 匹配规则 } 从尾开始匹配(删除),最短的数据删除
${var%% 匹配规则} 从尾开始匹配(删除),最长的数据删除 [贪婪匹配]
${var / 旧字符串/新字符串} 替换变量内的旧字符串为新字符串,只替换第一个
${var // 旧字符串/新字符串} 替换变量内的旧字符串为新字符串,替换全部
${var/#旧字符串/新字符串} 查找var所表示的字符串中,行首被旧字符串所匹配到的字符串,以新字符串替换
${var/%旧字符串/新字符串} 查找var所表示的字符串中,行尾被旧字符串所匹配到的字符串,以新字符串替换
i="www.hanjy.cn"&& echo ${i#*.}                
hanjy.cn  		#头开始匹配(删除),最短的数据删除  

i="www.hanjy.cn"&& echo ${i##*.} 
cn  			#从头开始匹配(删除),最长的数据删除



i="www.hanjy.cn"&& echo ${i%.*}       
www.hanjy    		#从尾开始匹配(删除),最短的数据删除

i="www.hanjy.cn"&& echo ${i%%.*} 
www  			# 从尾开始匹配(删除),最长的数据删除



i="www.hanjy.cn"&& echo ${i/w/W}     
Www.hanjy.cn   		#替换变量内的旧字符串为新字符串,只替换第一个

i="www.hanjy.cn"&& echo ${i//w/W} 
WWW.hanjy.cn   		#替换变量内的旧字符串为新字符串,替换全部



i="www.www.hanjy.cn"&& echo ${i/#www/WWW}  
WWW.www.hanjy.cn

i="www.hanjy.cn.cn"&& echo ${i/%cn/CN}    
www.hanjy.cn.CN

变量赋值

image-1656222732798

变量赋值 说明
${var=value} 若var未设定,将值赋给变量var (空值或者非空值不处理)
${var:=value} 若未赋值或未设定的var,将值value值赋给它 (非空值不处理)
${var-value} 若未设定的var,将值value值赋给它,但value值不存储到var对应的地址空间 (非空值或者空值时不作处理)
${var:-value} 若未赋值或未设定的var,将值value值赋给它,但value值不存储到var对应的地址空间 (非空值时不作处理)
${var+value} 若var为空值或者非空值,重设其值 (没设定时不处理)
${var:+value} 若var为非空值,重设其值 (没设定或空值时不处理 )
${var?value} 若var未设定,显示系统错误信息 ${var:?value} 会将value输出到标准错误 STDERR (空值或者非空值不处理)
${var:?value} 若var未设定或者空值,显示系统错误信息 ${var:?value} 会将value输出到标准错误STDERR (非空值不处理)
```shell 示例

#var={str-value} 当str不为空字符串时 将值赋给变量var var={i-hello}&&echo var,i
hello,

#当str为空字符串时 变量var亦为空
i=""&&var=${i-hello}&&echo var,i
,

#当str为有值时 变量var=i i="world"&&var={i-hello}&&echo var,i
world,world

#${var+value} 对已赋值的var,重设其值
i=“www.hanjy.cn”&& echo ${i+hello}
hello

#{var?value}和{var:?value} 对未赋值的var,显示系统错误信息
i=“www.hanjy.cn”&& echo ${tt:?}
-bash: tt: 参数为空或未设置
i=“www.hanjy.cn”&& echo ${tt?}
-bash: tt: 参数为空或未设置

i=“www.hanjy.cn”&& echo ${tt?error}
-bash: tt: error
i=“www.hanjy.cn”&& echo ${tt:?error}
-bash: tt: error

${var:=value} 对未赋值的var,将值value值赋给它 已赋值的输出结果
i=“www.hanjy.cn”&& echo ${ii:=hello}
hello
i=“www.hanjy.cn”&& echo ${i:=hello}
www.hanjy.cn

#${var:-value} 对未赋值的var,将值value值赋给它,但value值不存储到var对应的地址空间
i=“www.hanjy.cn”&& echo ${ii:-hello}
hello



### 字符串切片

`${#var}`:返回字符串变量var的长度
```shell|示例
 i=hello && echo ${#i}
5

${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到${#var}-1之间(bash4.2后,允许为负值)

 [root@sea ~]#: i=hello && echo ${i:1}
ello

${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

i=hello && echo ${i:1:3}
ell

${var: -length}:取字符串的最右侧几个字符 注意:冒号后必须有一空白字符

 i=hello && echo ${i: -3}
llo

${var:offset: -length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容

i="hello world"&& echo ${i:2 : -3} 
llo wo  #左侧跳过两个字符(he) 取到最右侧前的3个字符(rld)前的内容

${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容 注意:-length前空格

i="hello world"&& echo ${i: -5:2}  
wo  #先从后往前取5个字符(word) 在从前往后取2个字符

字符串查找并删除

查找删除 说明
${var/pattern} 删除var表示的字符串中第一次被pattern匹配到的字符串
${var/pattern} 删除var表示的字符串中第一次被pattern匹配到的字符串
${var//pattern} 删除var表示的字符串中所有被pattern匹配到的字符串
${var/#pattern} 删除var表示的字符串中所有以pattern为行首匹配到的字符串
${var/%pattern} 删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
#${var/pattern}:删除var表示的字符串中第一次被pattern匹配到的字符串
i="www.hanjy.cn"&& echo ${i/www.}          
hanjy.cn

#${var//pattern}:删除var表示的字符串中所有被pattern匹配到的字符串
i="www.www.hanjy.cn"&& echo ${i//www. }
hanjy.cn

#${var/#pattern}:删除var表示的字符串中所有以pattern为行首匹配到的字符串
i="www.www.hanjy.cn"&& echo ${i/#www.}  
www.hanjy.cn

#${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
i="www.hanjy.cn.cn"&& echo ${i/%.cn} 
www.hanjy.cn

字符大小写转换

大小写转换 说明
${var^^} 把var中的所有小写字母转换为大写
${var,,} 把var中的所有大写字母转换为小写
#${var^^}:把var中的所有小写字母转换为大写
i="www.hanjy.cn"&& echo ${i^^}   
WWW.HANJY.CN

#${var,,}:把var中的所有大写字母转换为小写
i="WWW.HANJY.CN"&& echo ${i,,}               
www.hanjy.cn

间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用
var的值是var2,而var2又是变量名,var2的值为value,间接变量引用是指通过var1获得变量值value的行为
例如:
var1=var2
var2=value

#bash Shell提供了两种格式实现间接变量引用
#方式1: eval var=\$$var1;
 var1=var2;var2=value;eval var=\$$var1;echo $var
         value
#方式2: var=${!var1}
var1=var2;var2=value;var=${!var1};echo $var
value

环境变量文件

在shell的命令行下直接定义的变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。
如果只是临时用一下,可以直接在shell下用export命令设定环境变量;如果希望此环境变量每次开机或打开Shell时自动设定而无须每次都手动设定,那么需要将export命令写入环境变量配置文件中。Linux下,环境变量被分别保存在多个环境变量文件中,当你进入系统的时候,这些环境变量文件是按照下面的顺序读取的:

(1)/etc/environment文件

设置整个系统的环境信息,在系统启动时被读取,与登录用户无关。

(2)/etc/profile文件

为系统的每个用户设置环境信息,任何用户每次登录时执行该文件。

(3)/etc/bashrc文件

是针对所有用户的bash Shell初始化文件,任何用户每次登录或打开新的Shell时执行该文件。在执行完/etc/profile 内容之后,如果用户的Shell运行的是bash shell,那么接着就会执行此文件。

(4) ~/.bashrc文件

该文件包含专用于你的bash shell的bash信息,在用户每次登录时或打开新的Shell时执行该文件。

(5)~/.bash_profile文件

每个用户都可使用该文件保存专用于自己使用的shell信息,在用户每次登录时执行该文件。

注意:在不同Linux中,这个文件的名字不同,可能的名字有~/.bash_profile、~/.bash_login、~/.profile其中的一种或者几种。如果都存在的话,执行的顺序为~/.bash_profile、~/.bash_login、~/.profile。

(6) ~/.bash_logout文件

在用户每次退出登录的时候执行该文件。

/etc/environment文件、/etc/profile文件、/etc/bashrc文件是针对所有用户的。

/.bashrc文件、/.bash_profile文件、~/bash_logout文件在每个用户的主目录(HOME目录)下都存在,是针对特定用户的(哪个用户的主目录就针对哪个用户)。

例如,编辑/etc/profile文件,添加CLASSPATH变量:

      vim /etc/profile
			#添加内容如下:
     export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

注:修改文件后要想马上生效还要运行#source /etc/profile,不然只能在下次重进此用户时生效。

重要的环境变量

(1) BASH 和SHELL

   BASH记录了bash Shell的路径,通常为/bin/bash,内部变量SHELL就是通过BASH的值确定当前Shell的类型。
   SHELL变量保存默认的Shell值,默认的值为/bin/bash,表示当前的Shell是bash Shell。如果有必要用另一个Shell,则需要重置SHELL变量值。
  下面显示了BASH和SHELL变量的值,由于Red Hat使用的是bash Shell,因而两个变量的值都是/bin/bash。
[root@localhost  ~]# echo $BASH

/bin/bash

[root@localhost  ~]# echo $SHELL

/bin/bash

(2) BASH_VERSION和BASH_VERSINFO[n]

 BASH_VERSION表示安装在系统上的Bash版本号。

 BASH_VERSINFO[n]是一个含有6个元素的数组, 它包含了所安装的Bash的版本信息,与下$BASH_VERSION很相像。

(3) SHLVL

 SHLVL记录了bash Shell嵌套的层次,一般来说,我们启动第一个Shell时,SHLVL为1,如果在这个Shell中执行脚本,脚本中的SHLVL为2,如果脚本再执行子脚本,子脚本中的SHLVL就变为3。

(4)HOSTTYPE、MACHTYPE、OSTYPE

 HOSTTYPE和MACHTYPE一样,都用于记录系统的硬件架构。

 OSTYPE记录了操作系统类型。

(5) PATH

  PATH是Linux中一个极为重要的环境变量,它用于帮助Shell找到用户所输入的命令。用户所输入的每个命令实际是是一个源代码文件,计算机执行这个文件里的代码以实现这个命令的功能,这些源代码文件称为可执行文件。可执行文件存在于各种各样的目录下,一些可执行文件放置在Linux系统标准目录中,还有一些可执行文件可能是用户写得的序或Shell脚本文件,他们放置在用户目录中。PATH就记录了一系列的目录列表,Shell为每个输入命令搜索PATH中的目录列表。
 下面显示了PATH环境变量的内容,可以看到,PATH中包含了多个目录的路径,它们之间用冒号分割,都是以bin或sbin的文件夹结尾,bin或sbin是Linux中存放可执行文件的文件夹。任何在PATH的可执行文件都可以在Linux系统的任何目录中直接执行。
[root@hanjy  ~]# echo $PATH

/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

如果需要在PATH中添加新目录,可以使用以下的命令:

export  PATH="/new directory":$PATH

命令中的new directory就是新加上去的目录,后面用冒号加$PATH,表示new directory加上旧的PATH变量值,得到新的PATH变量值。

(6)HOME

 HOME记录当前用户的根目录。root用户的根目录时/root,其他用户的根目录都存放在/home目录下,通常以用户名命名。

(7)PWD和OLDPWD

 PWD记录当前的目录路径,当利用cd命令改变当前目录时,系统自动更新PWD的值,OLDPWD记录旧的工作目录,即用户所处的前一个目录。

(8)USER、UID、LOGNAME

 USER、UID、LOGNAME是保存用户信息的环境变量,USER表示当前登录用户的账户,UID表示当前登录用户的ID、LOGNAME表示当前登录用户的登录名。

(9)PPID

 PPID是创建当前进程的进程号,即当前进程的父进程。

(10)PS1、PS2、PS3、PS4

 PS1:主提示符,在命令行中可以见到它。默认显示“[\u@\h\W]$”。

 PS2:第二提示符,当你需要额外输入的时候,你就会看到他。默认显示“>”。当命令比较长,需要多行输入时,在当行命令的末尾输入字符“\”,会出现下一行命令输入行,这时的提示符为第二提示符。

 PS3:第三提示符,它在select循环中显示。默认显示“#?”。

 PS4:第四提示符,当使用set -x选项来设置Shell的执行方式时,这个提示符会出现在每行输出的开头。默认显示“+”。

 PS1、PS2、PS3、PS4是在用户根目录下的.bash_profile中定义的。可以更改这些提示符的显示样式。

下面列出了提示符中特殊字符的意义:

\d:代表日期,格式为weekday month date,例如:“Mon Aug 1”

\H:完整的主机名称。例如:我的机器名称为:fc4.linux,则这个名称就是fc4.linux

\h:仅取主机的第一个名字,如上例,则为fc4,.linux则被省略

\t:显示时间为24小时格式,如:HH:MM:SS

\T:显示时间为12小时格式

\A:显示时间为24小时格式:HH:MM

\u:当前用户的账号名称

\v:BASH的版本信息

\w:完整的工作目录名称。家目录会以~代替

\W:利用basename取得工作目录名称,所以只会列出最后一个目录

#:下达的第几个命令

$:提示字符,如果是root时,提示符为:# ,普通用户则为:$

(11)IFS

 IFS用于指定Shell域分隔符,默认为空格。这个变量用来觉得Bash在解释字符串时如何识别域,或者单词边界。
data="windows, linux,MAC,Android"
#我们可以使用IFS读取变量中的每一个条目。
IFS=, 
#IFS现在被设置为,
for i in $data;
do
echo DATA: $i
done
输出如下:
DATA: windows
DATA: linux
DATA: ,MAC
DATA: Android
 注意,脚本内部修改IFS只在脚本内部起作用,当前Shell修改IFS只在当前Shell及子Shell中有效。

(12)MAIL

 MAIL表示当前用户的邮件存放目录。

(13)HOSTNAME

 HOSTNAME记录了主机名,Linux主机名是网络配置时必须要设置的参数,我们一般在/etc/sysconfig/network文件中设置主机名。/etc/hosts文件用于设定IP地址和主机名之间的对应关系,以利于快速从主机名查找到IP地址。

(14) LANG

 系统字符集。

(15) SECONDS

 SECONDS记录脚本从开始执行到结束所耗费的时间,以秒为单位。

(16)TMOUT

 TMOUT变量用于设置Shell的过期时间,当TMOUT不为0时,Shell在TMOUT秒后将自动注销。TMOUT放在脚本中,可以规定脚本的执行时间。

(17) REPLY

 REPLY变量与read和select命令有关。



 read命令用于读取标准输入的变量值。在此,可以将read命令简单理解为接受用户的键盘输入,交互式Shell脚本经常用到read命令。read命令其一般格式为:

read variable

 variable是变量名,read将读到的标准输入存储到variable变量中,read命令也可以不带任何变量名,此时,read就将读到的标准输入存储到REPLY变量中。新建脚本readreply.sh,内容如下:

readreply.sh脚本

#!/bin/bash

 

echo  -n "What is your name?"

read

echo  "Your name is $REPLY"

 

echo  -n "What is the name of your father?"

read  fname

echo  "Your father's name is $fname"

readreply.sh脚本的执行结果如下:

[root@bogon  ~]# . readreply.sh

What  is your name?lcb

Your  name is lcb

What  is the name of your father?lqq

Your  father's name is lqq

bash Shell的select命令源自于Korn Shell,是一种建立菜单的工具,它提供一组字符串供用户选择,用户不必完整地输入字符串,只需输入相应的序号进行选择,select命令的格式如下:

select  variable in list

do

  Shell命令1

  Shell命令2

  Shell命令3

  ......

break

done

上述select命令格式中的list是字符串列表,select自动将list形成有编号的菜单,用户输入序号以后,将该序号所对应的list中的字符串赋给variable变量,而序号值则保存到REPLY变量中。select命令的dobreak语句段中可以添加Shell命令,对variable或REPLY进行调用。

下例阐述select命令的用法,以及REPLY变量在select命令中的含义。新建一个名为selectreply.sh的脚本,内容如下:

#!/bin/bash

 

echo  "Pls. choose your profession?"

select  var in "Worker" "Doctor" "Teacher"  "Student" "Other"

do

  echo "The \$REPLY is $REPLY."

  echo "Your profession is $var."

break

done                                                                 

执行结果如下:

[root@bogon  ~]# . selectreply.sh                                                   

Pls.  choose your profession?                                                       

1)  Worker                                                                          

2)  Doctor                                                                          

3)  Teacher                                                                         

4)  Student                                                                         

5)  Other                                                                          

#?  4

The  $REPLY is 4.

Your  proffession is Student.

在上述selectreply.sh脚本的执行结果中,我们注意到输入select命令后,Shell提示符变为"#?",该提示符由Shell提示符变量PS3进行设置,“#?”是其默认值,可以重新设置。

****本文部分内用引用于https://blog.51cto.com/pengge666/1901137