2017-03-03 88 views
0

比方说,我有一堆年初设定的常量,我按字母顺序排列为更好地了解一个脚本:bash的变量向前声明

declare -r home_folder=/home/ 
declare -r user_folder=$home_folder$user_name/ 
declare -r user_name=$USER 

显然,第二行的评价不会给因为bash只进行一次评估,因此稍后调用$user_folder仍然会给出/home/。有什么办法可以解决这个问题吗?

编辑:首选的解决方案看起来像

declare -r home_folder=/home/ 
declare -r user_folder=$home_folder$pointer-to-user_name/ 
declare -r user_name=$USER 

与时user_folder评估被评估的指针,但我不知道是否有可能这在bash。

+0

ALPHABETICALLY ????如何在语义上对它们进行排序,那么可能你的问题本身就会消失。 (按字母顺序... *不相信的摇头*)请不要感到难过。我的建议:尝试按照它们“出现”的顺序排列,然后这个问题就消失了。按字母顺序排列没有足够的优势(如果你问我)没有足够的优势来证明这一点。 – Alfe

+1

Shell脚本是表达行为的迭代方式,执行顺序不是基于依赖关系的。你想要达到的目标要么是读完所有可能的任务,要么只执行满足依赖关系的任务,直到完成所有任务或剩下的所有任务都有未满足的依赖关系,或者构建某种依赖关系树并遵循它。你可以构建它,或者更可能的是,根据它们的语义来决定顺序赋值是否合理,并有助于避免循环依赖,尤其是使用'set -u'时。 – Fred

+0

除了命令的名称之外,shell中没有实际的变量声明。 'declare -r user_name'只设置*名称*上的一个属性;除非实际为其分配值,否则'user_name'仍未定义。 (OK,'-r'就是一个不好的例子,因为未能分配给一个你认为只读的名字会有效地阻止你通过这个名字定义一个变量。) – chepner

回答

0

bash脚本是从上到下逐行执行的,因为它只是逻辑的。与大量其他编程语言一样。变量总是包含您之前分配给它的值。

也许我不明白你的意思是“前向声明”。或者你将“赋值”与“声明”混合在一起?

+0

不知道我是不是混在一起......我想要做的事情就像是'a = pointer_to_b'和'b = foo',所以如果我写'$ a',我会得到'foo'。 – Wanderer

+0

bash afaik中没有指针。可能有其他方法来完成你正在尝试做的事情。你可以尝试eval:a ='$ b'; B = FOO; eval echo $ a; c ='eval echo $ a'; $ c – khaoz

+0

或a ='eval $ b'; B =回声; $ a - 但你不能像真正的指针那样使用它 – khaoz

0

您可以通过shell函数替换所有的变量:

home_folder() { echo "/home/"; } 
user_folder() { echo "$(home_folder)$(user_name)/"; } 
user_name() { echo "$USER"; } 

然后在你使用的代码,你可以随时记$(xxx)访问的xxx内容(而不是通常的$xxx${xxx})。

但是这会减慢一切,因为每个值在使用时都会重新创建。也许你可以忍受这一点。

+0

可能是目前最好的赌注,但我不确定我想写这样的代码...有没有办法像'a = pointer_to_b'和'b = foo',所以如果我写'$ a'我得到'foo'? – Wanderer

+1

那么,你所寻找的是非脚本语言的一个特性,它在执行之前得到编译。在这些范围内,每个常量的典型值都是正好一个值。然后,编译器发现并拒绝相反的任务。在脚本上下文中,这是处理不同的。您可以随时随地覆盖价值持有者。只考虑当前值。因此,引用一个尚未设置的值不会导致任何查找,但会导致运行时错误或(像在bash中)默认值(如空字符串)。 – Alfe

+0

好的,谢谢你指出这个区别。我没有想到这样的构造在一般情况下会成为bash/shell中的一大问题。 – Wanderer