Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • Mac

  • Windows

  • Linux

    • linux 下 PS1 命令提示符设置
    • Linux 下各文件夹的结构说明及用途介绍
    • Linux 运维人员最常用 150 个命令汇总
    • 实用的 bash 自定义脚本
      • 实用 alias 别名
      • 编写 shell 函数
        • 正则切换 Git 分支
        • 正则删除 Git 分支
        • 正则从远端检出 Git 分支
        • zsh 版 shell 函数
      • 参考资料
  • ShowyEdge
  • 开发效率提升之工具篇
  • 操作系统
  • Linux
Henry
2021-07-30
目录

实用的 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'
1
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
}
1
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
}
1
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
}
1
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]"
1

方法二:

echo -n "Are you sure to checkout and change branch to '$BRANCH' [Y/N]"
read REPLY
1
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
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]"
1

大功告成!

# 参考资料

  • 实用的 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)
编辑 (opens new window)
#PS1
上次更新: 5/27/2023, 1:02:05 PM
Linux 运维人员最常用 150 个命令汇总
ShowyEdge

← Linux 运维人员最常用 150 个命令汇总 ShowyEdge→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式