Bash 如何编写输出(文件)名并带有空格的命令,使其在反勾号内工作?
作为一个懒惰的unix/linux命令行用户,我使用了相当多的shell脚本来帮助我避免打字 例如,我有一个脚本Bash 如何编写输出(文件)名并带有空格的命令,使其在反勾号内工作?,bash,shell,zsh,Bash,Shell,Zsh,作为一个懒惰的unix/linux命令行用户,我使用了相当多的shell脚本来帮助我避免打字 例如,我有一个脚本lst,它打印当前目录中最新文件的名称。如果调用mytext并键入emacs`lst`,则mytext将在emacs中打开 但是,如果最近的文件被调用为my text,则emacs`lst`将失败,因为shell将此命令解释为emacs my text,而不是emacs my\text 使用类似于emacs“`lst`”中的引号可以纠正这个问题,但会额外使用两次击键 是否有任何方法可以
lst
,它打印当前目录中最新文件的名称。如果调用mytext
并键入emacs`lst`
,则mytext
将在emacs中打开
但是,如果最近的文件被调用为my text
,则emacs`lst`
将失败,因为shell将此命令解释为emacs my text
,而不是emacs my\text
使用类似于emacs“`lst`”
中的引号可以纠正这个问题,但会额外使用两次击键
是否有任何方法可以修改lst
,使命令在不需要额外击键的情况下工作?输出反斜杠转义文件名无效
我使用了zsh
,但问题(希望解决方案)在bash中是相同的。你必须一直这样。没有捷径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-c'x=“foo*”;echo$(printf“$x)”两次非引号扩展
$zsh-c'模拟sh;x=“foo*”;echo$(printf“$x)”文件
...
这是你想要的巨大胜利(也是让zsh与其他脚本完全不兼容的重要因素之一)。其他shell都不能做到这一点。如何通过键绑定您的惰性函数,这样您就不必键入任何内容,只需按Ctrl+z键,然后在命令行中为您插入文本
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
中的适当位置添加此选项,我从不在shell脚本中使用反勾号。但是命令行是另一回事——两次相同的击键比$()
中三次不同的击键要经济得多,哦,天哪,一个字符!但是是的,高尔夫球手使用它。还有$[]
和一些重定向快捷方式。是的,当sh_word_split
未设置时,zsh不会拆分单词,但这对Handw的问题没有任何影响。这是为什么?即使您的lst
脚本是用bash编写的,从zsh运行它,只要bash脚本编写正确,emacs也应该只获得一个参数。(顺便说一句,我的“最新文件”函数可能比你需要的更复杂,因为它还意味着安全地传递变量名。)创建一个脚本els
,它执行exec emacs“`lst`”
;这样可以节省更多的打字时间。或别名(不带exec
)。