MacBook Air上的bash升级

MacBook Air上的bash升级

  • MacBook Air上的bash升级
    • 为什么要升级
    • 如何升级
      • 下载最新的bash
      • 编译安装
      • 全局配置
      • 另一种方法
    • 配置bash
      • 自带命令参数补全
      • Git命令补全
      • bash颜色配置
        • ls
        • grep
        • 其它配色
      • 一些alias
        • 关于ls的
        • 关于git的
        • 一些零散的
        • function
      • Terminal字体
    • 最后总结不想学zhe习teng的直接看这里
    • 最后的最后
    • 终于大功告成啦

为什么要升级?

我输入bash --version后,可以得到:

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)
Copyright (C) 2007 Free Software Foundation, Inc.

在默认的MacBook Air上,会自带一个bash。可是,它的版本却偏老。

这不仅带来许多使用上的不便,例如命令参数补全(bash-completion不支持bash3.2),也有很多隐患。

我唯一值得欣慰的是,这个版本足以抵御Shellshock漏洞。

如何升级?

升级,方法就是下载最新的bash源码、编译、替换当前的bash,这三步。

当然,这还有个前提,你必须已经安装Xcode(关键是配套的Command line tools)了。
如果你连gitgcc都没有,那就没必要搞什么bash了。
此外,HomeBrew也是要有的,为了方便。

下载最新的bash

下载并解压:

curl https://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz -o ~/Downloads/bash-4.3.gz
tar xzf ~/Downloads/bash-4.3.gz -C ~/Downloads/

我当前最新的bash版本是4.3。可以在这里查看最新的版本。

编译、安装

cd ~/Downloads/bash-4.3
./configure && make && sudo make install

安装到这里就结束了。直接输入bash --version的结果,和刚才一样。但是重启、新建终端窗口、新建终端TAB页中,都可以得到新的结果。

全局配置

此时,终端用的用的bash,是在/usr/local/bin/bash的新安装bash。

如果要完全替代原bash,还需要更改/bin/bash

sudo mv /bin/bash /bin/bash3.2
sudo ln -s /usr/local/bin/bash /bin/bash

这一步,如果你只是在控制台敲命令,或者是使用bash bash_script的方式来执行脚本,那么可有可无。
但是,如果你需要用./bash_script或其它更复杂的使用方式,那么全局配置是必须的。
因为,你打开大多数bash脚本都可以在第一行看到:

#!/bin/bash

#!这个操作符,会把脚本解释器设置为/bin/bash。所以你将一会儿用旧的,一会儿用新的。
因此,更改链接是必须的。

(本节内容,受教于zrong’s Blog。)

另一种方法

brew install bash
sudo mv /bin/bash /bin/bash3.2
sudo ln -s /usr/local/Library/LinkedKegs/bash /bin/bash
  • 第一行,用Homebrew来安装bash。
  • 第二行,备份原bash。
  • 第三行,建立软链接。

和前面的区别,就是不用编译,直接安装,bash实体的放置位置有差异而已。

但是,我的水平虽然说不上什么不对,却不太喜欢这种太“方便”的做法。
brew本来就是依赖bash的命令行工具,如今反过来管理bash。总觉得不太稳妥。

如果你因为什么原因怒删brew,及其全部文件(包括/usr/local/Cellar下的bash实体)。那么/bin/bash这个死链,能否支撑你的terminal?

配置bash

Mac上的bash,如果不配置,不仅丑,而且难用。
即使换上最新的版本,也是如此。

自带命令参数补全

如果按TAB键,不能自动补全,那么bash和Windows下被人唾弃的CMD,还能有多大差距?

安装bash-completion

brew install bash-completion

然后在.bash_profile里,添加其相关配置:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi

在我的机器上,brew --prefix就是/usr/local
这样,bash的很多自带命令、大多brew安装的命令,就可以完美补全了。

Git命令补全

遗憾的是,此时Git仍然不能补全。

单独配置Git的补全:

curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash > ~/.git-completion.bash
echo "source ~/.git-completion.bash" >> .bash_profile
  • 第一句,单独把.git-completion.bash文件从Git在GitHub上的Git库里(嘿嘿)扒拉下来。或者,你也愿意把整个git库拉下来,然后执行cp
  • 第二句,把source配置写到.bash_profile里去。

