不要问你的 shell 点文件能为你做什么,而是问 shell 点文件能为你做什么!
我使用过各种操作系统,但过去几年我的主力机都是 Mac。很长一段时间,我都在使用 Bash,但当一些朋友开始宣传 zsh 时,我尝试了一下。 我很快就喜欢上了它,几年后,我非常喜欢它,因为它做了很多小事情。
我一直在使用 zsh(通过 Homebrew 提供,而不是系统安装的)和 Oh My Zsh 增强。
本文中的示例适用于我的个人 .zshrc
。 大多数可以直接在 Bash 中工作,并且我不认为任何示例依赖于 Oh My Zsh,但结果可能会有所不同。 我曾经维护一个用于 zsh 和 Bash 的 shell 点文件,但我最终放弃了我的 .bashrc
。
我们都疯了
如果你希望跨操作系统使用同一个点文件,你需要让你的点文件有点智能。
### Mac Specifics
if [[ "$OSTYPE" == "darwin"* ]]; then
# Mac-specific stuff here.
fi
例如,我希望 Alt + 箭头键按单词而不是单个空格移动光标。 为了在 iTerm2(我首选的 shell)中实现这一点,我将此代码片段添加到我的 .zshrc 的 Mac 特定部分
### Mac Specifics
if [[ "$OSTYPE" == "darwin"* ]]; then
### Mac cursor commands for iTerm2; map ctrl+arrows or alt+arrows to fast-move
bindkey -e
bindkey '^[[1;9C' forward-word
bindkey '^[[1;9D' backward-word
bindkey '\e\e[D' backward-word
bindkey '\e\e[C' forward-word
fi
Bob 怎么样?
虽然我爱上了我的 shell 点文件,但我并不总是希望在我的家用机器上和工作机器上使用相同的东西。 一种解决方案是拥有补充点文件,用于在家中使用,而不是在工作中使用。 这是我如何完成的
if [[ `egrep 'dnssuffix1|dnssuffix2' /etc/resolv.conf` ]]; then
if [ -e $HOME/.work ]
source $HOME/.work
else
echo "This looks like a work machine, but I can't find the ~/.work file"
fi
fi
在这种情况下,我以我的工作 DNS 后缀(或多个后缀,取决于你的情况)作为键,并获取一个单独的文件,这让我在工作中的生活变得更好。
你做的那件事
现在可能是一个好时机,在编写脚本时停止使用波浪号(~
)来表示你的主目录。 你会发现有些情况下它无法识别。 养成使用环境变量 $HOME
的习惯可以为你节省大量的故障排除时间和头痛。
一个合理的扩展是拥有特定于操作系统的点文件,如果你愿意,可以包含它们。
记忆,独自在月光下
我已经编写了大量令人尴尬的 shell 脚本,并且我得出的结论是,我真的不想再编写更多了。 并不是 shell 在大多数情况下不能满足我的需求,但我发现如果我在编写 shell 脚本,我可能只是在拼凑一个胶带解决方案,而不是永久性地解决问题。
同样,我讨厌记住事情,并且在我的职业生涯中,我不得不在一天中进行彻底的上下文切换。 实际后果是,多年来我不得不重新学习很多东西。 (“等等……这种语言使用哪种 for 循环结构?”)
所以,每隔一段时间,我就会决定我厌倦了再次查找如何做某事。 我改善生活的一种方式是添加别名。
对于任何使用系统的人来说,一个常见的场景是找出是什么占用了所有磁盘空间。 不幸的是,我一直无法记住这个咒语,所以我创建了一个 shell 别名,创造性地称为 bigdirs
alias bigdirs='du --max-depth=1 2> /dev/null | sort -n -r | head -n20'
虽然我可以少偷懒并实际记住它,好吧,那根本不是 Unix 的方式...
错字,以及喜欢它们的人
使用 shell 别名改善我生活的另一种方式是让我免于错字。 我不知道为什么,但我已经养成了在序列 ea
之后输入 w
的坏习惯,所以如果我想清除我的终端,我经常会输入 cleawr
。 不幸的是,这对我的 shell 没有任何意义。 直到我添加了这个小金块
alias cleawr='clear'
在 Windows 拥有一个等效但更好的命令的一个例子中,我发现自己输入了 cls
。 看到你的 shell 举起双手令人沮丧,所以我添加了
alias cls='clear'
是的,我知道 ctrl + l
,但我从未使用过它。
逗自己开心
工作可能压力很大。 有时你只需要玩得开心。 如果你的 shell 不知道它显然应该 *只是做* 的命令,也许你想耸耸肩回应它! 你可以用一个函数来做到这一点
shrug() { echo "¯\_(ツ)_/¯"; }
如果这不起作用,也许你需要掀桌子
fliptable() { echo "(╯°□°)╯ ┻━┻"; } # Flip a table. Example usage: fsck -y /dev/sdb1 || fliptable
想象一下,当我需要掀桌子时,我却不记得我把它叫做什么时,我的懊恼和沮丧。 所以我添加了一些 shell 别名
alias flipdesk='fliptable'
alias deskflip='fliptable'
alias tableflip='fliptable'
有时你需要庆祝
disco() {
echo "(•_•)"
echo "<) )╯"
echo " / \ "
echo ""
echo "\(•_•)"
echo " ( (>"
echo " / \ "
echo ""
echo " (•_•)"
echo "<) )>"
echo " / \ "
}
通常,我会将这些命令的输出通过管道传输到 pbcopy
并将其粘贴到我正在使用的相关聊天工具中。
我从我关注的一个名为“命令行魔法”的 Twitter 帐户获得了这个有趣的函数: @climagic。 因为我现在住在佛罗里达州,所以我很高兴这是我生活中唯一的雪
snow() {
clear;while :;do echo $LINES $COLUMNS $(($RANDOM%$COLUMNS));sleep 0.1;done|gawk '{a[$3]=0;for(x in a) {o=a[x];a[x]=a[x]+1;printf "\033[%s;%sH ",o,x;printf "\033[%s;%sH*\033[0;0H",a[x],x;}}'
}
函数乐趣
我们已经看到了一些我使用的函数的例子。 由于这些例子很少需要参数,因此它们可以作为别名完成。 当它不仅仅是一个简短的语句时,我出于个人偏好使用函数。
在我的职业生涯的各个时期,我都运行过 Graphite,一种开源的、可扩展的时间序列指标解决方案。 我需要将指标路径(用句点分隔)转换为文件系统路径(用斜杠分隔),反之亦然,这已经足够多次了,因此为这些任务提供专用函数变得很有用
# Useful for converting between Graphite metrics and file paths
function dottoslash() {
echo $1 | sed 's/\./\//g'
}
function slashtodot() {
echo $1 | sed 's/\//\./g'
}
在我职业生涯的另一段时间,我运行了很多 Kubernetes。 如果你不熟悉运行 Kubernetes,你需要编写大量的 YAML。 不幸的是,编写无效的 YAML 并不难。 更糟糕的是,Kubernetes 在尝试应用 YAML 之前不会验证它,因此在你应用它之前你不会发现它是无效的。 除非你首先验证它
function yamllint() {
for i in $(find . -name '*.yml' -o -name '*.yaml'); do echo $i; ruby -e "require 'yaml';YAML.load_file(\"$i\")"; done
}
因为我厌倦了让自己难堪,偶尔还会破坏客户的设置,所以我编写了这个小代码片段,并将其作为 pre-commit hook 添加到我的所有相关存储库中。 类似的东西作为你的持续集成过程的一部分将非常有用,特别是如果你是团队合作。
哦,手指,你在哪里?
我曾经是一个优秀的盲打员。 那些日子已经一去不复返了。 我的错字比我原本认为的要多。
在不同的时间,我使用了相当多的 Chef 或 Kubernetes。 幸运的是,我从来没有同时使用过两者。
Chef 生态系统的一部分是 Test Kitchen,这是一套用于促进测试的工具,它通过命令 kitchen test
调用。 Kubernetes 使用 CLI 工具 kubectl
管理。 这两个命令都需要几个子命令,并且两者都不特别流畅地脱离手指。
与其创建一堆“错字别名”,不如将这些命令别名为 k
alias k='kitchen test $@'
或
alias k='kubectl $@'
时间分裂者
我职业生涯的后半部分涉及与其他人一起编写更多代码。 我曾在许多环境中工作,在这些环境中,我们在我们的帐户上分叉了存储库的副本,并使用拉取请求作为审查过程的一部分。 当我想确保我的给定存储库的分支与父存储库保持最新时,我使用 fetchupstream
alias fetchupstream='git fetch upstream && git checkout master && git merge upstream/master && git push'
我亲眼目睹了色彩降临的荣耀
我喜欢颜色。 它可以使 diff 等内容更易于使用。
alias diff='colordiff'
我认为彩色 man 页面是一个巧妙的技巧,所以我合并了这个函数
# Colorized man pages, from:
# http://boredzo.org/blog/archives/2016-08-15/colorized-man-pages-understood-and-customized
man() {
env \
LESS_TERMCAP_md=$(printf "\e[1;36m") \
LESS_TERMCAP_me=$(printf "\e[0m") \
LESS_TERMCAP_se=$(printf "\e[0m") \
LESS_TERMCAP_so=$(printf "\e[1;44;33m") \
LESS_TERMCAP_ue=$(printf "\e[0m") \
LESS_TERMCAP_us=$(printf "\e[1;32m") \
man "$@"
}
我喜欢命令 which
。 它只是告诉你你正在运行的命令来自文件系统中的哪个位置——除非它是一个 shell 函数。 在多个级联点文件之后,有时不清楚函数是在哪里定义的,或者它做了什么。 事实证明,whence
和 type
命令可以帮助解决这个问题。
# Where is a function defined?
whichfunc() {
whence -v $1
type -a $1
}
结论
我希望这篇文章能帮助并激励你找到改善日常使用 shell 的体验的方法。 它们不需要是巨大的、新颖的或复杂的。 它们可能会解决一个小的但频繁的摩擦,创建一个快捷方式,甚至提供一个减少常见错字的解决方案。
欢迎你浏览我的 dotfiles repo,但我警告你它可能需要大量的清理。 随意使用你发现有用的任何东西,请彼此善待。
1 条评论