2

作为一个懒惰的 unix/linux 命令行用户,我使用了很多小的 shell 脚本来帮助我避免打字。

例如,我有一个脚本lst可以打印当前目录中最新文件的名称。如果这被调用mytext并且我输入emacs `lst`然后mytext将在 emacs 中打开

但是,如果调用了最近的文件,my text那么emacs `lst`将失败,因为 shell 将此命令解释为emacs my text而不是emacs my\ text

使用 in 之类的引号emacs "`lst`"可以解决问题,但会使用两次额外的击键

有什么方法可以修改lst,以便命令在没有额外击键的情况下工作?输出反斜杠转义的文件名不起作用。

我使用zsh,但问题(希望是解决方案)在bash

4

2 回答 2

1

永远不要使用反引号。您必须始终正确引用。没有捷径。printf %q是唯一可远程移植的替代方案(Zsh${(q)var}类似),但这些不适合您的问题。正确的(唯一的)答案是引用。

编辑:也许你应该坚持使用 zsh 来进行交互。我不是该 shell 的专家,但我知道例如,如果不使用其特殊扩展,它不会在默认模式下执行分词或通配。

$ zsh -c 'x="foo *"; echo $(printf "<%s> " $x)' # two passes of unquoted expansion
<foo *>
$ zsh -c 'emulate sh; x="foo *"; echo $(printf "<%s> " $x)'
<foo> <bltins> <builtins.mm> <COMPATIBILITY> <data> ...

对于您想要的东西,这是一个巨大的胜利(并且是使 zsh 与其他所有脚本完全不兼容的重要因素之一)。没有其他 shell 可以做到这一点。

于 2013-01-24T10:12:16.197 回答
1

如何对你的惰性函数进行键绑定,这样你就不用输入任何内容,只需点击Ctrl+zzle在你的命令行中为你插入文本。

z_lst() {                                                                      
  emulate -L zsh
  setopt extendedglob
  local lastfile
  # you could even implement your whole lst function here instead
  lastfile=$(lst)
  LBUFFER+=" ${lastfile// /\ }" # this should print the spaces like '\ '.
}                                                                               
zle -N z_lst && bindkey "^z" z_lst

将此添加到您的.zsh.

于 2013-01-24T15:59:35.023 回答