重启、新开、或执行

source ~/.git-completion.bash

后,Git就可以补全啦!

bash颜色配置

ls

ls,可以在.bash_profile里,加入

export CLICOLOR=1
export CLICOLOR_FORCE=1
export LSCOLORS=gxfxaxdxcxegedabagacad
  • 第一句,打开ls命令的颜色。这句的作用,和alias ls='ls -G'类似。
  • 第二句,强制使输出在非控制台的地方也有颜色。这句的作用,在你把ls的结果作为输出,提供给类似grep这样的命令时,也保持原先的颜色。
  • 第三句,指定11种文件类型的不同颜色。颜色、文件类型见下两表:
字母 颜色 字母 带色粗体
a 黑色 A 黑色粗体
b 红色 B 红色粗体
c 绿色 C 绿色粗体
d 棕色 D 棕色粗体
e 蓝色 E 蓝色粗体
f 洋红色 F 洋红色粗体
g 青色 G 青色粗体
h 浅灰色 H 浅灰色粗体
第N个字母 代表的文件类型
1 directory
2 symbolic link
3 socket
4 pipe
5 executable
6 block special
7 character special
8 executable with setuid bit set
9 executable with setgid bit set
10 directory writable to others, with sticky bit
11 directory writable to others, without sticky bit

文件类型应该不需要翻译吧。(你确定翻译了你还认识?)

详见man ls,搜索color。

grep

grep,可以在.bash_profile里,加入

export GREP_OPTIONS='--color=always'

alias grep='grep --color'

能用环境变量配置的,不建议用alias

默认为高亮红色,可以通过修改

export GREP_COLOR='a;b'

来改变默认颜色。其中a填入数字,效果如下:

a 效果
0 关闭所有属性
1 设置高亮度
4 下划线
5 闪烁
7 反显
8 消隐

b填入数字,效果如下:

前景 后景 颜色
30 40 黑色
31 41 红色
32 42 绿色
33 43 黄色
34 44 蓝色
35 45 紫色
36 46 青色
37 47 白色

默认为1;31,即红色高亮

我喜欢

export GREP_COLOR='5;40'

黑底闪烁。
(话说,谁知道Markdown怎么设置“黑底闪烁”?)

其它配色

如果还有其它需要对显示结果配色的CMD,只需要查看man CMD并搜索color或option,按照以上方法,应该都能配置。

如果命令本身不支持配色,那就没办法了。

一些alias

alias如果过多,一般都会单独用一个文件来管理。
这里用.alias.bash,下面的alias都加入这个文件。

别忘了在.bash_profile里,要加一行

source .alias.bash
关于ls
alias ll='ls -hlF'
alias l.='ls -d .*'
alias lsf='ls -hl | grep -v ^d'
alias lsd='ls -hl | grep ^d'
alias lr='ls -R | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/   /'\'' -e '\''s/-/|/'\'''
  • ll是加强版ls,显示目录、文件的详细信息
  • l.仅显示隐藏文件、目录
  • lsf仅显示文件,不显示目录
  • lsd仅显示目录,不显示文件
  • lrtree的形式显示当前目录下的所有文件夹,不显示文件

以下是关于返回上级目录的:

alias ..='cd ..'
alias ...='cd ../../'
alias ....='cd ../../../'
alias .....='cd ../../../../'
alias ......='cd ../../../../../'
关于git
alias gl="git log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
alias glg='git log --graph --full-history --all --color --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"'
  • gl是不错的单行log展示形式
  • glg是有commit关系图形的形式,类似gitk
一些零散的
alias df='df -h'
alias rm='rm -i'
alias freq='cut -f1 -d" " ~/.bash_history | sort | uniq -c | sort -nr | head -n 30'
alias tm='ps -ef | grep'
  • 修改df为总是显示M或G等单位符号,提高可读性。类似的还有du,不过一般du都是要带参数的,我常用du -hd1du -hs,既然都要带参数,这个h就不用偷懒了。
  • rm -i会总是再提醒一次“是否删除”,安全一些。alias后,输入-f可以忽略提示。
  • freq会列出你最常用的30个命令。这个命令我也不常用,只是列在这里,随时学习这个多重管道。
  • tm后面加进程名称,例如tm firefox,可以找出其PID(第二列),以便kill
