![如何“获取”特定变量](https://linux22.com/image/171314/%E5%A6%82%E4%BD%95%E2%80%9C%E8%8E%B7%E5%8F%96%E2%80%9D%E7%89%B9%E5%AE%9A%E5%8F%98%E9%87%8F.png)
假设我有两个 bash 脚本:
提供者.sh,它执行一些过程并需要“暴露” MAP
,但不是A
or B
:
#!/bin/bash
declare -A MAP
A=hello
B=world
MAP[hello]=world
消费者.sh,它执行Provider.sh
并需要使用MAP
.
#!/bin/bash
source ./Provider.sh
echo ${MAP[hello]} # >>> world
为了尽可能地整理环境,我希望尽可能少的Provider.sh
可见Consumer.sh
。如何才能做到只有 MAP 是“来源”的。
答案1
可以使用函数来确定变量的范围。例子:
## Provider.sh
# Global vars
declare -A map
# Wrap the rest of Provider.sh in a function
provider() {
# Local vars only available in this function
declare a=hello b=world c d
# Global vars are available
map[hello]=world
}
provider "$@" # Execute function, pass on any positional parameters
# Remove function
unset -f provider
$ cat Consumer.sh
. ./Provider.sh
echo "${map[hello]}"
echo "$a"
$ bash -x Consumer.sh
+ . ./Provider.sh
++ declare -A map
++ provider
++ declare a=hello b=world c d
++ map[hello]=world
++ unset -f provider
+ echo world
world
+ echo ''
答案2
您可以使用函数并使变量成为本地或全局变量:
#!/bin/bash
foo() {
declare -gA MAP # make global
local A=hello # make local
local B=world # make local
MAP[hello]=world
}
foo
然后:
#!/bin/bash
source ./Provider.sh
[[ -z "$A" ]] && echo "Variable A not defined"
[[ -z "$B" ]] && echo "Variable B not defined"
echo ${MAP[hello]}
输出:
Variable A not defined
Variable B not defined
world
答案3
我不相信有办法只获取 shell 脚本的一部分。你可以选择获取全部内容,也可以什么都不获取。
但是,您可以grep
仅从文件中提取所需的行并将其写入新文件,然后您可以获取该新文件。当然,如果您的代码中有一些复杂的函数,那么这将不起作用。
无论如何,最好将此代码拆分为多个脚本,并仅获取您需要的内容。如果您只想使用一个脚本,您还可以将代码放入多个函数中,从多个位置获取代码,然后仅调用您需要的函数。
答案4
当您说source
并且有两个文件时,我认为您希望在命令行上提供这两个命令,并希望提供者设置变量供消费者稍后使用。 (啊,我看到消费者来源生产者,所以他们将共享相同的命名空间,消费者不会污染它的调用命名空间。
我对某些 bash_aliases 使用函数,并从.bashrc
.这样,它们就可以在当前 shell 中设置和使用变量,而不是在子 shell 中,变量在运行后就会消失。
当我有一个必须获取才能工作的 bash 文件时,我在其中添加了一个提醒shebang
:
#!/bin/echo "You have to source this file (${BASH_SOURCE}), not run it"
# -*-mode:sh;sh-shell:bash;fill-column:84-*-
请注意,/bin/echo
使用的是 /bin/bash,而不是 /bin/bash,这样在运行时,它只会回显第一行。
还将${BASH_SOURCE}
向用户提示文件的位置。
第二行# -*-mode:sh;sh-shell:bash;fill-column:84-*-
是让 Emacs 在编辑文件时弄清楚如何突出显示和缩进文件。
guest 提供的两个功能很棒,但是如果放在单独的文件中,如果您只是运行文件,则这些功能将不会被激活。
所以,我在这里获取了访客的代码,但进行了一些更改,以实现我认为您可能想要的功能。另外,条件是将它们放入要获取的文件中。
#!/bin/echo "You have to source this file (${BASH_SOURCE}), not run it"
# -*-mode:sh;sh-shell:bash;fill-column:84-*-
# define producer and consumer functions
declare -A MAP # you might want to use a different name
# because this is going to be in your global namespace
function provider() {
local A=hello
local B=world
MAP[hello]=world
}
## However maybe what you are wanting is a setter function instead?
function providerSetter() {
MAP[${1}] = ${2}
}
function consumer()
echo ${MAP[hello]}
}
## Again, you might want a getter function
function consumerGetter()
echo ${MAP[${1}]}
}
## you can put defaults into the second functions, i.e.,
function providerSetter2() {
MAP[${1:-hello}] = ${2:-world}
}
function consumerGetter2()
echo ${MAP[${1:-hello}]}
}
欢迎来到论坛!