【问题标题】:Is my Perl script grabbing environment variables from "someplace else"?我的 Perl 脚本是否从“其他地方”获取环境变量?
【发布时间】:2010-05-28 16:59:30
【问题描述】:

在“神秘的生产系统”中的 Solaris 机器上,我正在运行一个引用环境变量的 Perl 脚本。没什么大不了的。

shell 执行前和执行后的那个变量的内容是我所期望的。

但是,当脚本报告时,它看起来好像在其他某个子 shell 中运行,这在脚本执行期间用不同的值破坏了我的变量。

很遗憾,我真的无法粘贴代码。我正在尝试获得一个原子案例,但我已经无能为力了。

【问题讨论】:

  • 你是直接运行脚本,用你自己的手指在你自己的shell中输入吗?还是通过 cron 或 sudo 或 nohup 或 Web 服务器等其他方式运行?

标签: perl solaris environment-variables


【解决方案1】:

您的脚本或您“使用”的任何库是否可能与 %ENV 散列混淆?

【讨论】:

  • 好主意,但不幸的是没有。它只使用 Sybase::DBLIB 和 Net::FTP。
  • BEGIN{use Tie::Trace;Tie::Trace::watch %ENV} 放在脚本的顶部(在use 任何其他模块之前)。然后,每当您的 Perl 脚本中的环境变量发生变化时,您都会收到一条警告消息。
  • @mobrule:很棒的提示!我以前从来不知道。
  • @mobrule:这个建议太好了,不适合发表评论。将其作为答案并为自己赢得一些支持。当然,如果我想要一个真正安全的系统,我可能会在启动时破坏大部分 %ENV
【解决方案2】:

你能通过 Perl 调试器运行代码来看看它的去向吗?你能转储 pid ($$) 来检查它是分叉还是调用子shell?

或者,您可以在整个代码中散布打印语句,以缩小环境变量被更改的时间点,或者开始删除不太可能与故障点相关的组件。

【讨论】:

  • 我喜欢 perl 调试器的想法。我一直忘记它的存在;)目前我们发现了一个非常奇怪的环境解决方法,所以,为了方便起见,我必须接受它(它比这个症状要高得多。)一旦我清楚了这个问题我将在本地克隆这个东西,看看我是否无法按照你描述的方式弄清楚。谢谢o/
【解决方案3】:

1) 什么版本的 Perl?

2) 我相信某些环境变量可能会被子进程破坏。可以ps吗?

【讨论】:

  • 我们使用的是 5.8.4。不幸的是我不能ps它。 1)它结束得太快了。 2)它是一个只读脚本的符号链接,所以我不能在游戏中添加暂停,所以我可以。
  • 你能杀死符号链接并在那个地方创建一个副本进行调试吗?
  • 是的,你知道,我很可能能够做到这一点。它有巨大的卷须,执行子进程是为了它的“实时”目的,但冷静思考我认为我没有理由至少不能在孤立的环境中将它带到问题区域。
  • @MichaelWilson 编写 Pause.pm 执行 END { sleep 999 } 1; 并以 perl -Ipath/where/Pause/lives -MPause yourprogram 运行程序。这会让它在完成后进入睡眠状态。您可以使用相同的技术来绑定 %ENV 哈希,并让它在任何时候报告它的变化。或者只是将代码复制到您的主目录,将其编辑为您喜欢的内容并从那里运行它。如果它使用 FindBin 来定位东西,您可以在 BEGIN 块中更改 $0 以匹配原始位置。
【解决方案4】:

好的,这就是发生的事情:

perl 本身完全是一个红鲱鱼。

脚本在子 shell 中执行,创建时会重新加载 rc 文件。那些 rc 文件破坏了我在父 shell 中手动添加的环境变量和参考副本。

我能够通过一个简单的 csh 脚本来演示这一点,该脚本刚刚回显了环境。

消除我的 rc 文件(这些文件被 wonkitude 过度劳累)清除了神秘的替换。

更新:证明这是一个“test.sh”的测试,它有一个简单的“set”命令。证明子shell没有正确继承父环境。奇怪的是,当我将父交互式 shell 切换到 ksh 时,环境开始正确继承。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2018-09-16
    • 2021-05-07
    相关资源
    最近更新 更多