记录一些困扰很久的问题
先上百科解释,简而言之shell(壳)是相对kernel(内核)而言的,对于操作系统来说,shell暴露了一个接口给用户,用户可以通过这个接口调用操作系统的指令。shell的主要主要工作就是解释用户输入的命令或者执行用户按照shell语法写的文件。这样就诞生出来了好多shell程序,比如 bash/sh/ksh/csh(*nix)或者windows上的cmd.
Unix 系统上诞生了两个主要的shell血统 Bourne shell (包括 sh,ksh,and bash) 和 C shell (包括 csh and tcsh)
GNU 计划是很有意思的,是“GNU’s Not Unix”的递归缩写,因为当时Unix是一款商业的操作系统,然后就有人要造反做自由软件,他的倡导人是RichardStallman,最后最大的产出是Linux系统。
在mac系统上执行 ntop$ ls /bin/*sh
会看到mac已经自带了大部分的shell程序
/bin/bash /bin/ksh /bin/tcsh
/bin/csh /bin/sh /bin/zsh
刚刚分清了各种*sh,那shell/console/terminal又是什么东西呢,好像我们在平时使用的时候认为他们同一个东西,搜索之后发现了这里。
在过去terminal和console指硬件设备,现在的系统中他们都是一个软件。
iterm2 是 iterm 的升级版本,它和mac自带的terminal.app一样也是terminal(终端模拟器),但是它比自带的terminal多了很多功能,交互做的更好。oh-my-zsh 不是shell也不是terminal/console 它是一个zsh配置管理的框架(这要归功于zsh配置的灵活性,导致很多人为他写了很多个性化的配置,并形成了一个社区)。所以要想把自己的zsh搞得花花绿绿,可以直接配置一个oh-my-zsh主题就行了。
现在看来zsh在各方面已经完全超越其他的各种shell(但是在mac或者大部分系统上默认并不是zsh,abcdf…zsh 意指shell的尽头)。终端模拟器方面iterm2最好用了,但是本人不太喜欢它的图标。oh-my-zsh 是必须要有的因为我希望有高亮显示各种花花绿绿的关键词。
所以最后选择的方案是:zsh + oh-my-zsh
安装oh-my-zsh只需要一条命令,在官网上可以找到这条命令:curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh |
直接执行,然后重启终端 ———— 已经变彩色了!如果默认shell不是zsh在安装的过程中会提示把默认的shell设置成zsh。
其实本文最开始想写的就是环境变量的配置问题,因为不经常使用mac的缘故每次配置的时候都要在网搜索一番,然后看到有的要修改 ‘/etc/profile’ 有的要修改 ‘~/.profile’ 有的要修改 ‘~/.bashrc’。并且由于OS X系统版本的变迁和shell程序不同还会出现好多配置失效的情况,大部分情况下mac上的环境变量配置只能用一坨屎来形容。
如果打开了一个终端,最简单的方式配置环境变量是这样做,在中终端执行(以 Android adb 命令示例)
ntop$export PATH=$PATH:/Users/ntop/Library/Android/sdk/platform-tools
ntop$adb version
Android Debug Bridge version 1.0.32
但是这样做只能保持这次的环境变量配置只能维持在当前进程里面,如果关闭程序或者新开一个终端,这个设置就会失效(这显然不是我们想要的)。
在Windows上只要在高级设置里面配置环境变量就可以了,简单明了,但是在mac上官方是没有答案的,于是好多程序员开始研究了各种配置方式,从权限角度可以分全局配置(System-Wide)和用户配置(User-Wide)。全局配置的结果是每个用户都能共享配置,用户配置只能给当前配置了的用户使用。
修改‘/etc/profile’文件
这个文件可以配置好多东西,环境变量只是其中一项。
一般这个文件的配置如下
#Set file creation mask
unmask 022
#Tell me when new mail arrives
MAIL=/usr/mail/$LOGNAME
#Add my /bin directory to the shell search sequence
PATH=/usr/bin:/usr/sbin:/etc::
#Set terminal type
TERM=lft
#Make some environment variables global
export MAIL PATH TERM
在mac上打开这个文件可能内容和上面并不一样,不过没有关系,在文件最后加上一句 export PATH=$PATH:/Users/ntop/Library/Android/sdk/platform-tools
在我的系统上大概是这样的
➜ ~ cat /etc/profile
# System-wide .profile for sh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
export PATH=$PATH:/Users/ntop/Library/Android/sdk/platform-tools
新开一个终端,执行 adb shell
会打印 zsh: command not found: adb
, 恩,我们遇到了第一个坑,‘/etc/profile’ 只对bash有效对 zsh 是无效的(我在前面已经把默认的shell设置成了zsh)。可以通过 chsh -s /bin/bash
命令把终端的默认shell修改回bash,这时候再执行
ntop$ adb version
Android Debug Bridge version 1.0.32
It works!!!
修改‘/etc/paths’或‘/etc/paths.d/’
详细的解释见这里 大概意思就是如果你的’/etc/profile’文件中默认是这样写的
# System-wide .profile for sh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
那么 eval `/usr/libexec/path_helper -s`
这句话的意思是调用path_helper程序来设置环境变量,这个程序呢会寻找两个地方
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
直接把自己的环境变量路径加进去就行了。
ntop$ ls /etc/paths.d
go
ntop$ cat /etc/paths.d/go
/usr/local/go/bin
相对于修改 ‘/etc/paths’ 在 ‘/etc/paths.d/’ 下面添加一个文件来解决问题感觉更好一些,所以我做了如下配置
ntop$ ls /etc/paths.d
android go
ntop$ cat /etc/paths.d/android
/Users/ntop/Library/Android/sdk/platform-tools
但是无论是修改’/etc/paths’ 还是 ‘/etc/paths.d’ 都是只有在使用bash的时候才有生效,对于zsh来说都是无效的(呵呵)。
用户级别的配置大部分都是在修改 ~
目录下的配置文件,网上随便一搜,又是一大堆的配置文件,这些配置文件有的再 ~
目录下可以找到有的是找不到的,而且他们的配置针对的shell也不一样,下面逐一说明。
首先要看一下你用的是什么shell,执行 echo $SHELL
会打印当前的shell类型,如果是bash可以编辑下面三个文件,这三个文件也有坑,注意。
如果是csh配置 ‘~/.cshrc’ 如果是zsh配置’~/.zshrc’ (终于到了我自用的shell了)
这些文件在~
目录下未必会有,如果没有的话,需要自己创建,配置的语法都是一样的,关键是要看自己使用的shell是哪一种类型。
export PATH=$PATH:/Users/ntop/Library/Android/sdk/platform-tools
对于bash而言如果仅仅做一些简单的环境变量配置,去理解 ‘~/.profile’,’~/.bash_profile’ 和 ‘~/.bashrc’ 的不同,未免太过复杂,简而言之,可以这样配置。
对于前面描述的全局配置而言,只能作用于bash ,对于csh和zsh的全局配置目前还没有调研清楚,以后明白了再补充。
听了同事的建议,可以在 ‘.zshrc’ 文件中 source 一下 bash 的相关配置,比如:
source ~/.bashrc
最后我使用的zsh配置是这样的
➜ ~ cat .zshrc
....
# User configuration
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
# Android
export PATH=$PATH:/Users/ntop/Library/Android/sdk/platform-tools
# export MANPATH="/usr/local/man:$MANPATH"
source $ZSH/oh-my-zsh.sh
....