Custom shell script

shell重度用户的一些分享

环境

Terminal+zsh,安装zsh后.zshrc.pre-oh-my-zsh 用于迁移之前的shell配置,该文件也用于保存和自定义脚本。
实际使用中我更倾向于在当前机器上新建一个配置集合git仓库,写一个copy脚本,把散落在设备上各目录下的配置文件或自定义脚本收集起来统一管理,一段时间后copy并上传到git保存,久而久之就形成了自己最顺手的工具集

简诉指令来由

很多指令都是开发中需要用到的,总是在命令行敲就很麻烦,git相关的指令都进行了精简,一部分是参考了zsh的git插件alias,一部分则是自己定义的。
指令包括:git操作集,adb操作集,路径操作集

git操作集

平时工作中用得最多的就是git相关指令,本人喜欢用shell操作git,一般只有在review的时候才会使用gui,所以基本开发中涉及到提交,切换,submodule处理等都是通过指令来完成。

gsb

配置文件中包含了下面这一串奇怪的gsb指令,在处理submodule的时候总是需要切换相关分支,但是每次都键入很长的指令,就算有history也要手输一长串,所以用下面的方法自定义后只需要gsb就能列出指令说明,不用去记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#gsb 所有gsb开头的指令都是git submodule相关指令
alias gsb='cat ~/.zshrc.pre-oh-my-zsh|grep '"'"'^#gsb'"'"' '
#gsb-dev: 切换kt-smart和相关module到dev分支,并update
alias gsb-dev='gck dev && gsf gck dev && gsu'
#gsb-master: 切换kt-smart和相关module到master分支,并update
alias gsb-master='gck master && gsf gck master && gsu'
#gsb-check: 检查当前所有模块所在分支
alias gsb-check='gsf gb'
#gsb-checkout-dev: 检查当前所有模块的dev分支,自动从远端创建关联的本地dev分支
alias gsb-checkout-dev='gck -b dev origin/dev && gsf -b dev origin/dev'
#gsb-pull: 对所有module执行pull指令,拉去并合并最新代码
alias gsb-pull='gf && gsf gf'
#gsb-status: 对所有module执行status指令
alias gsb-status='gst && gsf gst'

adb

adb的相关alias没什么好说的,主要看一下function中的部分定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# use the devices with number
adbd(){
if [[ -z $1 ]] {
STH_ADB_DEVICE=$(adb devices -l |grep device|awk -F: '"'"'{if(NR>1){print $4" ===> "FNR-1}}'"'"')
[[ -n $ANDROID_SERIAL ]] && echo "Used: ===> $ANDROID_SERIAL"
echo "$STH_ADB_DEVICE"
} else {
STH_ADB_TARGET=`expr $1 + 1`p
export ANDROID_SERIAL=$(adb devices|awk -F "[[:space:]]" '"'"'{print $1}'"'"'|sed -n $STH_ADB_TARGET)
STH_ADB_DEVICE_MODEL=$(adb devices -l |awk -F '"'"'[[:space:]]+'"'"' '"'"'{print $5}'"'"'|sed -n $STH_ADB_TARGET|awk -F: '"'"'{print $2}'"'"')
echo "Use device: $STH_ADB_DEVICE_MODEL serial: $ANDROID_SERIAL"
}
};
# adb shell kill pid with package name
adbk(){
if [[ -z $1 ]] {
echo "please input package name!"
} else {
STH_ADB_KILL_PID=$(adb shell ps|grep $1|awk '"'"'{print $2}'"'"')
$(adb shell kill $STH_ADB_KILL_PID)
}
};

adbd 是对adb devices的解析,用于多设备的情况下在shell端设置要访问的Android设备
adbk 用于kill Android端应用,只需要匹配部分包名即可

