2012-04-20 88 views
1

我似乎有一些shell脚本的问题(ZSH特别),其中壳失败了解其中的空间出口。只有在使用`runco​​mmand`或$(runco​​mmand)时才会出现问题。

测试用例:

# Works fine: 
export test1="a b c" 

# Does not work: 
$(echo 'export test2="a b c"') 

的错误是沿export:4: not valid in this context: c"线的东西。在空格和/或引号之前添加1-2 \ -escapes可能会将错误消息更改为export:4: not valid in this context: b\

任何人都可以洞察问题是什么?谢谢。

(我这样做的原因是允许python通过动态生成在.myshellrc中运行的代码来设置shell变量;如果有人知道更优雅的方式来执行此操作,那将非常受欢迎,因为评论。谢谢)编辑:为了澄清,我正在寻找一种方法来完成上述工作,或者一种允许外部脚本来指定要输出的方法的替代方法。

(*叹息*,我希望这不是在4.3.12版本特定的问题......我想,这可能在过去的工作。)

+0

'echo $ test2'将会打印'“a' – kev 2012-04-20 12:11:33

回答

2

通常的方式做到这一点是使用eval作为千电子伏说,并把它传递有问题的程序的完整输出。然后程序应出示有效的shell代码本身:

eval "$(your_script.py)"

而且your_script.py将打印像export var1="a b c"(是的,输出使用括号是OK)。

使用这种技术的程序的一个例子是rbenv。用户必须把eval "$(rbenv init -)"在自己的壳init文件,并rbenv init实际输出相当多的代码:

export PATH="/opt/rbenv/shims:${PATH}" 
source "/opt/rbenv/libexec/../completions/rbenv.zsh" 
rbenv rehash 2>/dev/null 
rbenv() { 
    local command="$1" 
    if [ "$#" -gt 0 ]; then 
    shift 
    fi 

    case "$command" in 
    shell) 
    eval `rbenv "sh-$command" "[email protected]"`;; 
    *) 
    command rbenv "$command" "[email protected]";; 
    esac 
} 
+0

谢谢,这是非常有用的。 – ninjagecko 2012-04-20 12:22:55

+0

接受与警告,人们也应该检查出'源=(scriptname)[arg0 arg1的ShawnChin的优秀答案http://stackoverflow.com/a/10246161/711085。 ..]' – ninjagecko 2012-04-21 09:40:39

2

看看this。你可以试试:

eval 'export test2="a b c"' 
+0

不幸的是,这似乎并未使用其他命令。是否有可能使此解决方案适用于使用另一个生成多行代码的脚本的输出,而不是” export test2 =“abc”''?对不起,我在这个问题中提到了我的目标;我会尝试在编辑中澄清它 – ninjagecko 2012-04-20 12:15:44

+0

啊,简单的扩展eval'$(...)'似乎确实起作用,谢谢 – ninjagecko 2012-04-20 12:21:47

3

这里的问题是它运行的命令之前的工作拆分是为了输出。你最终以export被3个参数调用 - test1="a,bc"

使用eval其他答案已经提到的是要解决它的方法之一。

的altenative的解决办法是使用process substitution。如果您的脚本生成多行代码,这特别有用。

实施例:

zsh% source =(echo export test1=\"a b c\") 
zsh% echo $test1       
a b c 

P.S.您可能想要使用<(...)语法而不是=(...),这将允许它也在bash中工作。

+0

啊,引人入胜,谢谢。可悲的是我只能接受一个答案,你认为哪种方法一般更清洁?他们有没有相对的优势? – ninjagecko 2012-04-20 12:49:14

+1

在这种情况下,他们都同样工作。我偏向于流程替代,因为它们在许多情况下也派上用场(例如http://stackoverflow.com/questions/7651946/bash-coproc-and-leftover-coproc-output/7653550#7653550),但是对于许多这是一个陌生的概念,如果您想让其他读者能够访问它,可能需要额外的评论。 – 2012-04-20 13:02:11

+0

啊我想我明白了。在eval“$(somescript)”的情况下,我们正在执行''eval multipleLinesOfShellCodeToEmbedWhichWereRegurgitatedBySomescript“';在source =(somescript)'的另一种情况下,我们仍在运行somescript,但不是将代码转储到文件中,而是创建一个临时匿名文件,并找到文件(可能有或没有类似文件,或完全相同的语义)。 – ninjagecko 2012-04-20 13:36:38

相关问题