与`source`命令相反


9

source在bash脚本中使用命令以读取/打印变量值

more linuxmachines_mount_point.txt

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"

source  linuxmachines_mount_point.txt

echo $linuxmachine01
sdb sdc sdf sdd sde sdg

source取消设置变量的反义词是什么?

预期成绩

echo $linuxmachine01

< no output >

14
不是source在您的环境中设置变量,而是在您export的文件中设置语句source。因此,如果您使用的是所有相同变量的不同文件,则source可能与相反。sourcesourceunset
user4556274 '17

2
是的,不要使用导出,只需使用name =“ val”。导出用于脚本到二进制变量(环境)。
ctrl-d


2
这是不可能的。您正在寻找的概念称为可逆计算。编程语言需要特别设计,但要有一些严格的限制,才能使其可逆。Bash不是那些编程语言之一。
约尔格W¯¯米塔格

1
@yael,这是不正确的(而且显然您从未运行过告诉ctrl-d进行的测试);您绝对不需要exports。所有export做的就是复制值到环境中-但他们存在的shell变量是否他们定义为环境变量为好。此外,定义不必要的环境变量会缩短您的最大命令行长度,因为它们存储在每个进程空间相同(有限!)中。
查尔斯·达菲

Answers:


21

使用子外壳(推荐)

在子shell中运行source命令:

(
source linuxmachines_mount_point.txt
cmd1 $linuxmachine02
other_commands_using_variables
etc
)
echo $linuxmachine01  # Will return nothing

子外壳由parens定义(...)。当子shell结束时,将忘记在子shell中设置的任何shell变量。

使用未设置

这将取消设置任何导出的变量linuxmachines_mount_point.txt

unset $(awk -F'[ =]+' '/^export/{print $2}' linuxmachines_mount_point.txt)
  • -F'[ =]+' 告诉awk使用空格和等号的任何组合作为字段分隔符。

  • /^export/{print $2}

    这告诉awk选择以开头的行,export然后打印第二个字段。

  • unset $(...)

    这将在内部运行命令$(...),捕获其标准输出,并取消设置其输出命名的任何变量。


为什么不使用它-对于`awk'{print $ 2}'文​​件中的i | awk -F“ =”'{print $ 1}'`; 取消设置$ i;完成了吗?(更简单的设置方法)
yael

2
@yael不需要使用额外的过程和循环。意见可能会有所不同,但我认为没有那么简单。同样且有潜在危险的是,它假定其中的每一行file都是导出语句。
John1024 '17

8
@yael同样,取消设置变量和取消其他代码副作用正是子外壳程序的目的。他们做到了简单而可靠。除非另有特殊原因,否则应该使用子外壳。
John1024 '17

4

您不能取消source脚本。

您可以做的是将所有导出的变量存储在一个临时文件中,将其与脚本生成后的变量进行比较,然后使用来消除溢出unset,例如:

export > temp_file
source myscript

#... do some stuff

unset "$(comm -3 <(sort temp_file) <(export | sort) | awk -F'[ =]' '{print $3}' | tr '\n' ' ')"

为什么不使用它-对于`awk'{print $ 2}'文​​件中的i | awk -F“ =”'{print $ 1}'`; 取消设置$ i;完成了吗?(更简单的设置方法)
yael

@yael仅在脚本仅包含exports 时才有效。
jimmij

您的意思是“ export s”,我的文件包括linuxmachine01 =“ sdb sdc sdc sdf sdd sde sdg”等等,当我使用awk循环时,它可以毫无问题地设置变量
yael

@yael我不知道您的文件到底是什么样子,所以我给出了一些一般性的答案,例如,如果脚本顶部包含注释“#这是一些带有安装点导出的变量”,该怎么办。
jimmij

2

您可以使用unset命令“忘记”变量。


文件可能与diff机器一起使用,那么如何取消设置文件中的第二个变量?
yael

未设置的变量名会忘记它(您可以在bash / sh / ksh / zsh手册页中找到它的解释),它的演示:pastebin.com/MGQyTZEA
francois P

是的,但是因为变量可能是diff,bash脚本需要通过从文件中读取变量并将其取消设置来做到这一点,所以它不能是静态的,因为变量是未知的
yael

那么你的grep输出线(切),以列表的变量从文件被取消设置出口linuxmachine06 =“深发展SDE自卫队SDD”那么你得到linuxmachine06的名称未设置例如:pastebin.com/M9eCtLc7当你看到unset命令这里DOEN不知道变量名只有在结尾才知道
francois P

好的,我将使用此语法来取消设置-对于awk'{print $ 2}'文​​件中的i | awk -F“ =”'{print $ 1}'`; 取消设置$ i;完成
2015年

2

获得期望的输出(什么都没有)的最简单解决方案是将变量重新声明为空:

$ export linuxmachine01="sdb sdc sdf sdd sde sdg"
$ echo "$linuxmachine01"
sdb sdc sdf sdd sde sdg

$ linuxmachine01=""
$ echo "$linuxmachine01"
$

当然,该变量仍然是定义(并导出)的,但为空但已定义:

$ declare -p linuxmachine01
declare -x linuxmachine01=""

要从环境和正在运行的外壳程序中正确删除变量,应使用unset(推荐的方式):

$ unset linuxmachine01
$ declare -p linuxmachine01
bash: declare: linuxmachine01: not found
$ echo "$linuxmachine01"
$

1

最简单的方法是修改脚本,因此它还定义了一个命令来撤消脚本的影响:

export linuxmachine01="sdb sdc sdf sdd sde sdg"
export linuxmachine02="sde sdd sdb sdf sdc"
export linuxmachine03="sdb sdd sdc sde sdf"
export linuxmachine06="sdb sde sdf sdd"
alias linuxmachines_mount_point='for v in linuxmachine01 linuxmachine02 linuxmachine03 linuxmachine04; do unset $v; done; unalias linuxmachines_mount_point'

为什么使用别名而不是函数?请注意,默认情况下,别名在非交互式Shell中是禁用的,因此,即用型,在脚本中将无法使用。
Charles Duffy

...实际上,如果我们定义一个变量,从而只需要设置一个变量,这将变得更加容易:declare -A linuxmachines=( [01]="sdb sdc sdf" [02]="sde sdd sdb" [03]="whatever" ),这只是unset linuxmachines还原。
查尔斯·达菲

@CharlesDuffy:别名和函数都可以用于此目的。我不建议将所有内容都放入一个变量中的原因是,定义撤消命令更为通用。您不仅可以取消定义变量,还可以取消定义函数,别名,系统设置,终端设置等。它提供了更好的抽象,因为您不必关心undo命令的确切内容。
Lie Ryan

我相信以上观点是,如果“目的”包括非交互使用(即,从脚本调用),则别名不适用于该目的。
查尔斯·达菲

0

您可以这样编写linuxmachines_mount_point.txt

test "$linuxmachine01" && unset -v linuxmachine01 || linuxmachine01="sdb sdc sdf sdd sde sdg"

当您需要变量时

source linuxmachines_mount_point.txt

当您要删除变量时

source linuxmachines_mount_point.txt

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.