更加偷懒的 SSH 技巧

之前总结过一次个人的使用习惯,包括 Terminal、Shell 及 SSH。

在这几年碰到新的工具外加逐渐优化后,已和当初有几分不一样了,是时候重新整理一下了。

2023.12.20 更新:避免 GitHub Action 出现明文敏感信息。

2023.09.01 更新:增加自动补全的颜色修改。

装修一下 PowerShell

之前折腾 Terminal 的文字在 这里

其实 Terminal 这块变动反而是最小的,随着 Windows Terminal 逐渐成熟后,从 Fluent Terminal 转到了 Windows Terminal 而已。

配置 Starship

因为一些原因,将常用的 SSH 客户端从 WSL 换成了 PowerShell,所以就将 PowerShell 装修了一下。

开始用的 oh-my-posh,后来发现了 Starship 速度更快更高效,就换成了这个。

直接 Scoop 安装:

1
scoop install starship

使用记事本打开配置文件:

1
notepad $PROFILE

加入一条内容:

1
Invoke-Expression (&starship init powershell)

重启 PowerShell 即可看到新的样式。

接着安装 PSReadLine,键入以下命令:

1
2
Install-Module PowerShellGet -scope CurrentUser -Force -AllowClobber
Install-Module -Force PSReadLine -scope CurrentUser

再次打开配置文件并加入新内容:

1
notepad $PROFILE
1
2
3
4
5
6
7
8
Import-Module PSReadLine

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineOption -ShowToolTips
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -HistorySearchCursorMovesToEnd

<2023.09.01 更新>

增加自动补全的颜色修改。

这个自动补全的颜色太暗了我看不习惯,之前在 Zsh 那一直用 fg=6,用取色软件取了下颜色的 Hex 值为 #56b6c2,根据 Microsoft 的 PowerShell 文档 在配置文件中加了如下这条:

1
2
3
Set-PSReadLineOption -Colors @{
InlinePrediction = '#56b6c2'
}

还原 Linux 命令习惯

因为用习惯了 Linux 命令,所以装一个 gow 一定程度上解决精分问题:

1
scoop install gow

但是安装后发现有一些别名已经被 PowerShell 自己占用,这要怎么办?

首先可以通过 Get-Alias 查看已经被占用的别名,然后编辑配置文件:

1
notepad $PROFILE
1
2
Remove-Item alias:ls
Remove-Item alias:curl

保存后重新启动终端,发现之前被占用的别名被撤掉就可以正常工作了。

我因为用 Zsh 比较多,很喜欢 ll 这个命令,但是 gow 只提供了 ls,那我们就自己造一个。

1
notepad $PROFILE
1
2
3
4
5
Set-Alias ll Set-ls-a
function Set-ls-a
{
ls -a
}

我非常喜欢它!

来认识下 SSH 工具的新朋友

之前 这篇文字 中用了点方法来让自己比较偷懒地使用 SSH,不过在这几年的时间里,我也没闲着,逐渐打磨着我的偷懒技巧。

来,瞧瞧我们的新朋友 trzsz-ssh

选择这个工具可以让我直接少维护一个脚本,并且还可以无缝使用 trzsz 功能,更加方便地与服务器之间传输文件。

上文提到因为一些从 WSL 换到了 PowerShell,也是因为 trzsz 无法在 Windows Terminal 套 WSL 时正常工作。

询问了作者也让我在 WSL 里调用 Windows 版的 tssh 来使用,那我寻思我不如换成 PowerShell 呢,别搁这套来套去了。

安装 tssh 及解决 SSH 代理问题

安装也很简单了,还是 scoop 直接安装:

1
scoop install tssh

之前折腾的 config 也不能白折腾呀,这边直接用上,但是直接用的话会有个小问题。

在 WSL 下,对于使用代理连接都是基于 nc 来实现的,但是 Windows 没有 nc 要怎么办呢?找到了一个替代品 connect

所以我们先安装 connect

1
scoop install connect

那么问题来了,使用 nc 和使用 connect 的 ProxyCommand 是不一样的,原本的 config 不能用。

