|
不废话了,刚吵完架,写点东西抛砖引玉,舒缓心情。
TCSH 中是使用内置的 complete 命令来设置 Programmable Completion 功能的。
complete 的语法为:
complete [command [word/pattern/list/[:select]/[[suffix]/]
"[" 和 "]" 中的内容是可以省略的部分。如果 complete 省略所有部分,它将输出所有完成规则。如果后面跟命令名,则输出命令对应的完成规则。
command 部分是一个命令名,同时也可以包括 glob-pattern。也就是说 command 部分可以是 {rm,rmdir} (代表其后对应的规则可以是 rm 也可以是对应 rmdir)。常用 shell 的朋友都经常用 rm * 或 ls /bin/?? 这样的语句吧。glob-pattern 指的就是这些特殊符号构成的 pattern。TCSH 中可以包括 "{}" "[]" "*" "?" 。
{a,b,c} 表示 a, b 和 c 三个文件。[abc]1 表示的是 a1 b1 c1。想了解更多请 man tcsh 查找 Filename Substitution 小节。至于 "*" 和 "?" 大家也经常用到,不说了。
TCSH 中可以设置特殊的 shell 变量 "noglob" 取消这个功能。来个小例子:
> touch filename{1,2,3}
> ls
> filename1 filename2 filename3
> set noglob
> touch tmp{1,2,3}
> ls
> tmp{1,2,3}
下面这部分基本是我看手册随手抄的,没说清楚的请海涵,看手册就明白,很简单。后面也会有例子,用起来就简单了。
complete 命令的 word 部分制定了哪种情况下命令行输入的词需要在按 TAB 键的时候被完成。包括以下几种:
c 小写,完成当前的词。命令行输入的部分需要同 pattern 部分(一个glob-pattern)开头相匹配。完成的时候 pattern 被忽略。
C 大写。作用与 c 相似,完成的时候包含 pattern 。
n 完成下一个词,是当前输入字符与需要被完成的词中间有分隔符号,比如空格。命令行当前光标前部分需要同 pattern 相匹配。
N 大写,与前两个词匹配。
p 与位置匹配,比如我输入
> ls /usr/share
则 p/1/pattern 这个 1 就同 "/usr/share" 相匹配。与 shell 变量的 index 用法相同。
list 部分是指定可能的完成方法。为以下几种:
a Alias 命令的别名,bash 用户应该也很熟悉
b 绑定的行编辑命令,就是指 CTRL-A CTRL-E CTRL-U CTRL-K 这些快捷键的对应行编辑命令 beginning-of-line end-of-line 等等。
c 命令,内部命令(shell 内部的命令)或外部命令(/usr/bin /usr/sbin /bin 等等)
C 大写,这是你指出特定路径中的外部命令
d 目录
D 你指定的特定目录
e 环境变量,也就是 printenv 或 env 命令输出的那些大写变量。TCSH 内部的变量通常都是小写,环境变量都是大写,比较容易区别。
f 文件名,这个文件名可以指文件的名字,也可以指目录的名字
F 指定路径的文件名
g 用户组的名字,不是数字
j Jobs,放在后台的 jobs 等等。
l 小写的 L ,不是 1 2 3 的 1,指的是限制。就是 bash 中 ulimit 命令输出的那些资源。TCSH 与 BASH 相同,但资源的名字打印出来稍有不同。
n 代表 noting ,什么也不干
s 小写,shell 的变量。
S 大写,这是指 Signal ,信号。kill -l 命令输出的那些信号。这里指的是信号名,不是对应的数字。
t 常规文件,这就是指普通文件了,不包括目录。注意与 f 的区别。
T 大写,指定目录的文件。
v 所有的变量(variables),包括内部变量和环境变量。
u 系统中所有的用户名。
x 作用与 n 相似,不同的是在执行 list-choices 行编辑命令(TCSH 将其绑定在 CTRL-D )的时候,向屏幕输出 select 部分的内容,可以作为自定义的帮助信息。
X 大写,指的是系统中已经有的 completion 内容。
$var 变量中的内容
(...) 指括号中的词,比如 (hello world),完成的时候对应 hello 或者 world
`...` 反引号,BASH 用户也经常用到。这里指的是执行反引号中命令输出的内容。
select 部分,这是一个可选的部分。与 list 部分相匹配的部分将被考虑到 completion 过程中。同时 figore 变量中的内容将被忽略。fignore 变量中的内容是你在完成中忽略掉的词。比如你设置。
> set fignore = (.bak)
> vi 按 CTRL-D 时,所有以 bak 为后缀的文件都不会被列在完成的可能性中。
上一段中的最后三种方式不能有 select 部分。
匹配 x 方式的时候,将使用 select 部分作为解释性的内容输出。
suffix 部分,顾名思义,后缀。为一个单独的字符。成功的 completion 后,suffix 指定的字符将被附加在后面。如果这部分为空,则什么都不加。如果这部分被忽略,则如果是目录其后将加上一个"/",文件被加上一个空格。
大写的 C D F T 与 c d f t 作用相似,但都以不同的方式使用 select 部分。要注意,它们要使用"@"字符来替代"/"分隔符,这是为了避免与 select 部分中出现的路径名中的"/"冲突。
好了,抄书也抄了不少,看起来乱七八糟一大堆。可能你对 TCSH 的 Programmable Completion 究竟是干什么的还一点概念都没有。也有可能被这些看起来有些复杂的东西吓着了。举些例子,大家就明白了,其实它非常容易设置,更非常容易使用。我写些可能的例子,由于是我现在写的,有可能有错误,要注意。
cd 命令后面的参数只跟目录名,cd 一个文件没有意义。那么我们就让 cd 来忽略所有的文件。
如果你在命令行手动执行 complete, 要注意引号。
> complete cd 'p/1/d/'
> cd 按 CTRL-D 看看,是不是当前目录中所有的文件都不在完成列表中?
上面那个完成规则的意思是,敲入 cd 空格,按 CTRL-D 的时候,列出可能的完成情况中只包含目录。使用 cd 的时候后一般只有一个参数,这个参数所对应的 p (position)数字就是 1。
set 是 TCSH 中设置变量的命令,我们要设置一个变量 i ,让它等于 5,则
> set i = 5
TCSH 中等号的两边是可以有空格的,这和BASH不同。
我们要再次改动 i 的值的时候,仍然需要使用 set 命令。
> complete set 'p/1/s/'
> set 按 CTRL-D 会自动列出所有的内部变量名字。这里我们指定按位置 p 完成,是因为变量后面的内容通常都是需要手动输入的,没有必要补全。
> set myname = "shannleon"
> set 按 CTRL-D 会列出所有内部变量
这个时候你再输入几个字符:
> set myn 按 TAB (complete-word 命令),则后面缺少的 "ame" 将被补全。
有了这个例子你可能想同时设置一下 unset 命令。这个命令是为了取消变量的。它后面的参数通常是一个 pattern。比如:
> unset *
这将取消所有内部变量!不要真的输入这个命令。我们经常做的只是取消某些自己的变量。这里要做的只是让它能够提示出我们可能的输入,省得敲那么多字符。
> complete unset 'n/*/s/'
匹配 unset 后面的所有参数。这样设置以后,我们在 unset i my 的时候按CTRL-D随时都可以得到一份列表,使用TAB就可以完成那些长的变量名。
mail 是个简单的邮件工具,在命令行使用的时候我们通常只希望后面跟用户的名字。比如给自己发封邮件
> complete 'n/*/u/'
让它随时给出一份用户名的列表。这样我在 mail sha 按TAB后,它将完成为 mail shannleon 。使用 n 和 * 可以让它后面跟一长串用户名,mail shannleon root js.yang 将不再需要敲那么多字符。
我们使用 mail 的时候通常都不是为了给自己发邮件,那么,把常用的邮件地址存在一个变量中。比如:
> set mailaddress = (shannleon@somedomain.com bush@whitehouse.gov mygirlfriend@herhome.com)
> complete mail 'n/*/$mailaddress/'
从此以后你发邮件它就可以自动完成后面那些长长的地址了。简单方便了很多吧。如果你的这些地址是存在一个文件中,那么就更好了。你可以用 AWK 这样的工具简单方便地挑选出地址,这时候 list 部分,你可以用反引号执行 AWK。
这个用法可以参考 chsh ,chsh --list-shells 将列出系统允许使用的 shell。
> complete chsh 'n/-s/`chsh --list-shells`/'
再输入 chsh -s CTRL-D 的时候,它给出的就是你需要的 shell 的路径了。注意 pattern 部分。我们第一次用到 completion 补全命令参数。
对于那些有着复杂参数的命令,比如 gnupg 。它长长的参数有时会让我们记忆困难。让 shell 替我们记住吧。
> complete gpg 'c/--/(sign clearsign encrypt decrypt armor ......)/' 'c/-/(s e a b ...)/'
这是什么意思?上面括号中的内容只是我省略了,因为它的参数实在太多了。
这个规则让我们在 gpg 后跟两个减号 -- (GNU 长参数)的时候,给出一个长参数的列表。而在使用一个减号 (POSIX 短参数)的时候给出那些单字符的参数。
complete 是可以同时接受很多不同规则的,但是,小心他们的顺序!!!规则的作用是从左到右,如果你将短参数放在长参数之前的话,长参数的作用规则将被覆盖掉,因为长规则的 pattern 中也有一个减号。
我们需要 gpg 的表现可能是这样:在使用短参数 -se 为普通文件加密的时候,忽略那些已经加密的文件(后缀通常为 .gpg .sig .asc),在解密的时候,忽略普通文件而显示那些已经加密的文件。
> complete gpg 'n/-s/f:^*.{gpg,sig,asc}/' 'n/--decrypt/f:*.{gpg,sig,asc}/' 'n/--/(sign clearsign ...)/' 'n/-/(s e a ...)/'
再次提醒一下,规则的顺序是最容易被你不小心忽略的问题。
不想再多写了,好像已经写了很长了。/usr/share/doc/tcsh-*/ 下有一个 completion.tcsh 文件,都是各种各样的完成规则,你有不明白的时候最好参考一下。当你对 TCSH 中的 Programmable Completion 熟悉了以后,你会发现你的 ~/.tcshrc 文件将变得越来越大,同时你也会理解为什么我现在已经开始用 RCS 版本控制来操作我的 ~/.tcshrc 文件了 ;-)
恩,还要提醒一下各位。在命令行操作 complete 的时候要注意引号,在 ~/.tcshrc 中设置的时候注意使用 set noglob 。否则会出错。在 ~/.tcshrc 中设置的时候一行写不下要用反斜杠“\”续行!!
为还没用过 TCSH 的朋友提供我自己的 ~/.tcshrc 的部分内容。有问题尽量 man tcsh 。写的非常清楚详尽。我的初始文件不是本机上传的,后面几十行的 completion 规则都没了。这些只是从记事本上抄的。强烈推荐各位好好看 TCSH 附带的规则。让你有种只有想不到没有做不到的感觉。
最后,有比较明白 BASH 中的 completion 的朋友麻烦指点小弟,我研究了两天没弄明白,感觉跟 TCSH 中的 complete 好像不是一回事。我其实是不想在 TCSH 这一棵树上吊死的。如果有朋友能告诉我如何把 TCSH 中的非常复杂的完成规则转换成 BASH 中的话,小弟这里先谢过了!!今天打死也不写了,以后再修改吧。。。
- # ~/.tcshrc
- # $Id: tcshrc,v 1.1.1.1 2006-09-12 19:49:52+08 shannleon Exp shannleon $
- ## TCSH OPTIONS
- set path = (/bin /usr/bin /usr/X11R6/bin)
- if( $uid == 0 ) set path = ($path /sbin /usr/sbin)
- set prompt = "[%n@%m %c]%# "
- set promptchars = '$#'
- set listjobs = long
- set symlinks = ignore
- set visiblebell
- set history = 1000
- set savehist = 1000
- set histdup = erase
- ## ENVIRONMENT VARIABLES
- setenv LESS "-e -r -Q"
- setenv LS_OPTIONS "-F -b -T 0 --color=auto"
- ## ALIASES
- unalias *
- alias helpcommand "\!:1 --help | less"
- alias ls "ls $LS_OPTIONS"
- alias v "ls -l"
- alias va "ls -la"
- alias du "du -h"
- alias df "df -T -h"
- if( $uid == 0 ) then
- alias cp "cp -i"
- alias mv "mv -i"
- alias rm "rm -i"
- endif
- ## KEY BINDINGS
- bindkey "^[[1~" beginning-of-line
- bindkey "^[[2~" quoted-insert
- bindkey "^[[3~" delete-char
- bindkey "^[[4~" end-of-line
- bindkey "^[[5~" undefined-key
- bindkey "^[[6~" undefined-key
- ## COMPLETIONS
- set noglob
- complete dd \
- c/[io]f=/f/ \
- c/{bs,[cio]bs}=/x:BYTES/ \
- c/{count,seek,skip}=/x:BLOCKS/ \
- c/conv=*,/"(ascii ebcdic ibm block unblock lcase notrunc ucase swab \
- noerror sync)"/,/ \
- c/conv=/"(ascii ebcdic .........同上)"/,/ \
- n/*/"(bs cbs conv count ibs if obs of seek skip)"/=/
- # 略去规则几十行 - -||
- unset noglob
- # EOF
复制代码 |
|