比如说,zsh
可以在命令前面加上noglob
“关闭文件名生成(通配)”前缀。
我正在寻找一个 shell,其中类似的方法不仅可以用于禁用通配符,还可以禁用所有类型的扩展。理由:对任何复杂的命令使用反斜杠转义或引号都会使其变得一团糟,A)难以阅读和理解B)不适合在其他嵌套级别上重复使用。
答案1
在 中zsh
,您可以执行以下操作:
set -o interactive_comments -o extendedglob
alias '@=:;# '
handle_@() {
local match
if [[ $1 = (#b)@\##[[:space:]]##([^[:space:]]##)[[:space:]]#(*) ]] $match
}
preexec_functions+=(handle_@)
然后在你的命令前面加上前缀@
(必须组成整个编辑缓冲区,没有foo; @ cmd
norfoo | @ cmd
等),之后的第一个单词将被视为命令名称,并且该行的其余部分将作为一个参数传递给该命令命令:
$ @ echo asd'@123 # # qwe $x ``
asd'@123 # # qwe $x ``
这意味着一个参数不能以空格开头,也不能包含换行符。
这是通过使用别名@
来实现的:;#
,:
noop 命令(以便preexec
运行钩子)后跟注释引导符,因此该行的其余部分被解析为注释并被丢弃。
在preexec
钩子中,我们将未处理的行(in $1
)拆分为命令和参数。请注意,\##
允许在其中解决旧版本(5.3 或更早版本)中的#
错误。请注意,它在 4.3.12(从 2011 年起)或更早版本中不起作用,其中注释不包含在s中。@
zsh
prexec()
$1
有趣的是,zsh 还具有quote-region
和quote-line
小部件(在 emacs 模式下默认分别绑定到Alt+"和Alt+ '),这可以省去您自己进行正确引用的麻烦。
例如,您可以这样做:
$ perl -e Ctrl+Space$x = '随便';...Alt+"
哪里Ctrl+Space或Ctrl+@(终端通常发送 NUL 字符)设置地区。
在 上Alt+",这将转换为:
perl -e '$x = '\''whatever'\'';...'
与地区现在引用。也可以看看https://stackoverflow.com/q/5407916了解如何设置地区(选择)使用Shift+ 箭头/运动键。