但是修改的话,又会造成 WSL 环境下无法使用了,总不能维护两套吧?

是,也不是。

config 呢,还是只维护一个,只不过 Windows 用的那个版本,可以借助 GitHub Actions 帮我转换一下。

到 GitHub 的项目上,选择 Actions 选项卡,然后点击 Simple workflow,将以下内容粘贴进去:

<2023.12.20 更新>

避免 GitHub Action 出现明文敏感信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: Transform config for Windows
on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Transform file
run: |
cp config windows-config
sed -i 's/ProxyCommand nc -X 5 -x/ProxyCommand connect -S/' windows-config
git config user.name "${{ secrets.GIT_USER_NAME }}"
git config user.email "${{ secrets.GIT_USER_EMAIL }}"
git add windows-config
git commit -m "Auto transform"
git push

然后前往项目的 Settings,左侧导航栏下方 Secrets and variables - Actions,在这里可以添加 Action 中调用信息。

上面用的 Secrets 一共有 2 个,分别是 GIT_USER_EMAILGIT_USER_NAME,分别是 GitHub 的邮箱与用户名。

这样每次在更新 config 文件时,GitHub Actions 会自动执行将 config 文件中的命令转换成 Windows 下可用的版本并提交到项目中。

拉下来的时候本地也会多了这个文件,现在直接把这个文件用上。

在 PowerShell 下编辑 config 文件:

1
2
cd ~/.ssh
notepad config

将下面内容粘贴进去:

1
Include ~\sshconfig\windows-config

记得把私钥给搬过来,这样敲一下 tssh 就可以直接用了。

根据 config 自动生成

优化一下

之前的 config 文件里 Host 都是小写的,为了打起来方便,因为毕竟常用的机器还是直接 ssh hostname 连上去了嘛。

但这样有个问题是,在 tssh 的列表中也是小写的了。

不过发现没有,上面的截图中首字母大写了,怎么做到的呢?

其实只是用了一点小技巧,在配置 config 文件的时候先写首字母大写的内容,也就是想显示给 tssh 的,然后再加小写的内容并以 * 结尾,就如下例所示:

1
2
3
4
5
6
7
# 测试平台
Host Test test*
HostName 192.168.50.167
Port 22
User root
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes

tssh 会忽略掉有通配符的配置项,利用这点既保留了平常的便捷性,又保证了列表的美观。

同理对于 git 的代理也可以使用此方法在列表中隐藏:

1
2
3
4
# GitHub
Host github.com*
User git
ProxyCommand nc -X 5 -x 127.0.0.1:37777 %h %p

最后再写个 alias 把 tssh 映射给 ssc

1
notepad $PROFILE
1
Set-Alias ssc tssh

顺便把 WSL 那边也维护一下,以便临时使用时保证使用习惯一致。

切换到 WSL,打开之前配置好的 Shell 配置文件(以下以 Zsh 为例):

1
vim ~/.zshrc

删掉 ssc 的那条 alias。

然后将上游的分发脚本修改一下,就有了下面的新脚本:

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
#!/bin/sh

SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
cd $SHELL_FOLDER
git pull
OLD_FILE=~/.ssh/config
NEW_FILE=./config
diff $OLD_FILE $NEW_FILE > /dev/null
if [ $? -ne 0 ]; then
cp ./config ~/.ssh/config
fi


cd ~
FIND_ZSH_FILE="./.zshrc"
FIND_BASH_FILE="./.bashrc"
FIND_STR1="sshconfig.sh"
FIND_STR2="tssh"
if [ ! -f $FIND_ZSH_FILE ]; then
exit 1
elif [ `grep -c "$FIND_STR1" $FIND_ZSH_FILE` -eq '0' ];then
echo "alias sshconfig='$SHELL_FOLDER/sshconfig.sh'" >> ./.zshrc
fi
if [ ! -f $FIND_ZSH_FILE ]; then
exit 1
elif [ `grep -c "$FIND_STR2" $FIND_ZSH_FILE` -eq '0' ];then
echo "alias ssc='/usr/bin/tssh'" >> ./.zshrc
fi
if [ `grep -c "$FIND_STR1" $FIND_BASH_FILE` -eq '0' ];then
echo "alias sshconfig='$SHELL_FOLDER/sshconfig.sh'" >> ./.bashrc
fi
if [ `grep -c "$FIND_STR2" $FIND_BASH_FILE` -eq '0' ];then
echo "alias ssc='/usr/bin/tssh'" >> ./.bashrc
fi

