最近发现可以在终端的配置文件里写代码,在终端输入配置文件里的方法名,就能执行指定代码了,能实现Alfred的部分功能。 # 配置文件 我所用的终端的是**bash**,配置文件是“**.bash_profile**”,mac上配置环境变量就是修改此文件,此文件位于用户目录下,新系统或者没有配置过环境变量的,没有这个文件,则需要用命令创建。 以点号开头的文件默认是不可见的,在Finder(访达)中,按 “ **⌘ + ⇧ +** . ” 开启/关闭 显示隐藏文件。 例如我的用户名是“**hf**”,完整的路径就是 “**/Users/hf/.bash_profile**”,每次修改配置后 都要执行 `source ~/.bash_profile` 才会生效,下面是相关命令: ````bash # 创建配置文件,已存在时则会忽略 touch ~/.bash_profile # 用 文本编辑 查看和编辑 open -e ~/.bash_profile # 用 vim 查看和编辑 # vim ~/.bash_profile # 更新配置,每次编辑过配置后,都要执行一次才能生效 source ~/.bash_profile ```` # 语法 现在我有个想法,在终端中**输入 bp 后按Enter键 打开配置文件**,**输入 sp 后按Enter键 更新配置文件**,配置文件是这样的: ````bash # 打开 配置文件 bp() { open -e "$HOME/.bash_profile" } # 更新 配置文件 sp() { source "$HOME/.bash_profile";} ```` 上面的 “**$HOME**” 和 “**~**” 是等价的。 语句可以合并成单行,但需要特别注意格式: - 尖括号和方法名之间,需要至少有一个空格; - 代码起始位置 和尖括号之间,需要有一个空格; - 代码结尾位置 和尖括号之间,要有一个分号; - 多行代码之间用分号隔开; ![image](https://upload-images.jianshu.io/upload_images/1390773-95a37045e44dc9fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 我经常忘了写结尾的分号,更新配置时会报语法错误,错误提示中不会告诉你错在哪一行,下面的提示中的519实际是 **.bash_profile** 文件的总行数,而不是有语法错误的地方。有时写high了,报这个错误,就是一脸懵。所以适当的备份配置文件可以避免翻车。 `bash: /Users/hf/.bash_profile: line 519: syntax error: unexpected end of file;` 由于点号文件备份不方便,于是在配置中,加了这些。 - 终端输入**backbp**(然后按Enter键)将配置备份成 **backup.bash_profile**; - 终端输入 **restorebp**(然后按Enter键)将备份配置还原成 **.bash_profile**; ```bash # 备份配置 backbp() { cp -f "$HOME/.bash_profile" "$HOME/backup.bash_profile";} # 还原配置 restorebp() { cp -f "$HOME/backup.bash_profile" "$HOME/.bash_profile"; source "$HOME/.bash_profile";} ``` ## 变量名 和 方法调用 语法上,其实跟写shell脚本的是一样的,[shell语法参考](https://www.runoob.com/linux/linux-shell.html)。 ````bash export iCloudDir="$HOME/Library/Mobile Documents/com~apple~CloudDocs" funcA() { echo "iCloud所在的路径是:$iCloudDir";} funcB() { echo "参数1是:$1"; echo "参数2是:$2"; echo "所有参数是:$@";} func1() { funcA;} func2() { funcB "arg1" "arg2";} ```` 终端执行情况: ``` hf-home:~ hf$ func1 iCloud所在的路径是:/Users/hf/Library/Mobile Documents/com~apple~CloudDocs hf-home:~ hf$ func2 参数1是:arg1 参数2是:arg2 所有参数是:arg1 arg2 ``` 个人习惯,变量名和配置内用到的方法名 采用驼峰命名法,终端上手敲的方法名都是 **没有空格的小写内容**。 # 案例1:终端流量走代理 需要走代理时终端输入**setproxy** (然后按Enter键),取消代理则输入 **unsetproxy**(然后按Enter键)。 1087是代理软件的端口号,根据实际情况填写,添加下面的内容到配置: ```bash # 设置代理 setproxy() { export http_proxy=http://127.0.0.1:1087 export https_proxy=http://127.0.0.1:1087 } # 取消代理 unsetproxy() { unset http_proxy unset https_proxy } # 简写 # 设置代理 # setproxy() { export http_proxy=http://127.0.0.1:1087 https_proxy=http://127.0.0.1:1087;} # 取消代理 # unsetproxy() { unset http_proxy https_proxy;} ``` # 案例2:剪贴板 执行命令后,自动打开ssh连接,并将密码复制到剪贴板中,当ssh连接询问密码时,直接 **⌘+v** 粘贴密码 (然后按Enter键)就可以连上服务器了。 *有时服务器的密码比较复杂,记不住,每次都要去笔记里拷贝过来。最近在玩树莓派,ssh连接命令是 `ssh pi:[email protected]` 重复内容比较多,老是输出错误* ```bash # 设置剪贴板 setClip() { osascript -e 'set the clipboard to "'"${*}"'" as text' } # 获取剪贴板 getClip() { if [ "$(osascript -e 'clipboard info' | grep '«class utf8»')" != "" ];then echo $(osascript -e "get the clipboard as «class utf8»" | sed "s/utf8»//; s/»//") else echo '' fi } # 连接树莓派 sshpi() { setClip "mypassowrd" ssh pi:[email protected] } ``` 如果服务器比较重要,可以对密码做一层处理,在终端运行下面一行命令,可以将密码转成base64文本: ```bash printf "mypassowrd" | base64 # bXlwYXNzb3dyZA== ``` 配置中的方法改成这样: ```bash # 连接树莓派 sshpi() { setClip "$(printf "bXlwYXNzb3dyZA==" | base64 -d)" ssh pi:[email protected] } ``` # 案例3:open命令 在mac上**open**命令可以做很多事情,**打开网页**、**打开文件夹**、**选中一个文件** 以及 **启动软件**。 ## 打开网页 添加下面的代码到配置中: ```bash bd() { open "https://www.baidu.com";} bl() { open "https://www.bilibili.com";} gg() { open "https://www.google.com";} yq() { open "https://www.yuque.com/hufang/pub/mac";} yuque() { open "https://www.yuque.com/hufang/pub/mac";} ``` 当你输入 **bd**(然后按Enter键)后会自动启动默认浏览器访问百度,mac上默认浏览器是Safari,也可以将Chrome设置为默认浏览器。 当你输入 **gg** 就会打开**google** …… 类似的还可以添加很多,在配置两个字母的方法前一定要在终端里运行一下,看看这个命令有用了,输入命令后 提示如下提示说明命令是可以用的 `-bash: bd: command not found` 其实网址类的要尽量少添加,利用好浏览器的书签功能,也能很高效。 命名尽量符合个人的自觉,比如 **yq**和**yuque** 功能相同,但我每次是输 **yuque**,这就是直觉,有点本能反应的意味。 ## 打开文件夹 我的配置中有这么一段: ```bash dl() { open "$HOME/Downloads";} dirdown() { open "$HOME/Downloads";} dirdl() { open "$HOME/Downloads";} opendl() { open "$HOME/Downloads";} opendown() { open "$HOME/Downloads";} dirdoc() { open "/Volumes/Extend/Documents";} dirvideo() { open "/Volumes/Extend/Documents/Videos";} dirdmg() { open "/Volumes/Extend/Soft/dmg";} dirsoft() { open "/Volumes/Extend/Soft/dmg";} dirapk() { open "/Volumes/Extend/Soft/APP_Apk";} dirapp() { open -R "/System/Applications/Preview.app";} dirbrew() { open "$HOME/Library/Caches/Homebrew/downloads";} dirworkflow() { open "$HOME/Library/Services";} ``` **dl** 、**dirdown**、**dirdl**、**opendl**、**opendown** 都是 打开默认的下载目录,是曾经用过的命令,最后**dirdown** 用的比较多,这也用终端当启动器的弊端。它们的区别,大家可以体会一下。 其实常用目录可以用快捷键切换,切到 下载目录,按快捷键 **⌥+⌘+ L**就可以了,也是能不写到配置里就不写,只写最常用的。 ![image-20201121191207767](https://upload-images.jianshu.io/upload_images/1390773-f60cceeca308b8d0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **dirdoc**、**dirvideo**、**dirdmg**、**dirsoft**、**dirapk** **Extend** 是我的一个硬盘分区,系统盘空间不够,大文件都会移动到这里。 在mac上选中文件/文件夹后,按快捷键 **⌘+⌥+C** 可以复制路径,粘贴出来就可以得到 **/Volumes/Extend/Documents** 这样的路径。 **dirapp** 在访达中打开应用程序目录,并选中 **预览** 这个app,打开应用目录还可以按 **⇧+⌘+A**。 由于个人安装的软件比较多,就有点不好找,预览 会在目录的中间位置,而且这是系统应用,一定是存在的。 **open -R "/xx/xx.xx"** 命令会打开访达,并选中一个文件。 ![image-20201121193501495](https://upload-images.jianshu.io/upload_images/1390773-cb5463ac7c596498.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 启动软件 配置中有这么一段: ```bash typora() { open "/Applications/Typora.app";} typora2() { open -n "/Applications/Typora.app" --args "$HOME/Documents/markdown/default.md";} vinfo() { open -n "/Applications/MediaInfo.app" --args "${*}";} vinfo2() { open -n "/Applications/MediaInfo.app" --args "${getClip}";} runobs() { open "$iCloudDir/mytool/mac-init/run_obs.sh";} runsome() { open "/Applications/Bob.app" open "/Applications/Hidden Bar.app" } ``` 在终端里输出 **typora** 会启动Typora,如果已启用则会将其切换到前台; 在终端里输出 **typora2** 会新开一个Typora,并打开对应文件; **\--args** 参数只会在应用启动时传入,应用已经启动时,参数就接收不到了,而且也不是所有应用都会接收和处理这个参数。 **-n** 参数表示新开一个应用 **vinfo**、**vinfo2** 安装**Mediainfo**后,在终端里输入 **vinfo /xx/xx.mp4**,就会调用**Mediainfo**查看mp4的属性,这种方式有点模拟终端敲命令的意味; 执行 **vinfo2** 前,先复制一个视频文件的路径到剪贴板,比如,选中一个mp4后按快捷键 **⌘+⌥+c**,然后在终端里输入 **vinfo2** 后直接敲Enter键,就会调用**Mediainfo**查看mp4的属性。 在终端里执行过一个命令后,按 **↑**(方向键上键)会调出上次执行的命令,再一下 **↑** 则会调出上上一次的命令。 如果要查看多个mp4的属性,我们只要 **选中文件**→ **⌘+⌥+c** → **终端按↑** → **敲Enter键**,如此往复,就可以很快地查看多个了。 **runobs** **open** 命令还可以执行一个shell脚本 **runsome** 可以把常用的应用都写进来,下次重启电脑后,输个命令就会批量启动了 ---- # 总结 其实还能扩展出很多用法,这取决于的想法 以及对shell脚本的熟练程度。 ~ **Enjoy** ~