前两天一直在思考如何管理我的 SSH config 配置,最后的解决办法就是通过 git 版本管理起来。但这两天由冒出一个新的问题,那就是经常在国内直连 aws 或者 oracle 的机器时 ssh 连不上,但是通过国内的 VPS 中转就非常快,那这就意味着,我每一次连接国外的机器时必须先登录腾讯云的机器,然后在从腾讯云的机器上连过去,有些麻烦,但那天在 Twitter 上看到有人分享了一个 SSH 管理的命令行工具 assh
,大致的看了一下使用简介,通过配置就可以完美的解决这个问题。
assh 这个工具就将登录一台机器跳转 SSH 再登录另外一台机器的步骤简化了,assh 使用 lib-ssh 提供的 ProxyCommand 来实现。大部分的公司,或者注重安全的 SSH 访问都会将 SSH 的登录配置管理放到一台堡垒机或者跳板机上,然后通过跳板机再去连接真正的机器。
+-------+ +----------+ +-----------+
| Laptop| <---> | Jumphost | <--> | RealServer |
+-------+ +----------+ +-----------+
比如上面的流程中,可能需要先连接 Jumphost:
ssh -p 222 someone@Jumphost
然后在 Jumphost 上连接真正的服务器,一方面是为了安全考虑,另一方面是可以非常方便的进行权限管理和审计:
ssh someone@RealServer
如果要简化这个步骤可以使用 SSH 的 -J
选项:
ssh -J someone@Jumphost:222 someone@RealServer
或者可以使用 ProxyCommand:
ssh -o ProxyCommand='ssh -W %h:%p -p 222 someone@Jumphost' someone@RealServer
从 OpenSSH 7.3 开始,还可以使用 ProxyJump
,可以通过在 config 文件中配置:
Host RealServer
HostName 1.2.3.4
ProxyJump someone@Jumphost:22[, user2@Jumphost2:222]
User someone
如果有多个 Jumphost 可以直接用逗号分隔接在后面。
上面两个方式都可以直接通过 Jumphost 来直接登录到 RealServer 上。
Host
: 定义 host, *
可以用来表示全局配置HostName
: 定义真实的 hostname, 可以是域名或者 IPUser
: SSH 登录的用户名IdentityFile
: 私钥路径ProxyCommand
: 定义连接服务器的命令LocalForward
: 通过 TCP 转发指定的本地端口到远程的端口Port
: 指定连接的远程端口Protocol
: 协议ServerAliveInterval
: 设置没有数据后多少时间间隔超时ServerAliveCountMax
: 设置服务活跃信息的数量,如果阈值达到,同时服务器活跃信息 ,服务器活跃消息 (server alive messages) 通过加密通道传输,因此不能被欺骗。The TCP keepalive 选项通过 TCPKeepAlive 是可以伪造的。服务器活跃机制在判断客户端或者服务器在不活跃时何时断开是非常有用的。默认值是 3,举一个例子,ServerAliveInterval 设置成 15,ServerAliveCountMax 保持默认,如果服务器没有回应,ssh 会在大约 45 秒后断开连接。这个选项只在 protocol 2 下有效看一个最基本的 assh.yml
配置:
hosts:
hosta:
Hostname: 1.2.3.4
hostb:
Hostname: 5.6.7.8
Gateways: hosta
hostc:
Hostname: 9.10.11.12
Gateways: hostb
hostd:
Hostname: 13.14.15.16
GatewayConnectTimeout: 2
Gateways:
- direct
- hosta
说明:
ssh -o ProxyCommand="ssh hostb nc %h %p" hosta
OpenSSH 可以复用存在的 TCP 连接,比如在创建了多个 SSH sessions 的时候,可以避免 TCP 创建连接带来的过度开销,修改 vi ~/.ssh/config
:
Host *
ServerAliveInterval 60
ServerAliveCountMax 30
ControlMaster auto
ControlPath ~/.ssh/connection-%r@%h:%p
ControlPersist 48h
回到 assh 本身,assh 是用 Go 语言编写的一个命令行工具,使用 yaml 格式的配置,可以通过该配置快速生成 ~/.ssh/config
配置,通过几行配置就可以利用 ProxyCommand 来进行 SSH 跳转。
assh 非常小巧,当却很强大
如果本地安装了 Go 环境:
go get -u moul.io/assh/v2
macOS 上:
brew install assh
assh 支持一些事件,可以用来触发一些操作或者进行通知。
BeforeConnect 会在 assh 将要连接到远程 SSH 端口时触发。
OnConnect 会在连接到远端 SSH 端口后被调用。
OnConnectError 会在 assh 在建立 TCP 连接失败时调用。
OnDisconnect 会在 assh socket 断掉后触发。
BeforeConfigWrite 会在 assh 重写 ~/.ssh/config
时触发。
# 生成 SSH 配置文件
assh config build
assh config build > ~/.ssh/config
# 搜索 hosts
assh config search <keywords>
# 列出配置
assh config list
# 可视化显示
assh config graphviz
# 列出活跃的连接
assh sockets list
# create a master control sockets
assh sockets master
# close active control sockets
assh sockets flush
# send packets to the SSH server
assh ping -c 4 host
这两天重装系统同步 Chrome 的数据才发现,我一直使用的 Dream Afar New Tab 这个我用了很久的扩展从 Chrome Webstore 消失了,不清楚是 Google 主动下架,还是作者很久没有更新被 Webstore 下了还是为什么。但这个扩展经过了很多的 Chrome 版本依然运行良好至今为止都能每天给我提供世界不同地方的美景。
Chrome 的扩展安装后以文件的形式在如下的目录中:
%UserProfile%\AppData\Local\Google\Chrome\User Data\Default\Extensions
~/.config/google-chrome/Default/Extensions/
~/Library/Application Support/Google/Chrome/Default/Extensions/
然后在 chrome://extensions/
扩展管理中点击 Details 获取扩展的详细信息可以知道扩展的唯一 ID,这个 ID 一般也是 Chrome Web Store 的唯一索引 ID,比如 Dream Afar 是 henmfoppjjkcencpbjaigfahdjlgpegn
。然后在上面的目录中找到对应的目录,将该目录备份,然后在另外的系统中对应的位置恢复该目录即可。
在扩展页面,左上角有一个 Pack,选择扩展的根目录,然后选择 Pack 就可以得到一个 crx 文件。
简单整理一下 Docker 中 network 子命令,以及 docker 中相关 network 方面的内容。
在安装完 Docker 后,使用 ifconfig -a
查看可以看到多出一个虚拟的 docker0 接口,这个接口是 Docker 默认的网关地址。
Docker 容器默认有三种连接方式:
Docker 默认会生成一个 docker0
网桥,如果不指定,默认创建的容器都会默认走此网桥,使用 bridge 模式联网。默认 bridge 会产生 docker0 的虚拟接口,在宿主机上可以使用 ifconfig -a
来查看,一般的网关地址是类似 172.17.0.1
这样的私有地址,所有的容器都会使用这个地址作为网关,容器的 IP 地址会从 172.17.0.2
到 172.17.0.254
这个范围 IP 段划分。
host 模式等同于容器直接使用物理机的网络,宿主机的 IP 就是容器的 IP,端口也可以直接调用。
none 模式,也就是容器默认不联网的模式。通常会合自定义网络的容器一起使用。non
在 swarm 服务中不可用。
还有两种更高级的网络模式,overlay 和 macvlan,分别用于跨宿主机的容器通信和给每个容器分配一个 mac 地址。
macvlan 网络允许给容器分配一个 MAC 地址,这样在网络中就可以以物理设备存在。Docker daemon 会通过 Mac 地址将流量导给容器。在处理一些历史遗留应用,期望直接使用物理网络的场景非常适合使用 macvlan
.
Overlay 网络会连接多个 Docker daemon,开启 swarm 服务来相互通信。也可以通过 overlay 网络来帮助 swarm 服务和独立容器之间的通信,或者帮助两个独立的容器,或者帮助不同的 Docker daemons。通过 overlay 就不需要系统级别在不同容器中的路由了。
Docker 本身也有一个 link 指令,可以用于连接两个容器,但这命令的缺点是只能单向连接,也就是 A 和 B 两个容器,只能 A 访问 B 或者 B 访问 A,做不到 AB 之间直接同时互访。
创建新网络
docker network create network-name
docker network create -d bridge network-name
使用 ls
查看:
docker network ls
审查 network 信息:
docker network inspect network-id
删除网络:
docker network rm name
docker network rm network-id
创建时指定 IP 段:
docker network create --subnet=192.168.1.0/24 net-name
创建名为 net-name 的网络,默认 bridge,IP 段是: 192.168.1.0 ~ 192.168.1.255
这里就简单的记录一下我从 Linux Mint 迁移到 MacOS 根据我的个人需求来初始化新的 MacBook Pro 的一些设置,和一些基本的感想。下面的内容会按照我自身的需求出发,我会列举我想要的功能然后在此基础上我需要借助哪些工具来实现。在切换到 MacBook Pro 之前,我使用了大约 6 年多的 Linux Mint,我已经有一套我自己的 Workflow,在切换到 Mac OS 之前我就在想哪一些的事情我是必须有 Mac 的软硬件才能做到,并且很提高某一方面的效率的,我列了一些
Macbook Pro have two different CPU specification, which is 2.6 GHz 6-core i7 and 2.3 GHz 8-core i9 processor.
The i9 9980H (2.3ghz) is 4% faster per core, and ~25% faster under full load than the i7 9750H (2.6ghz). $100 is ~4% of the price difference at that spec.1
The i9 9980HK (2.4ghz) is 5% faster in every situation than the i9 9980H.
Whether that will make a difference for you at all is highly dependent on what you are doing with it. If you are not compiling software, rendering, doing video compositing/encoding, or other parallelized high CPU tasks, it probably won’t.
内存是必需品,如果需要大量使用 Chrome,或者依赖于 IDE,或者需要同时开多个应用,大一些的内存还是必要的。
首先是一些必要设置的设置,后面的一切都依赖这些设置。
国内的网络环境,这已经成了所有设置的基础,甚至我想先下载一个 Chrome 都需要依赖代理设置好。首先从 GitHub 下载 ClashX,然后导入 v2ray 配置。(或者可以用 v2rayU, Qv2ray)
ClashX 的配置文件在 ~/.config/clash/
目录下。
已经替换成 Clash For Windows。
在终端中要进行代理:
# 设置 socks5 代理
export http_proxy="socks5://127.0.0.1:1080"
alias
alias setproxy="export ALL_PROXY=socks5://127.0.0.1:1080" alias unsetproxy="unset ALL_PROXY"
或者设置 curl (curl >= 7.21.7) 代理:
curl -x socks5h://localhost:1080 http://www.google.com/
在其他系统上在浏览器中的时间伴随着我使用系统的时间,大量的事是在浏览器的页面中完成的,比如在 Trello 中记录时间,比如收发邮件,比如密码管理等等。
有了代理,就可以很快的安装上 Google Chrome,然后登陆账号,没几分钟我所有的同步设置就全部来了,包括书签,插件,甚至历史记录。
LastPass 插件登录,密码同步;Trello 登录,代办事项同步;Tampermonkey 需要到设置中开启高阶设置,然后启用浏览器同步,所有的 userscripts 也同步过来了。等等还有很多的插件也一并同步了。Chrome 此时就已经可以是日常使用了。
我使用小鹤双拼,在开机设置的时候我就已经选择了双拼,然后在输入法中简单的设置一下使用小鹤双拼即可。在 Mac 下使用 Ctrl+Space 来切换输入法。
系统自带的小鹤双拼用起来似乎还没遇到什么大问题,先不配置 Mac 下的 Rime 了。如果需要编译安装 Squirrel 可以按照这个文档安装。
在系统设置 Sharing 中需要开启远程登录,这样就可以通过 ssh yourname@<mac.ip>
来登录系统了,非常方便我在局域网中将我原来的配置以及文件通过 rsync 传输过来。
Linux Mint 上继承了 Debian/Ubuntu 系列的 apt 包管理工具,一些工具的安装非常方便,Mac 下有 homebrew。
官网 下载安装即可,如果遇到说 curl 443 端口连接不上,那就只能先 Chrome 上把这个脚本下载下来,然后 bash install.sh
来手动安装了。
homebrew 也还提供了字体安装的支持,安装 homebrew-cask-fonts
brew tap homebrew/cask-fonts # tap 类似于 apt 中添加第三方源的 add repository
brew cask install font-inconsolata
brew cask install font-fira-code
brew cask install font-source-code-pro
brew tap homebrew/cask-drivers
然后配置国内镜像,加速下载。
brew 常用的命令:
brew search package_name
brew info package_name
brew install package_name
brew update
brew upgrade package_name
brew uninstall package_name
brew list
brew config
brew doctor
brew uninstall package_name
所有的 brew cask
包,可以到这里 查看。
homebrew 会将软件安装到 /usr/local/Cellar
,然后通过软链接链接到 /usr/loca/bin
目录。
brew install asdf tree tmux hub p7zip openssl curl node automake autoconf ack
brew install macvim --with-cscope --with-override-system-vim --with-lua --HEAD
brew install coreutils curl git asdf
rehash
brew 和 brew cask
的区别在于 cask 用来安装 GUI 软件。
brew cask
brew cask install anki alfred eudic iterm2 visual-studio-code
brew 的备份和恢复,如果要在两台 Mac 间备份和恢复 brew 安装的包,可以使用:
brew bundle dump # dump
brew bundle # 恢复
brew bundle dump
会生成一个 Brewfile 文件,这是一个纯文本的文件,里面列举了系统上的 brew 配置和安装的列表,那么我只需要维护一个 Brewfile 文件就可以一键安装必备的命令和桌面软件了。
通过 App Store 安装的应用可以通过 mas 来管理。
一直都说 Mac 的手势领先其他厂商,个人初使用来看确实非常顺手,没有卡顿,并且大面积的触摸板使用体验确实不错。
除了常用的双指上下滚动,左右翻页还有这样一些操作:
但是关于选择页面中的文本在 Mac 就比较有趣了,我一般的行为模式就是用左手大拇指双击进入选择模式,然后接触触摸板选择文字释放左手大拇指。我这个操作习惯在 Mac 需要用力按下触摸板选择,后来在 System Perferences -> Accessibility -> Mouse & Trackpad -> Trackpad Options -> Enable dragging without Drag Lock 找到了设置。
这个选项里面有三个选择:
很多人推荐开启第三个,我个人不太喜欢,明明能有用一个指头完成的事情为何要用三个指头。
但前两个就有点暧昧不清了,这里具体解释一下:2
我个人的习惯还是选择了第一个 without drag lock.
官网 下载安装即可。
zsh, vim, tmux 的配置放在 dotfiles 项目管理。
git clone git@github.com:einverne/dotfiles.git
cd dotfiles
make bootstrap
配置和 Guake 类似的下拉显示。
下载 JetBrains Toolbox,然后一个个选择想用的 IDE。
官网 下载,我个人非常喜欢的一个 Git 客户端,跨平台,页面也很清晰。不过简单的提交和使用 IntelliJ IDEA 自带的 Git 管理也已经足够好了。
设置 GitHub 的 SSH Key。
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
然后 clone 我的 dotfiles 配置,笔记,wiki 等等配置。
虽然大部分的情况下触摸板和快捷键已经能满足一定的需求,但有些时候还是会接上鼠标,尤其是当连接显示器将 Mac 作为主机使用的时候,这个时候我就发现一个问题,那就是鼠标滚轮的方向和我在 Linux 下养成的习惯相反了,看网上的材料说设置里面可以设置更改鼠标 nature 的方向,但是修改过后发现触摸板的双指滚动方向也跟着变了,然后继续搜索发现很多人推荐 Scroll Reverse 但是这个小工具在 OSX10.15 及以上有兼容性问题,继续搜索就发现了 Mos,这个软件可以更改鼠标滚动的方向,也可以让滚动更加平滑。
Mac 的快捷键设计有一个非常容易的记忆方法,和 UI 相关的快捷键基本上和 Cmd 相关,和 Ctrl 相关的大多数是终端内的操作。所以 Cmd 组合 Q/A/Z/C/V/X/T/H/M
等等都是和界面窗口标签页相关的,而 Ctrl 和 a/e/n/p/b/f
都和终端中光标移动或者终端中字符处理相关的。
在打开的窗口中显示隐藏的文件:Cmd+Shift+.
默认在 Finder 中显示所有文件,包括隐藏文件。
defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder
快捷键 | 说明 |
---|---|
Cmd + Q | 退出应用 |
Cmd + W | 关闭当前窗口,关闭 Tab |
Cmd + X/C/V | 和其他系统类似,剪切,复制,粘贴 |
Cmd + Tab | 切换打开的应用 |
Cmd + ` | 切换同一个应用的多个窗口,当然结合触摸板的四指下滑也可以 |
Cmd + , | 打开大部分应用的偏好设置 |
Cmd + [ | 后退 |
Cmd + ] | 前进 |
Cmd + Space | Spotlight search 被我替换成 [[Alfred]] 和 [[Raycast]] 的呼出按键 |
Cmd + L | 定位到地址栏,非全局快捷键,在 Chrome 中非常好用 |
Cmd + A | 全选 |
Cmd + Z | 撤销上一次操作,Cmd + Shift + Z 重做 |
Cmd + F | 页内搜索 |
Cmd + G | 搜索下一个, Cmd +Shift+G 上一个 |
Cmd + H | 隐藏最前面的窗口,这个操作不可逆,我应该不会用到 |
Cmd + M | 最小化前面的窗口到 Dock,也不可逆,所以我也不用 |
Cmd + N | 新建窗口 |
Cmd + O | 打开文件 |
Cmd + P | 打印当前文档 |
Cmd + S | 保存 |
截屏的快捷键
快捷键 | 解释 |
---|---|
command + 1 左边的按键 | 在同一个应用不同窗口间切换 |
Shift+command+3 | 截取全屏 |
Shift+command+4 | 截取部分,通过光标选择 |
Shift+command+5 | 打开截取工具,有更多选项 |
在大部分的文档类应用中了解这些快捷键也可以提升不少效率
快捷键 | 说明 |
---|---|
Cmd + B | 加粗 |
Cmd + I | 斜体 |
Cmd + K | 插入链接 |
上面提到的 Mac 下的 Ctrl 快捷键大部分是和终端或者输入框中的文字相关的,Ctrl 的组合在 Linux 的终端,Emacs 中也有不少的应用。
快捷键 | 说明 |
---|---|
Ctrl + a/e | 光标跳转到行首,行尾 |
Ctrl + b/f | 光标向前 (backward), 向后 (forward) 移动一个字符 |
Ctrl + n/p | 下一个 / 上一个 |
Ctrl + h/d | 向前删除一个字符,向后删除一个字符 |
Ctrl + k | 删除光标都末尾所有内容,这个快捷键在我的配置中设置了切换到上一个 Panel,所以我不怎么用 |
Ctrl + w | 删除前面一个单词 (WORD) |
Ctrl + u | 删除直到行首 |
Mac 全部快捷键
Mac 有个 Wired 的快捷键组合,在 Linux 终端下,向前向后跳转一个 Word 是 Alt+b/f, 但是 Mac 下默认是 Esc+b/f,这个默认的快捷键太奇怪了,想象一下在键盘上按住 Esc 在按 b/f 的姿态,一个手几乎是做不到的。所以把 Esc 按键 remap 到 Caps Lock 也算是一种勉强的解决方法吧。不过更好的方法,以及延续我的习惯,我在 iTerm2 中可以设置一下 Option+b/f。
From: https://apple.stackexchange.com/a/154296/149497
查字典是我个人非常频繁的一个需求,虽然 Mac 自带的词典日常使用已经完全够用,并且集成到系统的 Lookup 功能也是非常好用,但我个人还是比较喜欢 Ctrl+C+C 这样的快捷键。我个人的需求不仅是英文的字典,有的时候还会查阅韩语或其他语言的字典,我个人偏好离线的字典,所以一直一来使用的是跨平台的 GoldenDict,从 GoldenDict GitHub 页面下载安装即可。我个人的需求:
在 Mac 上随便截一张图可能就是 7,8MB 大小,非常不适合在互联网上分享,我一般会使用 Google 的 Squoosh 来进行压缩。
有些人推荐 squash 这款软件,简单的看了一下官网,似乎就我这个需求并不需要 Squash 这款软件。
在 Linux 上我使用 fcitx 自带的粘贴板 Ctrl+; 就可以呼出,因为就是输入法的功能,所以非常方便。在 Windows 下用 Ditto 这样一款软件。那么切换到 MacOS 就想要一个代替品。
~~brew cask install maccy~~
默认是 Shift+Cmd+C 弹出粘贴历史,我习惯了 Ctrl+;
所以直接改成这个快捷键。
已经不再使用 maccy,先是购买了 Alfred,然后又切换到了 [[Raycast]] 其自带的粘贴板管理已经非常强大了。
借助 OpenInTerminal 这个 Finder 的插件可以实现在 Finder 目录中,立即打开终端。
借助这个插件还可以:
这里不得不吐槽一下,文件管理器,Mint 中的 nemo 使用起来要舒服多,这上面的操作,右键就能完成,完全不需要额外安装插件。
在 Mint 我已经有了一套熟悉的快捷键,现在到了 MacOS 上一边熟悉自带的快捷键,也想对默认的一些快捷键做修改,这个时候就需要 Karabiner-Elements。
Karabiner-Elements 比较强大,可以自定义修改几乎键盘上的每一个键,不过我个人并不推荐把键盘修改的面目全非,这需要花费很长的时间来适应。
Karabiner-Elements
在使用 Karabiner 的时候发现组合键 Cmd+F12 等等 Fn 键,表现的就像是没有按下 Cmd 按键一样,最后发现需要在 Karabiner 中设置 Devices 才可以生效。
另外我将 Caps Lock 作为一个 Hyper Key,按下 Caps Lock 相当于同时按下 Cmd+Ctrl+Shift+Option, 这样 Caps Lock 就可以结合其他按键作为一个新的组合按键,在利用 Hammerspoon 可以实现一套自己的快捷键工作习惯,比如我个人将 Hyper Key + HJKL 作为调整窗口的快捷键,Hyper Key+NP 作为调整窗口在哪一个显示器的快捷键。
Karabiner 之后也会用一个篇幅来介绍一下。
去 Telegram 官网看,发现 MacOS 下有两个客户端,一个叫做 Telegram Desktop,这个和 Windows 和 Linux 放在一起;另一个叫做 Telegram for MacOS,简单了解一下后,发现这个客户端是单独用 Mac 的原生语言实现。这两个的区别在于 Telegram Desktop 使用跨平台的实现,所以体验上和其他两个平台相似,原生实现的 Telegram for MacOS 则提供了加密等额外的功能。
从 Dropbox 换成了 分布式的 Syncthing.
[[Syncthing]] 的配置设置 在 $HOME/Library/Application Support/Syncthing
.
另外也会用中心化的 NextCloud 作为备份。
开源的选择 IINA
或者老牌的 VLC
历史的笔记在为知笔记里面,下载,登录数据就回来了。 已经切换为 [[Obsidian]]
WizNote 打开的时候显示不被认证的开发者,需要执行
sudo spctl --master-disable
开启信任任何来源的安装,当然这个操作会降低系统的安全性,谨慎!
另外今年起,我渐渐的将笔记迁移到了 Obsidian.
我在 GitHub 上新建了一个 Private 的项目来同步 Obsidian 的笔记。详情可以参考我的 Obsidian 跨设备同步方案。
唯一的选择,网易云音乐,我之前也写过文章,在体验过市面上所有的音乐软件后,选择了网易,然后已经很多年了。
本地音乐播放器替换为 [[Swinsian]],跨平台音乐播放器已经替换为 [[Plexamp]]。
官网 下载安装。
在 Mac 上我发现我无法想在 Mint 中拖拽窗口到左右边缘,然后将窗口左右分屏,导致现在 Mac 上的窗口层层叠叠,管理起来非常的不方便。找了几个开源的工具。
体验了一下之后选择了 Rectangle,虽然也看到了 MacOS 上的平铺窗口管理。
但这些都需要大量的定制,所以先放着了。
经过一段时间的使用之后,最后还是用 Hammerspoon 用自定义脚本实现了 macOS 上的窗口管理,绑定快捷键之后的体验比上面提到的软件都要好很多。
Pixea 一款优秀的看图软件。
LICEcap
虽然 iStat Menus 很强大,但看看 CPU 和内存占用,网速,用开源的 iGlance 足矣。
Linux 和 NAS 上一直用的 Calibre
brew install --cask calibre
因为历史上保存了一些请求,所以还是用了 Postman,不过新出的 Postwomen 也可以试试。
brew install --cask postman
大名鼎鼎的 Charles,以及命令行 mitmproxy, 以及网络协议的 Wireshark 都来一套。
aria2, you-get 和 youtube-dl
日常使用,Transmission 作为 BitTorrent 备用。
自有了 NAS 以来,将 PT 下载切换到了 rtorrent 和 ruTorrent。
自己搭建的 Bitwarden,虽然常年使用 LastPass,但最近自己搭建 Bitwarden 后发现 Bitwarden 跨平台做的非常不错,还可以利用起 Mac 的 Touch ID。
2021 年 3 月开始完全放弃了 LastPass,全面切换到 Bitwarden。同时把 Android,macOS,Chrome 浏览器上的应用和扩展全部切换了
开了很多应用,导致状态栏非常乱,很多人推荐收费的 Bartender 3,不过试了一下发现开源的 Dozer 也非常不错。
在 Finder 中点击直接打开终端到当前文件夹。
brew cask install go2shell
在 Linux 下我使用一个叫 screenkey 的工具,在 Mac 上也找到一个类似的开源项目 keycastr.
brew cask install keycastr
如果经常使用 Mac 外接显示器使用,就会发现如果断开连接之后再连接,系统对外接显示器的记忆就丢失了,这个时候还需要到设置中进行一番设置。
最开始只是想做到在不同的 WiFi 环境下使用不同的 DNS 配置,所以发现了 Hammerspoon 这个开源的自动化工具,不过发现 Hammerspoon 太强大了,可以代替上面提到的很多个工具,以后会再加一篇文章单独介绍一下 Hammerspoon。
yabai
如果经常修改系统配置,常用 sudo 命令就需要输入一串密码,在 Mac 下可以使用 Touch Id 来验证密码。
sudo sed -i ".bak" '2s/^/auth sufficient pam_tid.so\'$'\n/g' /etc/pam.d/sudo
这一行命令的作用是把 /etc/pam.d/sudo
备份为 /etc/pam.d/sudo.bak
,然后在 /etc/pam.d/sudo
的第二行前面加入 auth sufficient pam_tid.so
。
要恢复就使用:
sudo mv /etc/pam.d/sudo.bak /etc/pam.d/sudo
Touch Id 的妙用还可以参考:pam-touchID 和 pam_touchid.
Mac 上使用 netstat
显示监听的端口:
netstat -an | grep LISTEN
或者使用 lsof
:
sudo lsof -iTCP -sTCP:LISTEN -n -P
lsof
可以看到具体某个端口关联的 PID。
上面提到基础的编程环境安装,这里在针对具体细节补充说明。
asdf 是一个命令行下的多语言,多版本管理工具,我之前的文章提到过 pyenv 安装管理多个版本的 Python, 同样的我在外延部分提到了 Java 的多版本管理 jenv, 还有 Ruby 的多版本管理 rbenv,甚至还有 node.js 等等语言,等等编译工具的多版本管理工具,而 asdf 将这些多版本管理工具都整合到一起,通过简单的 asdf 一行命令就可以搞定很多二进制工具,或语言的版本管理,asdf 通过扩展的方式支持了非常多的常用工具。在 Mac 下的安装也非常简单,直接参考官方网站 即可。
asdf plugin add java
asdf install java adoptopenjdk-8.0.262+10.openj9-0.21.0
asdf install java adoptopenjdk-11.0.8+10.openj9-0.21.0
asdf global java adoptopenjdk-8.0.262+10.openj9-0.21.0
java -version
asdf plugin add maven
asfd install maven 3.6.2
asdf global maven 3.6.2
mvn --version
asdf plugin add python
asdf install python 3.6.1
asdf global python 3.6.1
python -V
asdf plugin add nodejs
bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
asdf install nodejs 14.5.0
asdf global nodejs 14.5.0
node -v
yarn -v
我使用 MySQL 官方的管理工具 MySQL Workbench 结合 JetBrains 的 DataGrip 一起使用,相辅相成。
我的很大一部分照片库在 Windows 的 Lightroom 中,幸亏 Lightroom 的迁移并不麻烦,在 Windows 上使用 WinSCP,然后局域网连上 Mac,直接将 Lightroom 所在的 Pictures 图片库复制到 Mac 上面的图片库中,然后将 Lightroom 的 .lrcat
catalog 文件夹也拷贝到 Mac 上,这个目录可以在 Windows 的“编辑”-“目录设置”中找到。
拷贝完成后在 Mac 上打开 lrcat 文件,然后在 Lightroom 中右击文件夹,Find missing folder,重新导入就 OK 了。
选择拓展坞的时候看了京东上面的大部分牌子,也参考了一些帖子,无疑如果不差钱直接上贝尔金,CalDigit TS3 Plus,雷电 3 的拓展坞一步到位即可。但我自己并不需要 4K60Hz,也用不上那么大的带宽,我目前的需求只需要一个可以用的 HDMI 扩展,一个 USB 外接鼠标,最好再带一个 SD 卡槽,剩下的 VGA,RJ45 网口我并不是必须,所以开始的时候直接买了贝尔金的 Tpye-C 的拓展坞,京东下单叠加了一个优惠大概 500,但是拿回来之后试用了两天就发现了问题,我只接一个 USB 的时发热也有些大,另外一个致命的问题就是 SD 卡的读取速度真的和测评里面看到的一样 20M 就上不去了。所以果断退货换了一个飞利浦的 7 合 1(HDMI,SD/microSD,Tpye-C,三个 USB),回来立即试了一下 SD 读取,以及发热问题,在只用 USB 接口的时候几乎感受不到温度,SD 卡也可以轻松地到 70M,就他吧。(另外要提一下为什么不买绿联的拓展坞,在京东上销量几乎被绿联拿走了一大半,但是我已经不止一次的看到过因为绿联的拓展坞从而导致接口损毁,甚至影响主板,导致重启的问题,所以直接排除在选择范围了)
Mac 自带的 rsync 会遇到乱码问题,使用 brew 重新安装
brew install rsync
在安装应用时,有些应用没有上架到 App Store,比如 GoldenDict,Mac 在安装的时候就会提示上面的错误,并且没有办法打开,这个时候就需要到设置中 Security&Pravicy 中,将 Allow apps downloaded from 选项中的 All 打开。
我使用的 Resilio Sync 的后台管理界面使用了 BitTorrent 自己签发的证书,所以 Chrome 中打开的时候会报错“NET::ERR_CERT_INVALID”,普通情况下我知道该风险,在其他操作系统中会提供一个选项,点击高级可以继续访问链接,但是在 Mac 上并没有这个按钮,我搜索了一下,想要尝试信任证书,无果,后来发现一个神奇的方法,在页面中点击空白处,然后输入:thisisunsafe,即可。略神奇。
ssh 客户端会在用户目录 ~/.ssh/
目录下存放配置信息 (~/.ssh/config
) 和公钥和私钥,如果有多个设备不同设备间的同步和管理就会成为一个比较头疼的问题。我在 Reddit 上抛出这个问题 后,我本来想的是通过 git 版本控制来进行管理,但有人说因为公钥和私钥都是二进制的文件,其实没有必要使用 git,任何一个同步工具就能够解决。
不过鉴于国内糟糕的网络环境,我还是通过 git 来管理,最后同步该私有仓库即可。主要注意的是 SSH key 是非常敏感的信息,要注意安全。
用户目录下的 ~/.ssh
目录以及下面的文件需要特别小心的管理其权限,
~/.ssh
目录需要设置 700 (drwx------)
权限644(-rw-r--r--)
600 (-rw-------)
需要保证该目录不会被其他 group 的用户读取和修改。
OpenSSH 客户端的配置文件保存在用户本地的 ~/.ssh/config
文件中,该文件是一个文本文件。.ssh
目录会在用户第一次执行 ssh 命令的时候被创建。如果文件夹不存在,可以直接手动进行创建:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
touch ~/.ssh/config && chmod 600 ~/.ssh/config
ssh 客户端在解析配置时会按照如下顺序:
command line options
user-specific file, located at ~/.ssh/config
system-wide file, /etc/ssh/ssh_config
SSH Config 文件符合如下的结构:
Host hostname1
SSH_OPTION value
SSH_OPTION value
Host hostname2
SSH_OPTION value
Host *
SSH_OPTION value
SSH 客户端配置文件的内容按节(部分)组织。每个部分都以主机指令开始,包含在与远程SSH服务器建立连接时使用的特定SSH选项。
Host指令可以包含一个模式或由空格分隔的模式列表。每个模式可以包含零个或多个非空格字符或以下模式说明符之一:
*
匹配零个或多个字符。例如,Host *
匹配所有主机,而 192.168.0.* 匹配192.168.0.0/24子网中的主机。?
匹配一个字符。模式 Host 10.10.0.?
匹配 10.10.0.[0-9]
范围内的所有主机。!
当在模式的开头使用时,否定匹配。例如,Host 10.10.0.*!10.10.0.5
匹配 10.10.0.0/24
子网中除 10.10.0.5
之外的任何主机。SSH 客户端会逐行读取配置文件,并且如果出现多个匹配的配置,将优先采用第一个出现的匹配模式的选项。因此,具体的主机配置定义应该在文件的开头给出,并且通用的配置应该放在文件的末尾。
可以通过 man ssh_config
查看 ssh options 可配的列表。
SSH config 文件也会被 scp
, sftp
和 rsync
这些命令读取。
上面已经了解了 SSH 配置的一些基本只是,现在来看看一个常见的配置例子:
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_einverne_github
这一段的配置就是当连接 GitHub 的时候直接使用配置的 publickey 去连接。
如果是
ssh -p 2322 alex@dev.example.com
可以配置成
Host dev
HostName dev.example.com
User alex
Port 2322
当添加了这一个配置之后,就可以使用 ssh dev
来直接连接。
SSH config 中可配置字段解释。
用于我们执行 SSH 命令的时候如何匹配到该配置。
*
,匹配所有主机名。*.example.com
,匹配以 .example.com 结尾。!*.dialup.example.com
,*.example.com
,以 ! 开头是排除的意思。192.168.0.?
,匹配 192.168.0.[0-9]
的 IP。是否自动将 key 加入到 ssh-agent,值可以为 no(default)/confirm/ask/yes。
如果是 yes,key 和密码都将读取文件并以加入到 agent ,就像 ssh-add。其他分别是询问、确认、不加入的意思。添加到 ssh-agent 意味着将私钥和密码交给它管理,让它来进行身份认证。
指定连接的时候使用的地址族,值可以为 any(default)/inet(IPv4)/inet6(IPv6)。
指定连接的时候使用的本地主机地址,只在系统有多个地址的时候有用。在 UsePrivilegedPort 值为 yes 的时候无效。
是否响应支持的身份验证 chanllenge,yes(default)/no。
是否压缩,值可以为 no(default)/yes。
压缩等级,值可以为 1(fast)-9(slow)。6(default),相当于 gzip。
退出前尝试连接的次数,值必须为整数,1(default)。
连接 SSH 服务器超时时间,单位 s,默认系统 TCP 超时时间。
是否开启单一网络共享多个 session,值可以为 no(default)/yes/ask/auto。需要和 ControlPath 配合使用,当值为 yes 时,ssh 会监听该路径下的 control socket,多个 session 会去连接该 socket,它们会尽可能的复用该网络连接而不是重新建立新的。
指定 control socket 的路径,值可以直接指定也可以用一下参数代替:
请最大限度的保持 ControlPath 的唯一。至少包含 %h,%p,%r(或者 %C)。
结合 ControlMaster 使用,指定连接打开后后台保持的时间。值可以为 no/yes/ 整数,单位 s。如果为 no,最初的客户端关闭就关闭。如果 yes/0,无限期的,直到杀死或通过其它机制,如:ssh -O exit。
指定是否允许远程主机连接到本地转发端口,值可以为 no(default)/yes。默认情况,ssh 为本地回环地址绑定了端口转发器。
真实的主机名,默认值为命令行输入的值(允许 IP)。你也可以使用 %h,它将自动替换,只要替换后的地址是完整的就 ok。
指定 ssh 只能使用配置文件指定的 identity 和 certificate 文件或通过 ssh 命令行通过身份验证,即使 ssh-agent 或 PKCS11Provider 提供了多个 identities。值可以为 no(default)/yes。
指定读取的认证文件路径,允许 DSA,ECDSA,Ed25519 或 RSA。值可以直接指定也可以用一下参数代替:
指定在连接成功后,本地主机执行的命令(单纯的本地命令)。可使用 %d,%h,%l,%n,%p,%r,%u,%C 替换部分参数。只在 PermitLocalCommand 开启的情况下有效。
指定本地主机的端口通过 ssh 转发到指定远程主机。格式:LocalForward [bind_address:]post host:hostport,支持 IPv6。
是否使用密码进行身份验证,yes(default)/no。
是否允许指定 LocalCommand,值可以为 no(default)/yes。
指定连接远程主机的哪个端口,22(default)。
指定连接的服务器需要执行的命令。%h,%p,%r
如:ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
SSH 登录的用户名
SSH 连接时发生这个错误:
sign_and_send_pubkey: signing failed: agent refused operation
: Permission denied (publickey).
ssh_exchange_identification: Connection closed by remote host
大概率是 ~/.ssh/
目录下私钥的权限不对,找到对应的私钥:
chmod 600 ~/.ssh/id_rsa
Mosh 是 mobile shell
的缩写,Mosh 允许间断性连接,使用传统的 SSH 连接远程设备时,如果遇到一点点的网络问题,SSH 连接就会被中断。Mosh 使用 UDP 传输,相较于 SSH,在漫游网络,Wi-Fi,移动 (cellular) 网络,长距离连接等网络场景下提供了更好的连接体验。
Mosh 提供的一些特性:
安装过程就比较简单了:
apt install mosh
其他平台类似。
指定端口号:
mosh --ssh="ssh -p 2222" someone@host
指定 ssh key:
mosh --ssh="~/bin/ssh -i ./identity" someone@host
Vim 中已经提供了非常多移动的动作,从简单的字符间移动 (jkhl),到 word 间 (w/e/b),句子间 ((
/)
),段落间 ({/}),行首行尾 (0/^/$),文档开始 (gg),文档结尾 (G),还有搜索 (/
/np
) 等等一系列的操作,但 easy-motion 将 Vim 中的移动又提升了一个高度。
继续往下阅读之前先确保阅读了 vim 文档中关于 motion 的内容。
想象一个场景,想要跳转到当前行下一个段落中的第二个句子的第三个单词开头,使用上面提到的方法,可能需要按下不同的按键,并且可能还需要组合使用,那有没有什么方法能降低这个移动(或者说跳转)操作的复杂度呢?答案就是 easy-motion。不知道有多少人用过 Chrome 下的 Vimium 插件,在网页中按下 f
,页面中每一个能点击的地方都会显示几个字符,然后按下字符就会相当于在页面上点击,easy-motion 也使用相同的方式实现这一功能。
easy-motion 插件提供了更强的移动操作,在 easymotion 的官方文档中是这样定义 easymotion 的,easymotion 可以将 <number>w
或者 <number>f{char}
简化为几个按键的操作,举一个简单的例子,在 easymotion 下,如果按下 w
,那么 easymotion 会高亮所有 w
(下一个词首) 的结果,然后只需要按下一个键,就可以跳转到任何 w
按键按下后的目标地址。
Plug 'easymotion/vim-easymotion'
:help easymotion
Easymotion 的触发需要按下两次 <leader><leader>
,当然推荐熟悉之后使用 vim 的 map 配置更改一下 leader.
Default Mapping | Details
---------------------|----------------------------------------------
<Leader>f{char} | Find {char} to the right. See |f|.
<Leader>F{char} | Find {char} to the left. See |F|.
<Leader>t{char} | Till before the {char} to the right. See |t|.
<Leader>T{char} | Till after the {char} to the left. See |T|.
<Leader>w | Beginning of word forward. See |w|.
<Leader>W | Beginning of WORD forward. See |W|.
<Leader>b | Beginning of word backward. See |b|.
<Leader>B | Beginning of WORD backward. See |B|.
<Leader>e | End of word forward. See |e|.
<Leader>E | End of WORD forward. See |E|.
<Leader>ge | End of word backward. See |ge|.
<Leader>gE | End of WORD backward. See |gE|.
<Leader>j | Line downward. See |j|.
<Leader>k | Line upward. See |k|.
<Leader>n | Jump to latest "/" or "?" forward. See |n|.
<Leader>N | Jump to latest "/" or "?" backward. See |N|.
<Leader>s | Find(Search) {char} forward and backward.
| See |f| and |F|.
下面将 <leader><leader>
简写成 <ll>
向后向前跳转
<ll>w
<ll>b
双向跳转
<ll>s
向上向下跳转到行:
<ll>j
<ll>k
虽然使用了很长时间的 Vim,也使用了很长时间的 IntelliJ IDEA,但总感觉没有充分利用,所以想再这里总结一下,系统的浏览一遍 Idea Vim 插件能提供的功能,看看能不能有所受益,Vim 和 IntelliJ IDEA 的基本操作和内容就省略了。
首先 ideavim 这个插件是 JetBrains 官方提供的,基本上安装后即可。GitHub 的页面还提到 ideavim 插件提供了一些 Vim 插件的扩展功能,比如:
可以根据这个页面 上的方式配置和开启这个扩展功能。
~/.ideavimrc
来复用 Vim 的工作方式,以及充分利用 Idea 提供的 ActionIdea 中的 vim-easymotion 插件支持的配置,可以参考这里
在了解 easymotion 时意外收获了 AceJump 插件,IntelliJ IDEA 中的 easymotion 实际上是通过 AceJump 插件来实现的。 :q
默认情况下,使用 Ctrl + ; 来开启 AceJump 模式,不过我的 Ctrl + ;
已经作为输入法的多粘贴板来使用了,所以就改成 Alt + k 。
AceJump 的工作流程,按下 Alt + K 进入 AceJump ,此时按下任何按键就会在当前文件搜索,并给每一个结果一个 tag,按下回车,然后输入 tag 就可以快速跳转过去。
在 IntelliJ IDEA 中,任何选项操作都会映射到一个 action
上,点击按钮,就执行对应的 action
,所以记住 Ctrl + Shift + a 这个快捷键。
在编辑器模式下,可以输入如下命令查看 actionlist:
:actionlist
启用方式:
set surround
支持的 Commands: ys, cs, ds, S
下面的例子中,假设 *
是当前光标的位置:
Old Text | Command | Text After command execute |
---|---|---|
“Hello *world!” | ds” | Hello world! |
[123 + 4*56]/2 | cs]) | (123+456)/2 |
“Look ma, I’m *HTML!” | cs” | <q>Look ma, I'm HTML!</p> |
if *x>3 | ysW( | if ( x>3 ) |
my $str = *www; |
vllS’ | my $str = 'www'; |
vim-surround 在想要改变 surround
的时候非常方便。
目前我的使用场景大部分通过 IDEA 自带的 rename 功能批量替换变量即可做到,所以目前还没有开启这个功能的需求,更多多光标的操作技巧可以参考这篇文章
IdeaVim 支持的所有快捷键:
最后,这里 是我的 .ideavimrc
配置。
前些天正好在我的二代树莓派上安装了 AdGuard Home,这样一个基础服务必然不能少了监控,所以正好把 Prometheus node-exporter 安装一下。
首先确认一下 CPU 型号,我的是二代,比较老,直接 lscpu
看一下就知道:
Model name: ARMv7 Processor rev 5 (v7l)
这是一个 armv5 版本的,然后到 node-exporter 下载二进制:
注意选对版本。
wget https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-armv5.tar.gz
然后接着这篇文章 即可。
最后验证:
curl http://localhost:9100/metrics
添加到 Prometheus Server
- job_name: 'raspberry pi node exporter'
scrape_interval: 5s
scrape_timeout: 5s
static_configs:
- targets: ['192.168.2.3:9100']
之后 Grafana 添加数据源,和之前的文章 一样。
之前也总结过两篇文章,我是如何使用 Clonezilla 进行全盘备份和恢复的 以及备份 Linux 过程中遇到的问题,今天这篇就记录一下恢复之前备份过的 Windows
我先来还原一下现在情况,原来我有两台小米的 Air 笔记本,所有的配置一样,不过一台我从之前的电脑上恢复了一个 Linux Mint 的系统,暂且叫这台 A1 笔记本,然后还有一台是默认的 Windows 系统,不过这一台用的比较少,暂且叫这台 A2 笔记本。前段时间我把 A2 笔记本使用 Clonezilla 备份了一下生成了一个从 device 到 image 的镜像,然后我把 A2 笔记本卖了,所以现在只剩下 A1 笔记本。
我在卖 A2 笔记本的时候,当时也做了系统的恢复,就是把当年 A1 原始的默认 Windows 系统恢复到了 A2 笔记本上,正好省去了我格式化硬盘,备份数据的苦恼,恢复上去之后 A2 没啥问题也可以直接启动。
但今天恢复 A1 笔记时,却遇到了一些问题,这里记录一下。
安装我之前的操作,恢复之前备份的 A2 的硬盘镜像文件到 A1 的整块硬盘上,官网的教程非常详细,这里就略过了,就安装默认的下一步下一步直接走了,可以所有操作完成后等等重启时,屏幕只出现了 “no bootable devices found”,我一想不应该呀,虽然用的是另一台机器的镜像恢复的数据,但是理论上应该还是能找到系统的。
之后还想着是不是引导坏了,还用着 Win PE 进去想修复一下,谁知道在 PE 里面根本找不到系统的硬盘,后来想想是不是恢复的时候把 MBR 搞坏了,还是说默认的 Windows 是安装在 GPT 分区表的硬盘上的。
然后使用如下的方法重新恢复了一次:
然后去 BIOS 中把之前引导 Linux 是的 Legacy 改成了 UEFI Mode,果然就能进入系统了。