当然别忘记给 WSL 里也装好 tssh,这样就没问题了。

最后如果想在 PowerShell 下更新 sshconfig,可以加一条 alias:

1
notepad $PROFILE
1
2
3
4
5
Set-Alias sshconfig Set-sshconfig
function Set-sshconfig
{
wsl.exe sh /mnt/c/Users/7inaBranford/sshconfig/sshconfig.sh
}

注意脚本的路径要用 WSL 下的路径来写,这样就可以不切换到 WSL 直接更新了。

小小改造下服务器的 Zsh

这几年在服务器上经常 curl ip.fm 来查看服务器本机 IP,于是决定把 IP 写在一个随时能看到的地方。

Zsh 和 Oh My Zsh 的安装 之前 说过这里就跳过不表,我在服务器端统一使用 ys 这个主题,这次就来改造一下这个。

1
cp ~/.oh-my-zsh/themes/ys.zsh-theme ~/.oh-my-zsh/themes/myys.zsh-theme

然后准备好要写上的服务器 IP:

1
ip=$(curl ip.fm | grep -o -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")

如果要用内网 IP 标识的话,直接手动写:

1
ip=192.168.7.3

然后对复制出来的主题进行操作:

1
sed -i 's/\%{\$bg\[yellow\]\%}\%{\$fg\[black\]\%/\%{\$fg\[yellow\]\%/' ~/.oh-my-zsh/themes/myys.zsh-theme && sed -i "s/{\$fg\[green\]\%}\%m/{\$fg\[green\]\%}\%m\%{\$fg\[blue\]\%} \<$ip\>\%{\$reset_color\%}/" ~/.oh-my-zsh/themes/myys.zsh-theme && sed -i 's/\%{\$terminfo\[bold\]\$fg\[red\]\%}\$/\%{\$terminfo\[bold\]\$fg\[green\]\%}\❯/' ~/.oh-my-zsh/themes/myys.zsh-theme

最后更改下 Zsh 的主题:

1
sed -i 's/ZSH_THEME="ys"/ZSH_THEME="myys"/' ~/.zshrc

初始化后即可生效。

1
source ~/.zshrc

效果还行吧!

写在最后

其实之前在 WSL 上经常碰到一个问题是 Zsh 的进程无法正常消灭,卡在那里会占用不少的 CPU,并且只能通过任务管理器方式来关闭,虽然不是经常碰到,但也十分烦人。

现在这个问题随着使用习惯的更改也解决了,真好!

附上最后的配置文件,仅供参考。

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
Invoke-Expression (&starship init powershell)

Import-Module PSReadLine

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineOption -ShowToolTips
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -HistorySearchCursorMovesToEnd

Set-PSReadLineOption -Colors @{
InlinePrediction = '#56b6c2'
}

Remove-Item alias:ls
Remove-Item alias:curl
Set-Alias ssc tssh
Set-Alias ll Set-ls-a
function Set-ls-a
{
ls -a
}
Set-Alias sshconfig Set-sshconfig
function Set-sshconfig
{
wsl.exe sh /mnt/c/Users/7inaBranford/sshconfig/sshconfig.sh
}

$Env:http_proxy=""
$Env:https_proxy=""
$Env:all_proxy=""
Set-Alias pon Set-Local-Proxy
Set-Alias pof Clear-Local-Proxy
function Set-Local-Proxy
{
$Env:http_proxy="http://127.0.0.1:37777"
$Env:https_proxy="http://127.0.0.1:37777"
$Env:all_proxy="socks5://127.0.0.1:37777"

Write-Host "------- Proxy ON! -------"
}

function Clear-Local-Proxy
{
$Env:http_proxy=""
$Env:https_proxy=""
$Env:all_proxy=""

Write-Host "------- Proxy OFF! ------"
}