bash 中`set -k` 选项的实际使用

MS.*_*Kim 17 shell bash

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

Bash 参考手册说,

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

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

slm*_*slm 14

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

注意:还有-k开关的长形式,set -o keyword.

例子

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD
Run Code Online (Sandbox Code Playgroud)

现在如果我set -k

$ set -k; ./cmd1.bash VARCMD="hi"; set +k
hi
Run Code Online (Sandbox Code Playgroud)

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

$ ./cmd1.bash 

$
Run Code Online (Sandbox Code Playgroud)

出口做什么?

$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.
...
Run Code Online (Sandbox Code Playgroud)

所以如果我们export | grep VAR像这样添加到我们的脚本中:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR
Run Code Online (Sandbox Code Playgroud)

我们再次运行上述测试:

$ set -k; ./cmd2.bash VARCMD="hi"; set +k
hi
declare -x VARCMD="hi"
Run Code Online (Sandbox Code Playgroud)

但没有set -k

$ ./cmd2.bash 

$
Run Code Online (Sandbox Code Playgroud)

所以,set -k还可以让我们暂时出口质量变量。

另一个例子

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR
Run Code Online (Sandbox Code Playgroud)

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

$ set -k; ./cmd3.bash VARCMD1="hi" VARCMD2="bye"; set +k
hi
bye
declare -x VARCMD1="hi"
declare -x VARCMD2="bye"
Run Code Online (Sandbox Code Playgroud)

那么它只是注入所有环境变量?

不在-k这里做了一件非常明确的事情。它仅导出在执行命令时包含在命令行中的变量。

例子

假设我设置了这个变量:

$ VARCMD1="hi"
Run Code Online (Sandbox Code Playgroud)

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

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

bye
declare -x VARCMD2="bye"
Run Code Online (Sandbox Code Playgroud)

但是为什么会这样呢?

我找到了这个来源,它对这个功能做了一些解释,标题是:“关键字参数分配字符串”。注意:源 URL 使用 IP 地址,因此我无法在 SE 上直接链接到它。

http://140.120.7.21/OpenSystem2/SoftwareTools/node16.html
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 关键字参数可以由 set 命令操作。

  • `./cmd.bash VARCMD=hi` 需要 `set -k` 来让它像 `VARCMD=hi ./cmd.bash` 没有`set -k` 那样工作。猜猜 OP 的具体问题是需要 bash 支持 `./cmd.bash VARCMD=hi` 形式 (4认同)

Mar*_*ick 9

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

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

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

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

set -k
...
command var1=val1 var2=val2