用shell读取一个配置文件,文件里面如果设置两个变量,又如何用shell读取这两个变量

用shell读取一个配置文件,文件里面如果设置两个变量,又如何用shell读取这两个变量,第1张

你不用读取这个配置文件, 直接加载文件即可。

如在param中定义了

A=1

B=3

你需要在myshell中获取param文件中的变量, 可以这样写

/PATH/param (或者source /PATH/param)

echo $A $B

1 shell变量基础

shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。shell变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell中可用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。任何其他的字符都标志着变量名的终止。名字是大小写敏感的。给变量赋值时,等号周围不能有任何空白符。为了给变量赋空值,可以在等号后跟一个换行符。用set命令可以查看所有的变量,unset var命令可以清除变量var,var相当于没有定义过。readonly var可以把var变为只读变量,定义之后不能对var进行任何更改。对shell变量的引用方式很多,用这些方式可以方便的获取shell变量的值,变量值的长度,变量的一个字串,变量被部分替换后的值等等。shell变量常见引用方式如下:

2 环境变量

环境变量的定义方法如下:

var=value

export var

shell在初始化的时候会在执行profile等初始化脚本,脚本中定义了一些环境变量,这些变量会在创建子进程时传递给子进程。

用env命令可以查看当前的环境变量。常用的系统环境变量如下:

_(下划线) 上一条命令的最后一个参数

BASH 展开为调用bash实例时使用的全路径名

CDPATH cd命令的搜索路径。它是以冒号分隔的目录列表,shell通过它来搜索cd命令指定的目标目录。例如:~:/usr

EDITOR 内置编辑器emacs、gmacs或vi的路径名

ENV 每一个新的bash shell(包括脚本)启动时执行的环境文件。通常赋予这个变量的文件名是bashrc。

EUID 展开为在shell启动时被初始化的当前用户的有效ID

GROUPS 当前用户所属的组

HISTFILE 指定保存命令行历史的文件。默认值是~/bash_history。如果被复位,交互式shell退出时将不保存命令行历史

HISTSIZE 记录在命令行历史文件中的命令数。默认是500

HOME 主目录。未指定目录时,cd命令将转向该目录

IFS 内部字段分隔符,一般是空格符、制表符和换行符,用于由命令替换,循环结构中的表和读取的输入产生的词的字段划分

LANG 用来为没有以LC_开头的变量明确选取的种类确定locale类

OLDPWD 前一个工作目录

PATH 命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令,一个普通值为 /usr/gnu/bin:/usr/local/bin:/usr/ucb:/usr/bin

PPID 父进程的进程ID

PS1 主提示符串,默认值是$

PS2 次提示符串,默认值是>

PS3 与select命令一起使用的选择提示符串,默认值是#

PS4 当开启追踪时使用的调试提示符串,默认值是+。追踪可以用set –x开启

PWD 当前工作目录。由cd设置

RANDOM 每次引用该变量,就产生一个随机整数。随机数序列可以通过给RANDOM赋值来初始化。如果RANDOM被复位,即使随后再设置,它也将失去特定的属性

REPLY 当没有给read提供参数时设置

SHELL 当调用shell时,它扫描环境变量以寻找该名字。shell给PATH、PS1、PS2、MAILCHECK和IFS设置默认值。HOME和MAIL由login(1)设置

SHELLOPTS 包含一列开启的shell选项,比如braceexpand、hashall、monitor等

UID 展开为当前用户的用户ID,在shell启动时初始化

3 数值变量

shell中默认把变量值当作字符串,例如:

age=22

age=${age}+1

echo ${age}

输出结果为22+1,而不是23,因为shell将其解释为字符串,而不是数学运算。

可以用let命令使其进行数学运算,例如:

let age=${age}+1

也可以用declare把变量定义为整型。例如:

declare -i age=22

这里就用 -i 选项把age定义为整型的了。此后每次运算,都把age的右值识别为算术表达式或数字。

