实用的 bash 自定义脚本
工作时间久了,发现越来越离不开 bash
自动化脚本了. bash
对于我们的便利体现的许许多多的微小的方面,用的好在工作效率的提升上可以说是"积小流而成江海".
# 实用 alias 别名
bash
的 alias
别名可以说是我用的最多的功能了,在我的理解看来,它就像是一个简单的函数,组合了一些繁琐的逻辑流程,对外只暴露一个优雅的别名。
alias ll='ls -l'
alias .='../'
alias ..='../../'
alias ...='../../../'
alias gl='git pull'
alias gaa='git add .'
alias gcmsg='git commit -m'
alias gcam='git commit -a -m'
alias gp='git push'
alias gco='git checkout'
alias gm='git merge'
alias gss='git status -s'
alias glol='git log –graph –pretty = format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit'
alias grh='git reset HEAD'
alias gba='git branch -a'
alias gcf='git config –list'
alias gcl='git clone –recursive'
alias gd='git diff'
alias ghh='git help'
alias ns='npm run serve'
alias nb='npm run build'
alias nd='npm run dev'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 编写 shell 函数
# 正则切换 Git 分支
切换分支的时候不想输入分支全名怎么办?怎样偷懒?当然是通过写正则来切换啦。
gcof() {
REGEX=$1
TARGET="$(git branch | grep -E $REGEX | grep -vx "\*.*" | head -n 1 | tr -d '[:space:]')"
if [[ -z $TARGET ]]; then
echo "Use regex '$REGEX' to match null"
else
echo "Use regex '$REGEX' to match branch '$TARGET'"
read -p "Are you sure to checkout branch '$TARGET' [Y/N]" -n 1 -s
echo # print blank line
if [[ $REPLY =~ ^[Yy]$ ]]; then
git checkout $TARGET
else
echo "Still on original branch"
fi
fi
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用方法:
假如现在有 3
个分支: master
, develop
和 feature/xxx
. 当前分支为 master
, 要切换到 develop
分支,输入 gcof de
回车,会提示你:
Use regex 'de' to match branch 'develop' Are you sure to checkout branch 'develop' [Y/y]
当我们输入 Y/y
后,就自动切换到 develop
分支啦
对于这种名字比较短的分支可能感觉提升效率的效果不明显,但对于有很多类似 feature/xxx
的分支,还是提升很大的,只需要输入几个字母就可以啦
# 正则删除 Git 分支
gbdf() {
REGEX=$1
TARGET="$(git branch | grep -E $REGEX | grep -vx "\*.*" | head -n 1 | tr -d '[:space:]')"
if [[ -z $TARGET ]]; then
echo "Use regex '$REGEX' to match null"
else
echo "Use regex '$REGEX' to match branch '$TARGET'"
read -p "Are you sure to delete branch '$TARGET' [Y/N]" -n 1 -s
echo # print blank line
if [[ $REPLY =~ ^[Yy]$ ]]; then
git branch -d $TARGET
else
echo "Still on original branch"
fi
fi
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 正则从远端检出 Git 分支
gcbf() {
REGEX=$1
TARGET="$(git branch -a | grep -E $REGEX | grep -vx "\*.*" | head -n 1 | tr -d '[:space:]')"
if [[ -z $TARGET ]]; then
echo "Use regex '$REGEX' to match null"
else
echo "Use regex '$REGEX' to match branch '$TARGET'"
BRANCH=${TARGET#*origin/}
read -p "Are you sure to checkout and change branch to '$BRANCH' [Y/N]" -n 1 -s
echo # print blank line
if [[ $REPLY =~ ^[Yy]$ ]]; then
git checkout -b $BRANCH origin/$BRANCH
else
echo "Still on original branch"
fi
fi
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# zsh 版 shell 函数
上面几个通过正则操作 git
的方法极大的提高了工作效率,但在 zsh
环境却报错了:
read:9: -p: no coprocess
这是因为:
在
zsh
中,-p
意味着从一个协程读取输入,而bash
则意味着一个提示,因此zsh
会报no coprocess
的错误。
The –p option doesn’t mean the same thing to bash’s read built-in command and zsh’s read built-in command. In zsh’s read command, –p means –– guess –– “Input is read from the coprocess.” I suggest that you display your prompt with echo or printf.
具体参见 read 在 zsh 和 bash 下的不同 - 哔哩哔哩 (opens new window) 和 ZSH: Read command fails within bash function "read:1: -p: no coprocess" - Super User (opens new window)
解决办法有两种:
将 read -p "Are you sure to checkout and change branch to '$BRANCH' [Y/N]" -n 1 -s
更改为:
方法一:
read "REPLY?Are you sure to checkout and change branch to '$BRANCH' [Y/N]"
方法二:
echo -n "Are you sure to checkout and change branch to '$BRANCH' [Y/N]"
read REPLY
2
虽然不报错,而且功能实现了,但这两种方法都有一个问题:当输入 y/Y/n/N
时,并不能自动往下执行代码,必须敲回车才可以
这是因为原命令 -n 1
帮我们自动截取
-n:用于限定最多可以有多少字符可以作为有效读入。例如 echo –n 4 value1 value2,如果我们试图输入 12 34,则只有前面有效的 12 3,作为输入,实际上在你输入第 4 个字符‘3’后,就自动结束输入。这里结果是 value 为 12,value2 为 3。
参见 Shell 中 read 的选项及用法_西溪漫步的博客-CSDN 博客_shell 中 read 的用法 (opens new window)
但这个是 bash
中的,zsh
中会报错:
not an identifier: -n
这时候再看大佬的回答有这么一句:
You may also need to replace –n 1 with –k or –k 1
让我们用 -k
代替 -n
, 那还说啥,走起!
read "REPLY?Are you sure to checkout and change branch to '$BRANCH' [Y/N]" -k 1
结果:
not an identifier: -k
什么情况,不是说替换一下就可以了吗?为什么还报错呢?
哦,原来人家 -k
是要写在 read
后面啊
参见 如何在 zsh 中读取 1 个符号? (opens new window)
-k [num]
只读一个 (或数字) 字符。所有都被分配到名字,没有分词。当-q 存在时,将忽略此标志。除非存在-u 或-p 之一,否则从终端读取输入。此选项也可以在 zle 小部件中使用。
而且人家默认就只读一个字符,所以那个 1
咱们也可以省略不写了
-s
如果从终端读取,请勿回显字符。目前不适用于-q 选项。
还有这个 -s
, 意思就是你输啥,终端也不显示,bash
也有这个参数,那咱们也加上
read -sk "REPLY?Are you sure to checkout and change branch to '$BRANCH' [Y/N]"
大功告成!
# 参考资料
- 实用的 bash 自定义脚本,快速提效工作流程 (opens new window)
- read 在 zsh 和 bash 下的不同 - 哔哩哔哩 (opens new window)
- ZSH: Read command fails within bash function "read:1: -p: no coprocess" - Super User (opens new window)
- Shell 中 read 的选项及用法_西溪漫步的博客-CSDN 博客_shell 中 read 的用法 (opens new window)
- 如何在 zsh 中读取 1 个符号? | (opens new window)
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05