路径操作集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# cd to path in child or in parent
cds(){
STH_CDS_FILES_FIND=0;
STH_CDS_FLINES=(`ls $PWD`)
for i ($STH_CDS_FLINES){
[[ $i == *$1* ]] && STH_CDS_FILES_FIND=1 && cd $i && break
}
if [[ $STH_CDS_FILES_FIND == 0 ]] {
STH_CDS_FILES_FIND=0;
STH_CDS_FLINES=(`ls $(dirname $PWD)`)
for i ($STH_CDS_FLINES){
[[ $i == *$1* ]] && cd "$(dirname $PWD)/$i" && break
}
}
};
# my custom directorys
mcd(){
STH_FLINES=(${(f)"$(<~/.mcd_path)"})
echo -e "\n===> how to use? \n .1 to use dir 1 \n s. to open dir\n"
for i ($STH_FLINES){
echo $i
sth_num=$i[(ws.:.)1]
sth_path=$i[(ws.:.)2]
[[ $sth_num[1] != "#" ]] && alias ".$sth_num"="cd $sth_path"
}
echo -e "\n"
};

cds 是对cd指令的拓展,我们使用中基本都是 ls,然后cd到路径,使用tab补全。这里就有一个问题,比如一个文件夹下面有很多按日期划分的文件夹,形如 2022-01-11 2022-01-12 2022-02-11,在tab补全时并不很智能,所以cds使用匹配在当前目录下查找要进入的文件夹,如果没找到再去上层目录查找,只要找到了就cd进去。好吧,其实这个功能我用的最多的情况是在多submodule之间快速切换。

mcd 这个指令需要在根目录下定义一个 .mcd_path 文件,每一行使用 aa:bb的形式分割,比如1:/usr/home 那么mcd会先输出文件内容,然后映射.1到后面的目录,所以只需要输入 .1就可以切换到其对应的目录,这个指令用于配置需要经常访问的文件夹。

完整配置