function

还有mcd和多功能解压extract。它俩只能用function来实现了。

function mcd() {
    mkdir -p "$1" && cd "$1";
}
extract () {
    if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2)   tar xjf $1     ;;
        *.tar.gz)    tar xzf $1     ;;
        *.bz2)       bunzip2 $1     ;;
        *.rar)       unrar e $1     ;;
        *.gz)        gunzip $1      ;;
        *.tar)       tar xf $1      ;;
        *.tbz2)      tar xjf $1     ;;
        *.tgz)       tar xzf $1     ;;
        *.zip)       unzip $1       ;;
        *.Z)         uncompress $1  ;;
        *.7z)        7z x $1        ;;
        *)     echo "'$1' cannot be extracted via extract()" ;;
         esac
     else
         echo "'$1' is not a valid file"
     fi
}

(更多详细信息,请参考《是时候展示真正的alias技术了》。)

Terminal字体

我的MacBook Air 11,默认的字体是Menlo 11pt
显然,对这么小的屏幕来说,这个字体太小了!

在很长的一段时间内,我用的都是Menlo 14pt。字形的辨识度很高,在VIM里能显示40行。

现在,在欣赏了Mac OS X 10.10自带的所有字体后,我还是更喜欢Monaco 13pt
13pt的它,和14pt的Menlo大小差不多,而且在我的视觉里,更可爱一些。

更改字体,在终端的【偏好设置】【描述文件】【文本】【字体】。

我没有尝试非自带字体,留待以后吧。

(更多字体信息,请参考10大最适合编程的字体或收听内核恐慌5·编程字体。)

最后总结(不想学zhe习teng的直接看这里)

上面的东西,如果你不想花时间看,那么把以下这段直接贴到Terminal就行了。
不过,需要注意的是:

  • 我只保证单句功能正确、总体逻辑正确。由于此时,我的bash已经通过上面的过程配置好了,当然不能再把下面的shell完整贴一遍。
  • 即使代码OK,但是没有加上if判断,所以,如果发生什么意外(如断网、下载失败等)而导致某一句执行错误,那么就悲剧了。
  • sudo两句,务必要确保前面都OK再执行
  • 你的gcc、git都没问题?你确定你连得上GitHub和gnu.org?

因此,在echo以上的这些命令,建议一行一行地贴。
两个echo不用担心,"$等符号都被转义了,可以正常写入.bash_profile.alias.bash

(嘿嘿,如果你是直接跳到这来看的,是不是心中一虚,又跳回去从头看?哇哈哈哈哈哈……^_^……)

一个完整带判断带异常处理的shell,只能等以后更新了。

shell如下:

这块建议逐行拷贝到Terminal。

bash --version
curl https://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz -o ~/Downloads/bash-4.3.gz
tar xzf ~/Downloads/bash-4.3.gz -C ~/Downloads/
cd ~/Downloads/bash-4.3
./configure && make && sudo make install
sudo mv /bin/bash /bin/bash3.2
sudo ln -s /usr/local/bin/bash /bin/bash
brew install bash-completion
curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash > ~/.git-completion.bash

如果上面执行都OK的话,可以配置文件了。

这块建议全部拷贝到Terminal中。切忌直接拷贝到文件,因为内含转义字符\"等。

echo "
# Setting bash-completion
if [ -f \$(brew --prefix)/etc/bash_completion ]; then
    . \$(brew --prefix)/etc/bash_completion;
fi

# Setting git completion
source ~/.git-completion.bash

# Persinal bash profile #

# ls
export CLICOLOR=1   #ls color
export CLICOLOR_FORCE=1
export LSCOLORS=gxfxaxdxcxegedabagacad  #ls color specific
# grep
export GREP_OPTIONS='--color=always'
export GREP_COLOR='5;40'

# alias
source ~/.alias.bash
" \
>> ~/.bash_profile

echo "\
#!/bin/bash

# alias

