这篇文章的写作初衷在于,每当我换到一个新的工作岗位,或者需要改善我的工作环境时,我总觉得很难上手,因为我缺乏一个清晰的框架来管理我的 Shell 环境。我并不频繁地更新我的 Shell 设置,因此大部分时间里,我的设置可以说是静态的。
但当我想要做出调整时,总是需要重新去理解我的设置结构,使用Grep 等命令来查找需要的东西。

我重新组织了我的 cshell 环境,并将其应用到其他 shell 上,包括 bash、zsh 等。以下是组件列表。

文件组织结构
基于上述组件,我把功能分散到了下面的文件中。其中最重要的一个文件我称之为“入口文件”,其他功能的文件都会被这个入口文件所调用 。所以我们最关心的可能也就是入口文件,而不是我们具体有多少的功能文件,以及这些功能文件时怎么命名的。以下的目录命名以及结构是我当前觉得很实用,又符合我上面提到的架构规范的。
> tree ~/.mysh/
~/.mysh/
|-- alias.cshrc
|-- behavior.cshrc
|-- style.cshrc
|-- complete.cshrc
|-- corp.cshrc
|-- cshsub
| `-- myecho.csh
|-- my.cshrc
`-- share.cshrc
mysh.cshrc
is the entry file which sources other files ;behavior.cshrc
defines the ENV variables, controls the tools’ behaviors, etc. ;alias.cshrc
is the files that contains all the command aliases ;complete.cshrc
has the command completion for the current shell ;style.cshrc
defines color, font, etc. which define the emulator’s look ;cshsub
folder has the file that will be used as a function in csh environment ;share.cshrc
is a file that others can source directly to use your settings.
入口文件
通常,在一个新的环境中,新团队会将中心环境推送给每个个体。我们可以在中心环境的基础上进行构建或覆盖。因此,入口文件通常不是 .cshrc,而可能是 user.cshrc 或 .cshrc_user 等。
我们可能需要创建一个链接,让 .cshrc 来源于入口文件。像这样:
ln -s ~/.mysh/mysh.cshrc ~/.cshrc_user
别名设置
在不同的环境中,一些基础工具的安装可能会有所不同,我们可能还需要将路径添加到 $PATH 环境变量中。在这里,我使用了 corp.cshrc 中的一系列 “mysh.*” 命令来自定义本地基础工具的映射。
alias mysh.gvim '<Current Tool Path based on the Server Environment>'
alias mysh.vim '<Current Tool Path based on the Server Environment>'
alias mysh.jq '<Current Tool Path based on the Server Environment>'
alias mysh.python3.6 '<Current Tool Path based on the Server Environment>'
alias mysh.perl '<Current Tool Path based on the Server Environment>'
alias mysh.dot '<Current Tool Path based on the Server Environment>'
alias mysh.node '<Current Tool Path based on the Server Environment>'
alias mysh.lua '<Current Tool Path based on the Server Environment>'
alias mysh.git '<Current Tool Path based on the Server Environment>'
alias mysh.tmux '<Current Tool Path based on the Server Environment>'
alias mysh.sqlite3 '<Current Tool Path based on the Server Environment>'
alias mysh.tclsh8.6 '<Current Tool Path based on the Server Environment>'
alias mysh.wish8.6 '<Current Tool Path based on the Server Environment>'
alias mysh.display '<Current Tool Path based on the Server Environment>'
alias mysh.animate '<Current Tool Path based on the Server Environment>'
alias mysh.composite '<Current Tool Path based on the Server Environment>'
alias mysh.convert '<Current Tool Path based on the Server Environment>'
alias mysh.identify '<Current Tool Path based on the Server Environment>'
alias mysh.compare '<Current Tool Path based on the Server Environment>'
alias mysh.conjure '<Current Tool Path based on the Server Environment>'
alias mysh.montage '<Current Tool Path based on the Server Environment>'
alias mysh.jupyter '<Current Tool Path based on the Server Environment>'
alias mysh.rlwrap '<Current Tool Path based on the Server Environment> \!*'
alias mysh.wmctrl '<Current Tool Path based on the Server Environment>'
alias mysh.xterm '<Current Tool Path based on the Server Environment>'
alias mysh.meld '<Current Tool Path based on the Server Environment>'
命令自动完成
我们可以添加 git 自动补全或其他我们想要的自动补全功能。还有许多内部工具和实用程序,并不支持原生的自动补全功能。
分享我的设置
这个文件是可以被其他人使用或复制的文件,因此最好制作一些版本,比如 share_1.0.0.cshrc,并将最新的版本链接到 share.cshrc。
格式化输出
这种风格主要涉及背景、颜色代码、字体大小、字体系列等。
这些设置放在 style.cshrc 中。我们甚至可以将一些设置组合在一起,取一个像“主题”这样的名称。
其他功能设置
这设置了一些环境或工具设置,比如初始化 git 模式、姓名、电子邮件等。还有其他一些像全局变量 GREP 选项等。
Csh 中类似函数的功能
Cshell 没有函数功能,但我们可以使用 “source” 命令让命令表现得像一个函数。方法如下。
- 编写一个可以接受参数的 cshell 脚本
- 创建一个别名,并定义程序名称
setenv __MYSH_ROOT "~/.mysh"
alias myecho "source $__MYSH_ROOT/cshsub/myecho.csh --program myecho \!*"
现在在其他 cshell 或交互式 shell 中,我们可以像使用可执行脚本一样使用 myecho,而不是使 myecho.csh 可执行,source 将在当前 shell 中应用设置,但可执行程序可能在独立的 shell 中执行函数。
myecho -pcolor "blue" -prefix "MY-TEST" -color yellow "This is my message."
这是输出结果: MY-TEST: This is my message.
更多细节,请查看另一篇讨论如何制作类似 csh 函数的实用工具的文章。
#!/usr/bin/env tcsh -f
alias "mycshrc" 'unsetenv __MYTMP_RUN_MY_CSHRC ; set tmppwd = `pwd` ; cd ~/.my ; git pull ; cd $tmppwd ; source ~/.cshrc ; ' ;
setenv __MYSH_ROOT "~/.my/shellfiles" ;
setenv __MYTMP_RUN_MY_CSHRC 1 ;
setenv __MYSH_APPCFG_SETTING "~/.my/localfiles/my.json"
setenv __MYSH_SHARE_CSHRC "$__MYSH_ROOT/apple.share.cshrc"
#######################################
# Define the shell color code
#######################################
if (-r $__MYSH_ROOT/style.cshrc) then
source $__MYSH_ROOT/style.cshrc ;
else
set mycolor_e="`echo x | tr x '\033'`"
set mycolor_red="${mycolor_e}[31m"
set mycolor_green="${mycolor_e}[32m"
set mycolor_yellow="${mycolor_e}[33m"
set mycolor_blue="${mycolor_e}[34m"
set mycolor_magenta="${mycolor_e}[35m"
set mycolor_cyan="${mycolor_e}[36m"
set mycolor_white="${mycolor_e}[37m"
set mycolor_end="${mycolor_e}[0m"
endif
set mycolor_prefix_user = "${mycolor_yellow}USER-CSHRC${mycolor_end}" ;
###############################################################################
## For the comments and notes
## Please check the lines at the bottom
###############################################################################
setenv __MYSH_USERNAME `whoami`
setenv __MYSH_FULLNAME `finger $__MYSH_USERNAME | grep "Name:" | cut -d ":" -f 3 | sed 's/^\s*//g' | sed 's/\s*$//g'` ;
echo "\n${mycolor_prefix_user}: ${mycolor_green}============================================================================================${mycolor_end}"
echo "${mycolor_prefix_user}: Hi, $__MYSH_FULLNAME"
echo "${mycolor_prefix_user}: ${mycolor_blue} Loading my.cshrc in {$__MYSH_ROOT}: ${mycolor_end}"
################################################################################
# Put your script below
################################################################################
setenv __MYSH_PLATFORM `uname -m`
# Guess the home directory
set __MYSH_HOME=/user/$__MYSH_USERNAME
if ( -d $__MYSH_HOME ) setenv HOME $__MYSH_HOME
set __MYSH_HOME=/users/$__MYSH_USERNAME
if ( -d $__MYSH_HOME ) setenv HOME $__MYSH_HOME
set __MYSH_HOME=/home/$__MYSH_USERNAME
if -d $__MYSH_HOME ) setenv HOME $__MYSH_HOME
# Reset cshrc log
rm -fr ${__MYSH_HOME}/.cshrc.log
set cshlog=${__MYSH_HOME}/.log.cshrc
echo "" > $cshlog ;
#################################################################################
# Put your script above
#################################################################################
if (-e $__MYSH_HOME/.shell/behavior.cshrc) then
source $__MYSH_HOME/.shell/behavior.cshrc
else
echo "${mycolor_prefix_user}: Can not find $__MYSH_HOME/.shell/behavior.cshrc" ;
endif
if (-e $HOME/.shell/alias.cshrc) then
source $HOME/.shell/alias.cshrc
else
echo "${mycolor_prefix_user}: Can not find $__MYSH_HOME/.shell/alias.cshrc" ;
endif
if (-e $HOME/.shell/complete.cshrc) then
source $HOME/.shell/complete.cshrc
else
echo "${mycolor_prefix_user}: Can not find $__MYSH_HOME/.shell/complete.cshrc" ;
endif
if (-e $HOME/.shell/corp.cshrc) then
source $HOME/.shell/corp.cshrc
else
echo "${mycolor_prefix_user}: Can not find $__MYSH_HOME/.shell/corp.cshrc" ;
endif
unsetenv __MYTMP_RUN_MY_CSHRC ;
echo "${mycolor_prefix_user}: End loading cshrc"
echo "${mycolor_prefix_user}: ${mycolor_green}============================================================================================${mycolor_end}\n"
# vim: ft=csh foldmethod=marker