Shell脚本:export test1 =“a b c”有效,但$(echo'export test2 =“a b c”')不起作用

时间:2012-04-20 11:58:05

标签: shell escaping zsh

我似乎遇到了一些shell脚本(特别是ZSH)的问题,其中shell无法理解带有空格的导出。只有在使用`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 \ - 转义可能会将错误消息更改为export:4: not valid in this context: b\

任何人都可以深入了解问题所在?谢谢。

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

(*叹*,我希望这不是4.3.12版本中特定版本的问题......我认为这可能在过去有效。)

3 个答案:

答案 0 :(得分:3)

这里的问题是在输出作为命令运行之前完成工作分割。您最终得到的结果是使用3个参数调用export - test1="abc"

使用eval作为其他答案提到的是解决问题的一种方法。

一个有效的解决方案是使用process substitution。如果您的脚本生成多行代码,这将非常有用。

示例:

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

P.S。您可能希望使用<(...)语法而不是=(...)语句,这样它也可以在bash中使用。

答案 1 :(得分:2)

看看this。你可以尝试:

eval 'export test2="a b c"'

答案 2 :(得分:2)

执行此操作的常用方法是使用eval,如kev所述并将其传递给相关程序的完整输出。然后程序应该自己生成有效的shell代码:

eval "$(your_script.py)"

并且your_script.py会打印类似export var1="a b c"的内容(是的,在输出中使用括号可以)。

使用此技术的程序示例是rbenv。用户必须将eval "$(rbenv init -)"放在他的shell 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" "$@"`;;
  *)
    command rbenv "$command" "$@";;
  esac
}