bash中set -k选项的实际用法


16

我们什么时候set -k在bash中使用option?

Bash参考手册说,

所有赋值语句形式的参数都放置在命令环境中,而不仅仅是命令名称之前的参数。

我了解该选项的作用,但是无法想象我们何时需要它。


正确认识。将-k允许我们无需重构他们跑了30岁的shell脚本。而是使用前缀语法传递临时环境变量:var1=x var2=y command ...
Henk Langeveld 2014年

Answers:


14

您基本上可以随时使用它,只要要将环境变量“注入”到shell脚本中(作为参数),就好像它们是通过export,在环境中设置的一样,而不必export在运行命令之前将它们永久驻留在的列表中。

注意:-k开关的形式也很长set -o keyword

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

现在,如果我set -k

$ set -k; ./cmd1.bash VARCMD="hi"; set +k
hi

但是,如果我只是运行上面的脚本:

$ ./cmd1.bash 

$

出口在做什么?

$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.
...

因此,如果我们要export | grep VAR像这样添加到脚本中:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

然后,我们再次运行了上述测试:

$ set -k; ./cmd2.bash VARCMD="hi"; set +k
hi
declare -x VARCMD="hi"

但没有set -k

$ ./cmd2.bash 

$

因此set -k,允许我们暂时批量导出变量。

另一个例子

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

当我们设置多个变量时,它们全部被导出:

$ set -k; ./cmd3.bash VARCMD1="hi" VARCMD2="bye"; set +k
hi
bye
declare -x VARCMD1="hi"
declare -x VARCMD2="bye"

那么,这只是注入所有环境变量吗?

没有-k在这里做一个非常明确的事情。执行命令时,仅导出命令行中包含的变量。

说我设置这个变量:

$ VARCMD1="hi"

现在,当我们运行相同的命令时省略VARCMD1="hi"

$  set -k; ./cmd3.bash VARCMD2="bye"; set +k

bye
declare -x VARCMD2="bye"

但是为什么会这样呢?

我找到了该源代码,该源代码解释了此功能,标题为:“关键字参数分配字符串”。注意:源URL使用IP地址,因此我无法在SE上直接链接到它。

http://140.120.7.21/OpenSystem2/SoftwareTools/node16.html

使用任何语言进行编程时,变量及其值传递对于编写可靠的代码至关重要。除了整数和数组变量类型之外,所有其他外壳程序变量都接受字符串作为其值。一致地说,在谈论Shell编程语言时,我们更喜欢短语“关键字参数”。将值分配给关键字参数时,需要注意以下几点:

  • 为避免任何意外的影响,请始终将参数分配子字符串放在命令字符串的前面。

    在B Shell中,关键字参数的分配值将存储在(本地)Shell变量中。在bash和ksh中,命令前面的关键字参数分配字符串将不会存储在shell变量中。它们仅影响执行当前命令的分支子流程。仅一行关键字参数赋值字符串确实存储在(本地)shell变量中。关键字参数分配字符串也可以作为别名,声明,排版,导出,只读和本地内置命令的参数出现。[Bash参考手册的3.4节]

  • 如果将关键字参数分配字符串放在命令名称之后,则将它们视为要执行的命令的参数。

  • 关键字参数可以通过set命令来操作。

在此链接中,ss64.com/bash/set.htmlset -k因为-o keyword除了-k选项外,它们还给出了。那是什么意思吗?
Ramesh 2014年

@Ramesh- set -o keyword是的长格式set -k。请参阅help set | grep -- '-k'
slm

喔好吧。我摸索了很长时间,试图了解为什么有两种选择。像往常一样完美的答案:)
Ramesh 2014年

4
./cmd.bash VARCMD=hi需要set -k使它的工作完全像VARCMD=hi ./cmd.bash没有set -k。猜猜OP的特定问题是需要bash来支持./cmd.bash VARCMD=hi表单的问题
iruvar

@ 1_CR-好点。我认为这与风格息息相关,我会看看是否可以找到实际的来源。
slm

8

的任何实际用法set -k都可能只是个人风格。某些人-也许喜欢那些提供在函数调用中使用关键字参数的能力的编程语言,或者喜欢该dd命令语法的少数人-可能更喜欢

设置-k
...
命令var 1 = val 1 var 2 = val 2

var 1 = val 1 var 2 = val 2命令

POSIX标准中set命令基本原理解释了该选项在某些外壳中存在的实际原因:

The following set flags were omitted intentionally with the following rationale:

The -k flag was originally added by the author of the Bourne shell to make it easier
for users of pre-release versions of the shell. In early versions of the Bourne shell
the construct
    set name=value
had to be used to assign values to shell variables.
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.