在fish shell中从另一个脚本获取变量的值



我在同一个目录下有两个脚本:

latlong.sh

#!/bin/sh
set latlong 'x.xxxxxx:x.xxxxxx'

autostart_once.sh

#!/bin/sh
. ./latlong.sh
# some start up commands
redshift-gtk -l $latlong -t 6500:3600 &

但是,在上面运行autostart_once.sh会产生一个错误。似乎即使在找到latlong脚本之后,latlong变量仍然是空的(我已经确保工作目录是latlong.sh所在的位置)。但是,如果我在运行鱼壳的终端中运行. ./latlong.sh,然后运行echo $latlong,则变量设置正确。这里会发生什么?

一些事情:

  1. 我不希望能够在自动启动脚本之外访问变量。
  2. 我将latlong变量放入另一个文件的原因是我在将该文件推送到dotfiles存储库之前加密了该文件,但我不想加密启动文件,以便其他人也可以使用它。

. ./latlong.sh中的.在某些shell中也称为source。[0]

它的作用是告诉当前shell在当前shell中运行给定的脚本。

这意味着在/bin/sh脚本中将运行latlong.sh与/bin/sh,无论shebang如何,因此它将运行

set latlong 'x.xxxxxx:x.xxxxxx'

将位置参数设置为latlongx.xxxxxx:x.xxxxxx。它在语法上是有效的,但在/bin/sh中的含义与在fish中的含义完全不同。当你在fish中运行. ./latlong.sh时,该鱼会读取它并将set解释为fish内置程序。

简而言之:这里最简单的解决方案是用同一种语言编写两个脚本。这将允许您在同一个shell中source它们,保持变量的完整。

如果您的latlong.sh与这里展示的示例一样简单,那就很容易了:

latlong=x.xxxxxx:x.xxxxxx

或者你可以选择csv或json之类的数据格式,然后想办法将加载到任何shell中。

或者您可以尝试direnv所做的相同的事情,即在定义的shell(在他们的情况下是bash)中运行脚本,然后对环境变量进行diff,以便在用户的shell中应用它们。

[0]:遗憾的是,posix不需要这样做,所以我们经常被不可读和容易错过的.名称所困扰