【问题标题】:Defining common variables across multiple scripts?跨多个脚本定义公共变量?
【发布时间】:2015-01-29 08:32:03
【问题描述】:

我有许多 Bash 和 Perl 脚本,它们在功能上不相关,但它们在同一个项目中工作是相关的。 它们在同一个项目中工作的事实意味着我通常在每个脚本的顶部指定相同的目录、相同的项目特定命令、相同的关键字。

目前,这并没有让我感到困扰,但我知道将所有这些值放在一个地方会更容易,然后如果发生更改,我可以更改一次值并让各种脚本接受这些更改。

问题是 - 如何最好地声明这些值?在每个脚本中“必需”的单个 Perl 脚本将需要对 Perl 脚本进行较少更改,但不提供 Bash 脚本的解决方案。使用“key=value”格式的配置文件可能更通用,但需要每个脚本来解析配置并且有可能引入问题。有更好的选择吗?使用环境变量?还是 Perl 可以轻松执行和解释的 Bash 特定方式?

【问题讨论】:

  • key=value 格式是原生 sh,可以使用 . 命令获取。它可以很容易地用 perl 解析。
  • 做得好,非常真实!我现在觉得自己很愚蠢。
  • 您也可以使用export 命令创建全局环境变量。例如:export FOO=2.
  • 另一个想法:将您的数据放入 shell 脚本中。该脚本将采用一个选项来控制数据的输出方式。调用程序将eval 结果。 ssh-agent 这样做:eval ssh-agent -c 用于 c-shell,eval ssh-agent -s 用于 bourne shell。
  • 为此,我们使用了一个“源”文件——您可以在运行 perl 之前获取该文件,也可以内联 . SOURCE; echo \$var

标签: bash perl variables configuration perl-module


【解决方案1】:

当您运行 shell 脚本时,它是在子 shell 中完成的,因此它不会影响父 shell 的环境。因此,当您将变量声明为 key=value 时,它的范围仅限于子 shell 上下文。您想通过以下方式获取脚本:

. ./myscript.sh

这会在当前 shell 的上下文中执行它,而不是作为子 shell。

来自 bash 手册页:

. filename [arguments]
source filename [arguments]

Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.

If filename does not contain a slash, file names in PATH are used to find the directory containing filename. 

您还可以使用export 命令创建全局环境变量。 export 控制哪些变量可用于新进程,所以如果你说

FOO=1
export BAR=2
./myscript2.sh

那么$BAR会在myscript2.sh的环境中可用,但$FOO不行。

【讨论】:

  • 这是我采取的路线,然后在 Perl 中使用my %CONFIG = read_file( "path/to/config" ) =~ /^(.+)=(.*)$/mg; 来解析和使用其中的变量。
【解决方案2】:

定义环境变量: 用户级别:在您的 ~/.profile 或 ~/.bash_profile 或 ~/.bash_login 或 ~/.bashrc 系统级别:在 /etc/profile 或 /etc/bash.bashrc 或 /etc/environment

例如为每个变量添加拖线:

FOO=myvalue
export FOO 

在 bash 脚本中读取这个变量:

#! /bin/bash

echo $FOO

在 perl 脚本中:

#! /bin/perl

print $ENV{'FOO'};

【讨论】:

  • 虽然这可行,但我认为减少环境变量的数量可能是一件好事,当然没有其他进程可以轻松地改变它们。
【解决方案3】:

您还可以获取另一个文件,因此您不会创建额外的环境变量,这可能会导致意外行为。

source_of_truth.sh:

FOO="bar"

scritp1.sh

#!/usr/bin/env bash

source source_of_truth.sh

echo ${FOO}
# ... doing something

scritp2.sh

#!/usr/bin/env bash

source source_of_truth.sh

echo ${FOO}
# ... doing something else

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 2021-08-08
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多