4 数组

在shell中可以使用数组,例如:

array[0]=0

array[1]=1

array[2]=2

则array就是一个数组,也可以这样给数组初始化:

array=(0 1 2) // 元素之间以空格分隔

可以通过 ${array[$i]}来访问array中某个元素,${array[]} 的返回值即数组的所有元素组成的串,${#array[]} 的返回值即数组的元素个数,${array[]:0:2} 返回第一个和第二个元素组成的串。0表示开始的位置,2表示要返回的元素个数,开始位置可以为0-2(0减去2)之类的,表示从倒数第二个元素开始。

下面写个稍微复杂点的例子:

1 #!/bin/bash

2 for ((i=0; i<100; i++))

3 do

4 array[$i]=$i

5 done

6 for ((i=0; i<100; i++))

7 do

8 echo ${array[$i]}

9 done

如果要使用二维数组甚至三维数组该怎么实现呢,那就需要用eval命令来模拟数组的功能了。

eval命令的作用是扫描命令两次再执行,如果不使用eval,只扫描一次,然后执行。看个例子:

root@suse:~$ name=Barry

root@suse:~$ $name=hello

Barry=hello: command not found

为什么第二句给Barry变量赋值会出错呢?从报错信息可以发现shell并没有识别这是个赋值语句,而是把Barry=hello当作一个命令来执行,当然会报错。为什么不能识别这是赋值语句呢?第一次扫描时,因为扫描到$符号,所以不能把这句当作赋值语句,赋值语句的左边总是一个变量名,而不应该是$开头的。所以第一次扫描仅仅识别了$name变量,并做了替换,而并没有认识到赋值语句。

如果使用eval $name=hello呢?

root@suse:~$ name=Barry

root@suse:~$ $name=hello

Barry=hello: command not found

root@suse:~$ eval $name=hello

root@suse:~$ echo $Barry

hello

可见使用了eval之后,对 $name=hello 第一次扫描替换了$name,没有识别赋值语句,第二次扫描识别是赋值语句,然后执行。现在大约可以想到怎样用eval实现二维数组了。

下面实现的二维数组每一行代表一个人的信息记录,包括姓名,年龄。

1 for ((i=0; i<2; i++))

2 do

3 for ((j=0; j<2; j++))

4 do

5 read man$i$j

6 done

7 done

8 echo "next print:"

9 for ((i=0; i<2; i++))

10 do

11 for ((j=0; j<2; j++))

12 do

13 eval echo -n "\$man$i$j:"

14 done

15 printf "\n"

16 done

5 特殊变量

$0:当前脚本的文件名

$num:num为从1开始的数字,$1是第一个参数,$2是第二个参数,${10}是第十个参数

$#:传入脚本的参数的个数

$:所有的位置参数(作为单个字符串)

$@:所有的位置参数(每个都作为独立的字符串)。

$:当前shell进程中,上一个命令的返回值,如果上一个命令成功执行则$的值为0,否则为其他非零值,常用做if语句条件

$$:当前shell进程的pid

$!:后台运行的最后一个进程的pid

$-:显示shell使用的当前选项

$_:之前命令的最后一个参数

sed 在13行后面追加内容简单,

sed -i '13 a\123456789' grubconf

前提是13行有内容才能成功

你试了一下你的命令,AAA变量没有内容啊,如果想用变量就把单引号变成双引号试试

环境变量可以帮助提升你的Shell体验。很多程序和脚本都通过环境变量来获取系统信息,存储临时数据和配置信息。

bash使用环境变量( environment variables)来存储有关shell会话和工作环境的信息。这项功能允许你在内存中存储数据,以便程序或shell脚本能够轻松访问。这是存储持久数据的一种简便方法。bash的环境变量分为两类:全局变量和局部变量。

补充:bash使用一致的专有环境变量,但是不同发行版的linux可能会添加自己的环境变量,本博客使用的发行版为Ubuntu 16045 Gnome。

全局变量对于shell会话和所有生成的子shell都是可见的。全局环境变量有助于子shell获取父shell信息。

在Linux中有四个命令可以帮助我们查看所有的环境变量,printenv、env、set、declare。

使用set命令时会一起显示之前定义的函数,仅显示变量可以使用如下命令:

局部变量只能在定义它们的进程中可见,Linux也有默认定义的标准局部环境变量。你也可以自己定义局部环境变量,称为用户定义局部变量。

set命令会显示某个特定进程的所有环境变量,包括局部变量、全局变量以及用户定义变量。

补充:set、env、printenv之间的区别很细微。set命令会显示出所有变量,并且按照字母顺序排序。env和printenv输出相同,但是仅含有全局变量,并且未对变量排序。

设置局部用户定义变量,就是之前002一节提到的变量。

注意:一般bash的环境变量都是使用的大写字母,建议自己的变量名为小写,避免产生冲突。

设置全局环境变量

先创建一个局部环境变量,然后使用export命令将其导出到全局变量。

使用unset命令,格式unset varname

注意:在子shell中删除全局环境变量不会影响到父shell的全局环境变量。

HOME:当前用户的主目录

IFS:shell用来将文本字符串分割成字段的一系列字符

PATH:shell用来查找命令的目录列表。当你输入一个命令时,shell会按照这个目录遍历寻找。

在登录系统启动一个bash shell时,默认情况下bash会在几个文件中查找命令。这些文件叫做启动文件或者环境文件。bash检查的启动文件取决于启动bash的方式:

登录Linux系统是,bash作为登录shell启动。登录shell会一次从以下几个启动文件中读取命令。

/etc/profile文件是系统上默认的bash shell的主启动文件。系统上的每个用户登录时都是执行这个文件。

注意: 某些Linux发行版使用了可拆卸式认证模块(PAM)。这时,PAM文件会在bash启动前处理,这些文件可能会包含环境变量。PAM文件包括/etc/environment和$HOME/pam_environment文件。

我们这里来查看一下/etc/profile文件的内容,学了之前的内容的话,这个文件很容易理解。

$HOME目录下的启动文件

剩下的启动文件都启着同一个作用:提供一个用户专属的启动文件来定义该用户所用到的环境变量。一般Linux发行版只有到下面这四个启动文件中的一两个。

这里列出Ubuntu的启动文件:

可以看到这里只有bashrc和profile两个文件。

shell会按照以下顺序执行启动文件,找到第一个其他的就会被忽略。

注意:这里没有$HOME/bbashrc,因为该文件是通过上面三个文件中的一个运行的。

我们来查看一下profile文件,bashrc文件请自行查看。

注意:这里会检查当前运行的shell是否是bash,如是的话,检查是否存在$HOME/bashrc,若存在则加载该文件。

交互式shell不是登录系统时启动的,它可能是你打开终端启动的。交互式shell不会访问/etc/profile文件,而是只会检查用户HOME目录中的bashrc文件。

执行shell脚本是的非交互式shell。脚本能以不同的方式执行,可以启动子shell执行,也可以在当前shell中执行。

bash提供了一个BASH_ENV的环境变量,当shell启动一个非交互式shell进程时,它会检查这个环境边浪来查看要执行的启动文件。若有指定的文件,则shell会执行该文件。Ubuntu未设置该变量。

若BASH_ENV未设置,那么非交互式shell如何获得环境变量呢?对于以子shell进程执行的情况,子shell会继承父shell导出的变量(export)。对于在当前shell中执行的情况,变量即为当前shell的变量。

在shell脚本中变量的定义,只能以字母和下划线开始,区分大小写,可以包含数字、字母下划线。

示例代码,读取用户输入到变量myvar,然后再输入。

#!/bin/bash

echo "input myvar"

read myvar

echo "myvar is $myvar"

效果如下:

运维

Linux中父shell 与 子shell :subshell 和 child shel

Code_LT

原创

关注

0点赞·346人阅读

子shell的概念

中文翻译过来的“子shell”叫法,实际上包括了“subshell”和“child shell”。

subshell是指: 对父shell的一个拷贝,共享了父shell的变量,函数,别名等,能用但修改只在subshell中生效。通过()开启subshell。内置变量BASH_SUBSHELL显示subshell的层数。

child shell是指: 重新开启的一个shell,不共享父shell的变量,函数,别名。一个纯新的环境。命令bash或者运行脚本就开启child shell。内置变量SHLVL显示child shell的层数。

The Korn Shell: Unix & Linux Programming Manual :

A subshell is a separate copy of the parent shell, so variables, functions, and aliases from the parent shell are available to the subshell

# BASH_SUBSHELL

> echo $BASH_SUBSHELL

0

> (echo $BASH_SUBSHELL)

1 --进入1层 subshell

> ( ( ( ( (echo $BASH_SUBSHELL) ) ) ) )

5 --进入5层 subshell

> bash

> echo $SHLVL

1 --进入1层 child shell

> echo $BASH_SUBSHELL

0

> bash

> echo $SHLVL

2 --进入2层 child shell

> echo $BASH_SUBSHELL

0

登录后复制

一、进入子shell的方式

直接输入bash(退出 :exit,也无法继承和改变父shell中的普通变量,同脚本):child shell

()中的命令是在子shell中实现:subshell

运行脚本,脚本也是在子shell中实现 :child shell

二、差异

child shell是一个全新的环境,不共享父shell中的普通变量,普通变量只能通过export方式实现共享。

subshell 中的普通变量是可以从父shell中继承的,只是不能改变父shell中的变量值。

验证环境:

> cat /proc/version

Linux version 30101-04755-default (geeko@buildhost) (gcc version 434 [gcc-4_3-branch revision 152973] (SUSE Linux) ) #1 SMP Thu May 28 08:25:11 UTC 2015 (dc083ee)

登录后复制

()的表现:

> x=10

> echo $x

10

> echo $$ #该命令用于显示当前shell进程号

10497 --父shell的进程号

> (echo $$;echo $x;ps;x=5;echo $x)

10497 -- 实际上还是父shell的进程

10 -- 进程中的x可取父进程中的x

5 -- 进程中的x被改变

PID TTY TIME CMD

3757 pts/0 00:00:00 bash #subshell进程进程号

3758 pts/0 00:00:00 ps

10497 pts/0 00:00:00 bash #父进程进程号

> echo $x

10 -- 父进程中的x没有改变

登录后复制

bash命令

> bash #进入子shell

> echo $$

3609

> ps

PID TTY TIME CMD

3609 pts/0 00:00:00 bash --child shell进程

5359 pts/0 00:00:00 ps

10497 pts/0 00:00:00 bash

> echo $x

-- 空

> x=5;echo $x

5

> exit #退出子进程

> echo $$

10497 --回到父shell

> echo $x

10 -- 父shell中x没有改变

登录后复制

脚本中子shell的表现:

将echo $$;echo $x;ps;x=5;echo $x写入testsh中

> echo $x

10

> /testsh

8794 --子shell的进程号

-- 无法获取父shell中的变量值

PID TTY TIME CMD

8794 pts/0 00:00:00 sh -- child shell 进程

8795 pts/0 00:00:00 ps

10497 pts/0 00:00:00 bash

5 -- 子shell中定义的变量

> echo $x

10 --父shell中值不变

以上就是关于用shell读取一个配置文件,文件里面如果设置两个变量,又如何用shell读取这两个变量全部的内容,包括:用shell读取一个配置文件,文件里面如果设置两个变量,又如何用shell读取这两个变量、shell 变量名中包含变量怎么弄、SHELL中SED如何获取变量的值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9580236.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存