# ls
# List files and directories with human readable detailed infomation
alias ll='ls -hlF'
# Show hidden files only
alias l.='ls -d .*'
# Show files only
alias lsf='ls -hl | grep -v ^d'
# Show directories only
alias lsd='ls -hl | grep ^d'
# Recursive directory listing
alias lr='ls -R | grep \":\$\" | sed -e '\''s/:\$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/   /'\'' -e '\''s/-/|/'\'''

# Jump back n directories at a time
alias ..='cd ..'
alias ...='cd ../../'
alias ....='cd ../../../'
alias .....='cd ../../../../'
alias ......='cd ../../../../../'

# git
# Compact, colorized git log
alias gl=\"git log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit\"
# Visualise git log (like gitk, in the terminal)
alias glg='git log --graph --full-history --all --color --pretty=format:\"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s\"'

# Human readable df
alias df='df -h'
# rm will be more safe by reminding you if without -f behind
alias rm='rm -i'
# Show which commands you use the most
alias freq='cut -f1 -d\" \" ~/.bash_history | sort | uniq -c | sort -nr | head -n 30'
# Search for process
alias tm='ps -ef | grep'

# function
# mkdir and cd into
function mcd() {
    mkdir -p \"\$1\" && cd \"\$1\";
}
# extract files
extract () {
    if [ -f \$1 ] ; then
      case \$1 in
        *.tar.bz2)   tar xjf \$1     ;;
        *.tar.gz)    tar xzf \$1     ;;
        *.bz2)       bunzip2 \$1     ;;
        *.rar)       unrar e \$1     ;;
        *.gz)        gunzip \$1      ;;
        *.tar)       tar xf \$1      ;;
        *.tbz2)      tar xjf \$1     ;;
        *.tgz)       tar xzf \$1     ;;
        *.zip)       unzip \$1       ;;
        *.Z)         uncompress \$1  ;;
        *.7z)        7z x \$1        ;;
        *)     echo \"'\$1' cannot be extracted via extract()\" ;;
         esac
     else
         echo \"'\$1' is not a valid file\"
     fi
}
" \
> ~/.alias.bash

重启终端。

最后的最后

什么?你说iTem2+Zsh?

连这你都知道了,还看我这篇破文干什么?

o(╯□╰)o

稍微介绍下吧。

iTerm2是MacOS自带终端Terminal的替代品,也是iTerm的后继者。它要在 MacOS 10.5 (Leopard) 或以上的版本运行。iTerm2带着一堆你从不知道而又一直渴求的功能,把终端这种工具,推向新的时代!

——[iTem 2 官网](http://iterm2.com)

以上是我的翻译,将就着看吧。

iTerm2是Terminal的一个加强版高级替代品,打开【偏好设置】看一眼就明白了——这种Windows设置般的恐怖功能迷阵,蕴含着数量庞大的功能和巨大的可定制空间。

不过我暂时是不会用的,因为在我的列表里,还有一堆更高优先级的东西要去学zhe习teng。
此外还有一个巨大的痛点——全屏快捷键不能全屏!开发者根本不理解我这个买得起MacBook Air 11买不起Magic Mouse的艹民之心!

Z Shell(Zsh) 是一种Unix shell,它可以用作为交互式的登录shell,也是一种强大的shell脚本命令解释器。Zsh可以认为是一种Bourne shell的扩展,带有数量庞大的改进,包括一些bash、ksh、tcsh的功能。

——[Z shell - 维基百科](https://zh.wikipedia.org/wiki/Z_shell)

除了前面提过的学zhe习teng优先级以外,Zsh作为一个bash的替代品,是否值得学习,还有待商榷。

如果你时间宽裕,我建议二者都学;如果你和我一样日程很满,我建议你只学一种。

而如果只学一种,学习一个主流的bash,比一个非主流的Zsh,在大多数情况下减少很多麻烦。至少,你不用每遇到一个新的工作环境(公司工作站、网络服务器、虚拟机等),就要替换一次bash。

而且,很多情况下别无选择。
(你以为你能拿到root权限吗?)
(OK,你是管理员,你敢擅自把公用的Linux系统里的shell配置成Zsh吗?)

╮(╯_╰)╭

终于大功告成啦!

O(∩_∩)O~

你可能感兴趣的:(bash,MacBook,bash)