在zsh函数内捕获命令输出

时间:2012-01-23 20:53:29

标签: function zsh

我正在尝试编写一个zsh函数来获取python模块的路径。

这有效:

pywhere() {
  python -c "import $1; print $1.__file__"
}

然而,我真正喜欢的是没有文件名的dir路径。这不起作用:

pywhere() {
  dirname $(python -c "import $1; print $1.__file__")
}

注意:它适用于bash,但不适用于zsh!

编辑这是错误:

~ % pywhere() {
function →   dirname $(python -c "import $1; print $1.__file__")
function → }
  File "<string>", line 1
    import pywhere() {
                  ^
SyntaxError: invalid syntax

2 个答案:

答案 0 :(得分:2)

您的问题是由于preexec损坏:当您打印它以包含在窗口标题中时,您没有正确引用命令行。

在您发布的.zshrc中,这不是您使用的那个(不要这样做!始终复制粘贴您使用的确切文件内容和命令),我看到了:

a=${(V)1//\%/\%\%}
a=$(print -Pn "%40>...>$a" | tr -d "\n")
print -Pn "\ek$a:$3\e\\"

print -P会导致迅速扩展。您在参数中包含该命令。您可以通过加倍来保护命令中的%个字符,但这还不够。您显然已启用prompt_subst选项,因此print -P会导致命令行中的$(…)构造定义要执行的函数:

python -c "import $1; print $1.__file__"

其中$1是命令行(函数定义:pywhere { … })。

不是尝试解析命令行,而是按字面打印出来。这也将纠正其他错误:除了不考虑prompt_subst之外,您将%符号加倍,但由于您执行了两次快速扩展,因此应该将它们翻两番,然后将\序列扩展两次好。

function title() {
  a=${(q)1} # show control characters as escape sequences
  if [[ $#a -gt 40 ]]; then a=$a[1,37]...; fi
  case $TERM in
  screen)
    print -Pn "\ek"; print -r -- $a; print -Pn ":$3\e\\";;
  xterm*|rxvt)
    print -Pn "\e]2;$2 | "; print -r -- $a; print -Pn ":$3\a";;
  esac
}

答案 1 :(得分:1)

为什么不使用它:

python -c "import os, $1; print os.path.dirname($1.__file__)"