下面是我长期积累的部分配置,其中的指令基本都有使用,在有一些想法后微调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#Sth's MACOS zsh config
#Author: stanhe
#echo "$(date +"%Y-%m-%d %T %N") Init .bashrc start! "
alias function='func(){
#================= alias function start =====================
gitcreatePreStatus(){
sPath=$PWD/.git/hooks
if [[ -e "$sPath" && ! -e "$sPath/pre-status.sh" ]]
then
echo -e "#!/bin/bash\necho 'pre-status'" > $sPath/pre-status.sh;
chmod +x $sPath/pre-status.sh;
echo "Create pre-status in .git/hooks";
fi
};
# add git command pre-status
git(){
gPath=$PWD/.git/hooks/pre-status.sh
if [[ $# -ge 1 && "$1" == "pre" && -e "$gPath" ]]
then
command $gPath "$@";
else
command git "$@";
fi
};
my_test(){
echo "my test";
};
test1(){
echo "test1";
};
# switch branch for current and submodules.
checkoutSub(){
echo "switch $1 ...";
gck $1 && gsf gck $1;
echo "===end===";
};
# checkout new branch for current and submodules.
checkoutNewSub(){
echo "Create $1 ...";
gck -b $1 && gsf gck -b $1;
echo "===end===";
};
# delete current and submodules branch.
deleteBranch(){
echo "Delete $1 ...";
gb -d $1 && gsf gb -d $1;
echo "===end===";
};
# checkout current and submodules to master
checkoutMaster(){
echo "Checkout all modules to master...";
gckm && gsf gckm;
echo "===end===";
};

# cd to path in child or in parent
cds(){
STH_CDS_FILES_FIND=0;
STH_CDS_FLINES=(`ls $PWD`)
for i ($STH_CDS_FLINES){
[[ $i == *$1* ]] && STH_CDS_FILES_FIND=1 && cd $i && break
}
if [[ $STH_CDS_FILES_FIND == 0 ]] {
STH_CDS_FILES_FIND=0;
STH_CDS_FLINES=(`ls $(dirname $PWD)`)
for i ($STH_CDS_FLINES){
[[ $i == *$1* ]] && cd "$(dirname $PWD)/$i" && break
}
}
};
# my custom directorys
mcd(){
STH_FLINES=(${(f)"$(<~/.mcd_path)"})
echo -e "\n===> how to use? \n .1 to use dir 1 \n s. to open dir\n"
for i ($STH_FLINES){
echo $i
sth_num=$i[(ws.:.)1]
sth_path=$i[(ws.:.)2]
[[ $sth_num[1] != "#" ]] && alias ".$sth_num"="cd $sth_path"
}
echo -e "\n"
};
# gck -n
gckn(){
if [[ -z $1 ]] {
echo " ===> please input branch number !"
} else {
TARGET_BRANCH=$1p
git checkout $(git branch | sed -n $TARGET_BRANCH)
}
};
# git check status by number
gdn(){
if [[ -z $1 ]] {
STH_GIT_DIFF=$(git status|grep '"'"'modified: '"'"'|awk -F: '"'"'{print $2" ===> "FNR}'"'"')
echo "$STH_GIT_DIFF"
} else {
STH_GIT_TARGET=$1p
git diff $(echo "$STH_GIT_DIFF"|sed -n $STH_GIT_TARGET|awk -F"===>" '"'"'{print $1}'"'"')
}
};
# use the devices with number
adbd(){
if [[ -z $1 ]] {
STH_ADB_DEVICE=$(adb devices -l |grep device|awk -F: '"'"'{if(NR>1){print $4" ===> "FNR-1}}'"'"')
[[ -n $ANDROID_SERIAL ]] && echo "Used: ===> $ANDROID_SERIAL"
echo "$STH_ADB_DEVICE"
} else {
STH_ADB_TARGET=`expr $1 + 1`p
export ANDROID_SERIAL=$(adb devices|awk -F "[[:space:]]" '"'"'{print $1}'"'"'|sed -n $STH_ADB_TARGET)
STH_ADB_DEVICE_MODEL=$(adb devices -l |awk -F '"'"'[[:space:]]+'"'"' '"'"'{print $5}'"'"'|sed -n $STH_ADB_TARGET|awk -F: '"'"'{print $2}'"'"')
echo "Use device: $STH_ADB_DEVICE_MODEL serial: $ANDROID_SERIAL"
}
};
# adb shell kill pid with package name
adbk(){
if [[ -z $1 ]] {
echo "please input package name!"
} else {
STH_ADB_KILL_PID=$(adb shell ps|grep $1|awk '"'"'{print $2}'"'"')
$(adb shell kill $STH_ADB_KILL_PID)
}
};
# check network connection
sth_netstat(){
STH_NET_BACK_CODE=$(curl -I -s --connect-timeout 3 www.baidu.com|head -n 1|awk -F "[[:space:]]" '"'"'{print $2}'"'"')
if [[ "$STH_NET_BACK_CODE" == 200 ]] {
echo "Can access network..."
} else {
echo "Access network Error!"
}
};
# ssh my pi
sshpi(){
if [[ -z $1 ]] {
echo " ===> please input the port number !"
} else {
ssh -p $1 pi@1.tcp.cpolar.cn
}
};
# open a file with file browser
s.(){
if [[ -z $1 ]] {
open ./
} else {
open $1
}
};
# create qrcode
qr(){
if [[ -z $1 ]] {
echo " ===> please input the qrcode string !"
} else {
echo $1 |curl -F-=\<- qrenco.de
}
};
#================= alias function end =====================
};func'

#================= custom alias =====================
#alias sth_alias_gdn_cmd1='git status|grep '"'"'modified: '"'"'|awk -F: '"'"'{print $2" ====> "FNR}'"'" simple for use ' in cmds
alias q='exit'
alias test='my_test'
alias t1='test1'
alias la='ls -lsah'
alias gaa='git add . && gst'
alias gii='git init'
alias gst='git status'
alias gsh='git stash'
alias gd='git diff'
alias gb='git branch'
alias gbs='gb && gsf gb'
alias gdc='git diff --cached'
alias gp='git push'
alias gpre='git pre'
alias gf='git pull'
alias gcmsg='git commit -m'
alias gcps='gitCreatePreStatus'
alias gl='git lg'
alias gck='git checkout'
alias gckm='git checkout master'
alias gcks='checkoutSub'
alias gckbs='checkoutNewSub'
alias gbds='deleteBranch'
alias gcksm='checkoutMaster'
#alias gcksm='gckm && gsf gckm'
alias gsf='git submodule foreach '
alias gsu='git submodule update '
#gsb 所有gsb开头的指令都是git submodule相关指令
alias gsb='cat ~/.zshrc.pre-oh-my-zsh|grep '"'"'^#gsb'"'"' '
#gsb-dev: 切换kt-smart和相关module到dev分支,并update
alias gsb-dev='gck dev && gsf gck dev && gsu'
#gsb-master: 切换kt-smart和相关module到master分支,并update
alias gsb-master='gck master && gsf gck master && gsu'
#gsb-check: 检查当前所有模块所在分支
alias gsb-check='gsf gb'
#gsb-checkout-dev: 检查当前所有模块的dev分支,自动从远端创建关联的本地dev分支
alias gsb-checkout-dev='gck -b dev origin/dev && gsf -b dev origin/dev'
#gsb-pull: 对所有module执行pull指令,拉去并合并最新代码
alias gsb-pull='gf && gsf gf'
#gsb-status: 对所有module执行status指令
alias gsb-status='gst && gsf gst'
alias gci='git commit'
alias grh='git reset --hard '
alias gr='git restore '
alias grs='git restore --staged '
alias ggrep='git grep -n '
alias adbi='adb shell input text' # action input
alias adbh='adb shell input keyevent 3' # action home
alias adbb='adb shell input keyevent 4' # action back
alias adbn='adb shell input keyevent 61' # action next
alias adbe='adb shell input keyevent 66' # action enter
alias adbdd='adb shell input keyevent 67' # action delete
alias adbwd='adb shell svc wifi disable' # disable wifi
alias adbwe='adb shell svc wifi enable' # enable wifi
alias adbfd='adb shell settings put global airplane_mode_on 0' # close airplane mode
alias adbfe='adb shell settings put global airplane_mode_on 1' # open airplane mode
alias adbne='adbwe && adbfd' # enable net
alias adbnd='adbwd && adbfe' # disable net
alias adbr='adb reboot' # reboot machine
alias adbl='adb shell ls' # ls
alias adbg='adb shell ps | grep '
alias adbbc='adb shell am broadcast -a ' # eg: adb shell am broadcast -a com.android.test --es test_string “this is test string” --ei test_int 100 --ez test_boolean true
alias adbsa='adb shell am start -n ' # start activity pkg/.activity
alias alg='adb logcat | grep --color=auto ' #adb logcat grep file
alias adbsh='scrcpy -b8M -m1920 --window-x 800 --window-y 100 --window-width 800 --window-height 450 &'
alias adbsv='scrcpy -b8M -m1400 --window-x 800 --window-y 100 --window-width 450 --window-height 800 &'

# tmux session
alias txsn='tmux new -s '
alias txsd='tmux detach'
alias txsl='tmux ls'
alias txsa='tmux attach -t '
alias txsk='tmux kill-session -t '
alias txss='tmux switch -t '
# tmux window
alias txwi='tmux split-window'
alias txws='tmux split-window -h'
alias txpu='tmux select-pane -U'
alias txpd='tmux select-pane -D'
alias txpl='tmux select-pane -L'
alias txpr='tmux select-pane -R'
alias txps='tmux swap-pane -d '

# system
#alias s.='open ./'
alias t.='open ./ -a Terminal.app'

function

zmodload zsh/mapfile

export PATH="$PATH:/Users/user/.tools"

#echo "$(date +"%Y-%m-%d %T %N") Init .bashrc end! "