打造高效的工作环境 – SHELL 篇
注:本文由雷俊(Javaer/Emacser)和我一起编辑,所以文章版权归雷俊与我共同所有,转载者必需注明出处和我们两位作者。原文最早发于酷壳微信公众号,后来我又做了一些修改,再发到博客这边。
程序员是一个很懒的群体,总想着能够让代码为自己干活,他们不断地把工作生活中的一些事情用代码自动化了,从而让整个社会的效率运作地越来越高。所以,程序员在准备去优化这个世界的时候,都会先要优化自己的工作环境,是所谓“工欲善其事,必先利其器”。
我们每个程序员都应该打造一套让自己更为高效的工作环境。那怕就是让你少输入一次命令,少按一次键,少在鼠标和键盘间切换一次,都会让程序员的工作变得更为的高效。所以,程序员一般需要一台性能比较好,不会因为开了太多的网页或程序就卡得不行的电脑,还要配备多个显示器,一个显示器写代码,一个查文档,一个测试运行结果,而不必在各种窗口来来回回的切换……在大量的窗口间切换经常会迷路,而且也容易出错(分不清线上或测试环境)……
除了硬件上的装备,软件上也是能够提升程序员生产力的地方,在软件层面提升程序员生产力的东西有一个很重要的事就是命令行和脚本,使用鼠标和图形界面则会大大降低程序员的生产力。酷壳以前也写过一些,如《你可能不知道的Shell》和《 应该知道的Linux技巧》,但是Unix/Linux Shell就是一个大宝库,怎么写也写不完,不然,怎么会有“Where is the Shell, there is a way”。
命令行
在不同的操作系统下,都有着很不错的命令行工具,比如 Mac 下的 Iterm2,Linux 下的原生命令行,如果你是在 Windows 下工作,问题也不大,因为 Windows 下现在有了 WSL。WSL 提供了一个由微软开发的Linux兼容的内核接口(不包含Linux内核代码),然后可以在其上运行GNU用户空间,例如 Ubuntu,openSUSE,SUSE Linux Enterprise Server,Debian和Kali Linux。这样的用户空间可能包含 Bash shell 和命令语言,使用本机 GNU/Linux 命令行工具(sed,awk 等),编程语言解释器(Ruby,Python 等),甚至是图形应用程序(使用主机端的X窗口系统)。
使用命令行可以完成所有日常的操作,新建文件夹(mkdir)、新建文件(touch)、移动(mv)、复制(cp)、删除(rm)等等。而且使用 Linux/Unix 命令行最好的方式是可以用 awk、sed、grep、xargs、find、sort 等等这样的命令,然后用管道把其串起来,就可以完成一个你想要的功能,尤其是一些简单的数据统计功能。这是Linux命令行不可比拟的优势。比如:
- 查看连接你服务器 top10 用户端的 IP 地址:
netstat -nat | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c | sort -rn | head -n 10
- 查看一下你最常用的10个命令:
cat .bash_history | sort | uniq -c | sort -rn | head -n 10 (or cat .zhistory | sort | uniq -c | sort -rn | head -n 10
(注:awk 和 sed 是两大神器,所以,我以前的也有两篇文章来介绍它们——《awk简明教程》和《sed简明教程》,你可以前往一读)
在命令行中使用 alias 可以将使用频率很高命令或者比较复杂的命令合并成一个命令,或者修改原生的命令。
下面这几个命令,可能是你天天都在敲的。所以,你应该设置成 alias 来提高效率
|
1
2
3
4
5
6
7
8
9
|
alias nis="npm install --save "alias svim='sudo vim'alias mkcd='foo(){ mkdir -p "$1"; cd "$1" }; foo 'alias install='sudo apt get install'alias update='sudo apt-get update; sudo apt-get upgrade'alias ..="cd .."alias ...="cd ..; cd .."alias www='python -m SimpleHTTPServer 8000'alias sock5='ssh -D 8080 -q -C -N -f user@your.server' |
你还可以参考如下的一些文章,看看别人是怎么用好 alias 的
- 30 Handy Bash Shell Aliases For Linux / Unix / Mac OS X
- What are your favorite bash aliases?
- 23 Handy Bash Shell Aliases For Unix, Linux, and Mac OS X
- A few more of my favorite Bash aliases
命令行中除了原生的命令之外,还有很多可以提升使用体验的工具。下面罗列一些很不错的命令,把原生的命令增强地很厉害:
- fasd 增强了
cd命令 。 - bat 增强了
cat命令 。如果你想要有语法高亮的cat,可以试试 ccat 命令。 - exa 增强了
ls命令,如果你需要在很多目录上浏览各种文件 ,ranger 命令可以比cd和cat更有效率,甚至可以在你的终端预览图片。 - fd 是一个比
find更简单更快的命令,他还会自动地忽略掉一些你配置在.gitignore中的文件,以及.git下的文件。 - fzf 会是一个很好用的文件搜索神器,其主要是搜索当前目录以下的文件,还可以使用
fzf --preview 'cat {}'边搜索文件边浏览内容。 grep是一个上古神器,然而,ack、ag 和 rg 是更好的grep,和上面的fd一样,在递归目录匹配的时候,会使用你配置在.gitignore中的规则。rm是一个危险的命令,尤其是各种rm -rf …,所以,trash 是一个更好的删除命令。man命令是好读文档的命令,但是man的文档有时候太长了,所以,你可以试试 tldr命令,把文档上的一些示例整出来给你看。- 如果你想要一个图示化的
ping,你可以试试 prettyping 。 - 如果你想搜索以前打过的命令,不要再用 Ctrl +R 了,你可以使用加强版的 hstr 。
- htop 是 top 的一个加强版。然而,还有很多的各式各样的top,比如:用于看IO负载的 iotop,网络负载的 iftop, 以及把这些top都集成在一起的 atop。
- ncdu 比 du 好用多了用。另一个选择是 nnn。
- 如果你想把你的命令行操作建录制成一个 SVG 动图,那么你可以尝试使用 asciinema 和 svg-trem 。
- httpie 是一个可以用来替代
curl和wget的 http 客户端,httpie支持 json 和语法高亮,可以使用简单的语法进行 http 访问:http -v github.com。 - tmux 在需要经常登录远程服务器工作的时候会很有用,可以保持远程登录的会话,还可以在一个窗口中查看多个 shell 的状态。
- Taskbook 是可以完全在命令行中使用的任务管理器 ,支持 ToDo 管理,还可以为每个任务加上优先级。
- sshrc 是个神器,在你登录远程服务器的时候也能使用本机的 shell 的 rc 文件中的配置。
- goaccess 这个是一个轻量级的分析统计日志文件的工具,主要是分析各种各样的 access log。
关于这些增加命令,主要是参考自下面的这些文章
- 10 Tools To Power Up Your Command Line
- 5 More Tools To Power Up Your Command Line (Part 2 Of Series)
- Power Up Your Command Line, Part 3
- Power Up Your Command Line
- Hacker Tools
Shell 和脚本
shell 是可以与计算机进行高效交互的文本接口。shell 提供了一套交互式的编程语言(脚本),shell的种类很多,比如 sh、bash、zsh 等。
shell 的生命力很强,在各种高级编程语言大行其道的今天,很多的任务依然离不开 shell。比如可以使用 shell 来执行一些编译任务,或者做一些批处理任务,初始化数据、打包程序等等。
现在比较流行的是 zsh + oh-my-zsh + zsh-autosuggestions 的组合,你也可以试试看。其中 zsh 和 oh-my-zsh 算是常规操作了,但是 zsh-autosuggestions 特别有用,可以超级快速的帮你补全你输入过的命令,让命令行的操作更加高效。
另外,fish 也是另外一个牛逼的shell,比如:命令行自动完成(根据历史记录),命令行命令高亮,当你要输入命令行参数的时候,自动提示有哪些参数…… fish在很多地方也是用起来很爽的。和上面的 oh-my-zsh 有点不分伯仲了。
你也许会说,用 Python 脚本或 PHP 来写脚本会比 Shell 更好更没有 bug,但我要申辩一下:
- 其一,如果你有一天要维护线上机器的时候,或是到了银行用户的系统(与外网完全隔离,而且服务器上没有安装 Python/PHP 或是他们的的高级库,那么,你只有 Shell 可以用了)。
- 其二,而且,如果要跟命令行交互很多的话,Shell 是不二之选,试想一下,如果你要去 100 台远程的机器上查access.log 日志中有没有某个错误,完成这个工作你是用 PHP/Python 写脚本快还是用 Shell 写脚本快呢?
所以,我们还要学会只使用传统的grep/awk/sed等等这些POSIX的原生的系统默认安装的命令。
当然,要写好一个脚本并不容易,下面有一些小模板供你参考:
处理命令行参数的一个样例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
while [ "$1" != "" ]; do case $1 in -s ) shift SERVER=$1 ;; -d ) shift DATE=$1 ;; --paramter|p ) shift PARAMETER=$1;; -h|help ) usage # function call exit ;; * ) usage # All other parameters exit 1 esac shiftdone |
命令行菜单的一个样例
#!/bin/bash
# Bash Menu Script Example PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
颜色定义,你可以使用 echo -e "${Blu}blue ${Red}red ${RCol}etc...." 进行有颜色文本的输出
|
1
2
3
4
5
6
7
8
9
10
11
|
RCol='\e[0m' # Text Reset# Regular Bold Underline High Intensity BoldHigh Intens Background High Intensity BackgroundsBla='\e[0;30m'; BBla='\e[1;30m'; UBla='\e[4;30m'; IBla='\e[0;90m'; BIBla='\e[1;90m'; On_Bla='\e[40m'; On_IBla='\e[0;100m';Red='\e[0;31m'; BRed='\e[1;31m'; URed='\e[4;31m'; IRed='\e[0;91m'; BIRed='\e[1;91m'; On_Red='\e[41m'; On_IRed='\e[0;101m';Gre='\e[0;32m'; BGre='\e[1;32m'; UGre='\e[4;32m'; IGre='\e[0;92m'; BIGre='\e[1;92m'; On_Gre='\e[42m'; On_IGre='\e[0;102m';Yel='\e[0;33m'; BYel='\e[1;33m'; UYel='\e[4;33m'; IYel='\e[0;93m'; BIYel='\e[1;93m'; On_Yel='\e[43m'; On_IYel='\e[0;103m';Blu='\e[0;34m'; BBlu='\e[1;34m'; UBlu='\e[4;34m'; IBlu='\e[0;94m'; BIBlu='\e[1;94m'; On_Blu='\e[44m'; On_IBlu='\e[0;104m';Pur='\e[0;35m'; BPur='\e[1;35m'; UPur='\e[4;35m'; IPur='\e[0;95m'; BIPur='\e[1;95m'; On_Pur='\e[45m'; On_IPur='\e[0;105m';Cya='\e[0;36m'; BCya='\e[1;36m'; UCya='\e[4;36m'; ICya='\e[0;96m'; BICya='\e[1;96m'; On_Cya='\e[46m'; On_ICya='\e[0;106m';Whi='\e[0;37m'; BWhi='\e[1;37m'; UWhi='\e[4;37m'; IWhi='\e[0;97m'; BIWhi='\e[1;97m'; On_Whi='\e[47m'; On_IWhi='\e[0;107m'; |
取当前运行脚本绝对路径的示例:(注:Linux下可以用 dirname $(readlink -f $0) )
|
1
2
3
4
5
6
7
|
FILE="$0"while [[ -h ${FILE} ]]; do FILE="`readlink "${FILE}"`"donepushd "`dirname "${FILE}"`" > /dev/nullDIR=`pwd -P`popd > /dev/null |
如何在远程服务器运行一个本地脚本
|
1
2
3
4
5
|
#无参数ssh user@server 'bash -s' < local.script.sh#有参数ssh user@server ARG1="arg1" ARG2="arg2" 'bash -s' < local_script.sh |
如何检查一个命令是否存在,用 which 吗?最好不要用,因为很多操作系统的 which 命令没有设置退出状态码,这样你不知道是否是有那个命令。所以,你应该使用下面的方式。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# POSIX 兼容:command -v <the_command># bash 环境:hash <the_command> type <the_command># 示例:gnudate() { if hash gdate 2> /dev/null; then gdate "$@" else date "$@" fi} |
然后,如果要写出健壮性更好的脚本,下面是一些相关的技巧:
- 使用
-e参数,如:set -e或是#!/bin/sh -e,这样设置会让你的脚本出错就会停止运行,这样一来可以防止你的脚本在出错的情况下还在拼拿地干活停不下来。 - 使用
-u参数,如:set -eu,这意味着,如果你代码中有变量没有定义,就会退出。 - 对一些变理,你可以使用默认值。如:
${FOO:-'default'} - 处理你代码的退出码。这样方便你的脚本跟别的命令行或脚本集成。
- 尽量不要使用
;来执行多个命令,而是使用&&,这样会在出错的时候停止运行后续的命令。 - 对于一些字符串变量,使用引号括起,避免其中有空格或是别的什么诡异字符。
- 如果你的脚有参数,你需要检查脚本运行是否带了你想要的参数,或是,你的脚本可以在没有参数的情况下安全的运行。
- 为你的脚本设置
-h和--help来显示帮助信息。千万不要把这两个参数用做为的功能。 - 使用
$()而不是 “ 来获得命令行的输出,主要原因是易读。 - 小心不同的平台,尤其是 MacOS 和 Linux 的跨平台。
- 对于
rm -rf这样的高危操作,需要检查后面的变量名是否为空,比如:rm -rf $MYDIDR/*如果$MYDIR为空,结果是灾难性的。 - 考虑使用 “find/while” 而不是 “for/find”。如:
for F in $(find . -type f) ; do echo $F; done写成find . -type f | while read F ; do echo $F ; done不但可以容忍空格,而且还更快。 - 防御式编程,在正式执行命令前,把相关的东西都检查好,比如,文件目录有没有存在。
你还可以使用ShellCheck 来帮助你检查你的脚本。
最后推荐一些 Shell 和脚本的参考资料。
各种有意思的命令拼装,一行命令走天涯:
下面是一些脚本集中营,你可以在里面淘到各种牛X的脚本:
- http://www.shelldorado.com/scripts/
- https://snippets.siftie.com/public/tag/bash/
- https://bash.cyberciti.biz/
- https://github.com/alexanderepstein/Bash-Snippets
- https://github.com/miguelgfierro/scripts
- https://github.com/epety/100-shell-script-examples
- https://github.com/ruanyf/simple-bash-scripts
甚至写脚本都可以使用框架:
- 写bash脚本的框架 https://github.com/Bash-it/bash-it
Google的Shell脚本的代码规范:
最后,别忘了几个和shell有关的索引资源:
- https://github.com/alebcay/awesome-shell
- https://github.com/awesome-lists/awesome-bash
- https://terminalsare.sexy/
最后,如果你还有什么别的更好的玩的东西,欢迎在评论区留言,或是到 coolshellx/ariticles @ github 修改本文。

关注CoolShell微信公众账号可以在手机端搜索文章
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
打造高效的工作环境 – SHELL 篇的更多相关文章
- 打造高效前端工作环境 - tmux
打造高效前端工作环境 - tmux 前言 现在前端开发可不容易啊,先打开个VIM,然后再打开个lite-server,一不小心写个ES2015还要打开个gulp来做预编译,如果能把这么多个窗口放在一 ...
- 打造高效前端工作环境-tmuxinator
前言 虽然tmux能让我们方便组织工作环境,但每次重新打开会话时都需要手动重新创建窗口.窗格和执行各种程序,能不能像VS那样以工程为单位保存窗口.窗格和各种所需执行的程序的信息呢?tmuxinato ...
- [转载] 高效MacBook工作环境配置
原文: http://www.xialeizhou.com/?p=71 高效MacBook工作环境配置 发表于 2015 年 8 月 1 日 由 xialeizhou 本文记录整个配置过程,供新入手M ...
- [转载] 高效 MacBook 工作环境配置
原文: http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=208231200&idx=1&sn=8a76ddc56c1f ...
- 高效 MacBook 工作环境配置
转自:https://mp.weixin.qq.com/s/sloc6HgKcosXtWcbMB_5hA 工欲善其事,必先利其器,工具永远都是用来解决问题的,没必要为了工具而工具,一切工具都是为了能快 ...
- 高效 MacBook 工作环境配置,超实用!
作者:正鹏 & 隃墨 http://www.xialeizhou.com/?p=71 前言 工欲善其事,必先利其器,工具永远都是用来解决问题的,没必要为了工具而工具,一切工具都是为了能快速准确 ...
- Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境
我们开发安卓大多是使用Eclipse和安卓SDK中自带的安卓模拟器.当然,Google早就推出了自己的安卓开发环境——Android studio,在不久前,Google发布了Android Stud ...
- 打造你的办公环境-email篇
1. 配置安装 procmailr 和 getmail ///////////////////////////////// ignore the follow /////////////////// ...
- 安装完CentOS 7 Minimal之后,从头打造桌面工作环境
安装完CentOS 7 Minimal之后,从头打造桌面工作环境 U盘装CentOS 7 DVD版不能引导的解决办法 更改root密码 SSH登录 增加除root之外的常规用户 装完CentOS 7之 ...
随机推荐
- 2018-08 【bug汇总】
1. 问题描述:更细参数时更新失败. 报错信息:无报错信息,返回为成功. 问题分析:代码查看逻辑无问题.说明可能不是逻辑的问题,dubug查看发现,参数并没有传入进来,查看传递参数的requestBe ...
- CornerStone使用跳坑总结(陆续更新)
Cornerstone是专门为Mac用户设计的Subversion(SVN)的控制,使版本控制更加透明.cornerstone根Xcode相比,能够更好的忽略文件,所以除了项目经理第一次初始化项目的时 ...
- Grid 实现瀑布流布局
<!doctype html> <html> <head> <meta charset="utf-8"> </head> ...
- 2019嘉韦思杯线上初赛writeup
1 土肥原贤二 看到页面怀疑是sql注入,写了个4'进去就发生报错.could not to the database You have an error in your SQL syntax; ch ...
- 学习笔记DL007:Moore-Penrose伪逆,迹运算,行列式,主成分分析PCA
Moore-Penrose伪逆(pseudoinverse). 非方矩阵,逆矩阵没有定义.矩阵A的左逆B求解线性方程Ax=y.两边左乘左逆B,x=By.可能无法设计唯一映射将A映射到B.矩阵A行数大于 ...
- 17. Debuggers (调试器 5个)
反编译是安全研究的重要组成部分. 它将帮助您解剖Microsoft补丁,以发现他们无法告诉您的默认修复的错误,或更仔细地检查服务器二进制文件以确定为什么您的漏洞利用不起作用. 许多调试器都可用,但ID ...
- Sql 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突
导致问题原因为创建时,表所使用的排序规则不一致 解决办法: 在对比条件后增加 collate Chinese_PRC_90_CI_AI 的转义即可 如: where test1.FieldName = ...
- day-06数据类型与深浅拷贝
深浅拷贝 # 值拷贝:应用场景最多 ls = [1, 'abc', [10]] ls1 = ls # ls1直接将ls中存放的地址拿过来# ls内部的值发生任何变化,ls1都会随之变化 ls2 = l ...
- edgedb 内部pg 数据存储的探索 (四) 源码编译
edgedb 基于python开发,同时源码重包含了好多子项目,以下进行简单的源码编译 clone 代码 需要递归处理,加上recursive,比较慢稍等 git clone --recursiv ...
- The Best Books on Game Dev
https://www.goodreads.com/list/show/99288.The_Best_Books_on_Game_Dev