selective focus photography of an arrow

目标指引你成功

每一个人都需要一个目标,来帮助你抵达彼岸。不过可惜的是,我们的教育很少教育大家关于目标、关于理想、关于人生价值的内容。这可能是我们的教育的问题。

不过,如果你看到这篇文章,说明你至少不是一个那么普通的人 —— 这年头看独立博客的人已经不多了。

目标存在的意义并不是和很多人想象中那样的无用。每当我和别人提起,“你是否有理想?”、“你找到你的人生母题是什么了么”,大家常常会说:“我的理想就是不用上班”。

但这只是一阶回答,不上班只是表象。那么你不上班之后要做的事情,才是你的理想 —— 它可能是宅在家里打游戏(只要你能一直打下去)、也可能是周游列国,也可能是做你想做的事情。

它是什么并不重要,重要的是,你必须想清楚你的目标(至少是想清楚当下的目标),有了这个目标,你便可以在做出选择的时候,基于你的目标进行纠偏,从多个选择中,找到那个离你的目标更近的选项。

d2b5ca33bd970f64a6301fa75ae2eb22 3

有没有目标,你都有可能抵达/无法抵达终点。但有了目标,可以让你抵达终点的速度变得更快一些。

MacBook Pro on brown wooden table

bundle audit 命令失效怎么办?

我最近在使用 Github 来做 Rails 的 CI 自动检查时,发现 CI 自动检查时使用的 bundle audit 命令失效了,搜索后发现,是 Bundle 将 audit 拆为了单独的 gem ,而 CI 的模板并未更新,导致在调用的时候出现了错误。

d2b5ca33bd970f64a6301fa75ae2eb22 1

既然明确了问题,解决就变得简单了。只需要在 CI 的脚本当中,加入对应的 gem 安装命令,即可完成修复。

  - name: Install bundle audit
        run: gem install bundler-audit

black flat screen computer monitor

通过 Code Snippet 提升效率

在开发应用的时候,我们常常会借助快速生成工具来帮助我们生成一些模板代码。

相比于 JS,Ruby 干脆让很多需要手动输入的地方可以不用输入,体验会更好。Rails 更是做到了极致,大量的约定。对于一些模板化的行为,你甚至可以不用写代码,框架帮你来解析。

常见的编辑器比如 VSCode、Sublime Text 都提供了大量基于插件的 Code Snippets,方便你可以快速生成一段模板代码。

不过在实际开发过程中,他们提供的模板代码可能并不太符合我们的需求,我们往往可能会有一些定制化的需求需要满足,这个时候,就比较依赖自定义模板了。

好在各种编辑器不止可以通过插件来定义 Code Snippet,你还可以自定义自己需要的 Code Snippet。

以 VSCode 为例,你可以参考其官方文档来定义自己需要的 Code Snippet,只需要简单的配置,就可以定义出你自己所需要的 Code Snippet。它可以是你自己写代码时的 Code Snippet,也可以是你在写博客时的 Code Snippet(比如写博客时自动生成前置的描述信息)。

不过,Code Snippet 的语法很多时候比较麻烦,需要一行一个字符串,对于较为复杂的 Code Snippet,构建这个 Code Snippet 本身就比较麻烦。好在有一些第三方工具,可以帮助简化这个过程。比如 Snippet Generator 就可以非常方便的帮助生成 VSCode 的语法,你只需要将需要生成模板的代码粘贴在左侧,并填写一些基本信息,就可以生成包括 VSCode、Sublime、Atom 的 Code snippet 代码,再将其粘贴到你的 VSCode 的配置中即可。

d2b5ca33bd970f64a6301fa75ae2eb22
Snippet Generator

你还可以将其中的一部分内容替换为对应编辑器所提供的占位符,就可以帮助你更加高效的利用这个 Snippet 来完成内容的快速撰写。

其他

text

如何用 SSH Config 来优化你的 SSH 连接?

在 Windows 的时候,我一度非常喜欢使用诸如 XShell 之类的软件,主要原因是我可以将不同的服务器信息保持在同一个软件当中,不用每次都手动保存(Putty往往就无法保存)。

而到了 macOS 之后,我不再使用 XShell 这样的软件来完成我的 SSH 工作流(事实上我也找不到类似 XShell 的软件,后来在 Setapp 软件包中发现了 Core Shell,但我已经有了下面的技巧了,就没再用)。

经过一番研究,我发现对于我的诉求来说,其实完全没必要使用一款第三方软件来完成,SSH 自带的功能即可完成。

再次 Review 一下我的诉求:

  1. 我希望不要输入 IP 地址,而是输入一个短语,或者是域名来连接我的服务器。
  2. 我希望能够支持自定义端口,因为我一般会把我的服务器端口从 22 改为一个随机的数字。
  3. 我希望可以指定密钥文件,因为我有多个密钥,不通的场景可能使用不同的密钥。

这些诉求如今我的新方法都可以实现。

SSH 支持自定义 Config 文件,而默认的 Config 文件位于 ~/.ssh/config 这个文件中,你可以在其中添加自己的配置来实现自定义 SSH。

比如这里用到的就是 SSH Config 中的 Host 定义,你可以以如下的规则来定义一个新的配置。

Host 主机名
    User 登录用的用户名
    HostName 登录用的主机名,可以是域名或者IP
    Port 登录用的端口号
    IdentityFile 需要使用的密钥文件

比如下图就是一个配置的例子

d2b5ca33bd970f64a6301fa75ae2eb22 3

通过在你的 Config 文件当中添加对应的定义,你就可以用 ssh 主机名 的方式来连接你的服务器了。

比如,我的树莓派的配置的主机名是 pi 那我就可以使用 ssh pi 的方式来连接到我的树莓派当中。

d2b5ca33bd970f64a6301fa75ae2eb22 5
shallow focus photography of man in suit jacket's back

稀缺、抗压与升职加薪

用发展的眼光看待自己的工作和生活当中,我提到,不少人总是在用静态的眼光看待自己。这些人不只使用静态的眼光看待自己,也一直在使用一个相对更加低阶的身份定位来锚定自己。

很多人没有意识到,你的薪资其实和两个部分有关:

  1. 你所掌握的技能在市场上的稀缺程度。
  2. 你所能承担的责任和担负的压力。

大部分秉承着「拿钱办事」心态的人,都在这两个点上做的不够好,一方面没有自己独特的技能点和生态位,导致在市场发生剧烈波动时,很容易因为没有任何特色而发生替换。另一方面,由于心态是「拿钱办事」,自然不愿意去承担更大的压力和责任。

而对于公司来说,一个极其标准化,没有任何稀缺性的产品,自然是不会给你升职加薪的;而这个产品如果也不愿意承担责任和压力,那我是真的想象不到有什么理由来为这样的一个产品支付更高的费用。

如果你发现自己很久没有升职加薪,不妨回过头来看看,自己是否满足了升职加薪的基本条件?

Several white arrows pointing upwards on a wooden wall

用发展的眼光看待自己的工作和生活

我在生活中遇到不少对于工作理解较为简单和质朴的人 —— 他们奉行工作就是给多少钱办多少事,不愿意去做分外之事。当然,严格意义来说,这样并没有错。毕竟,我们不应该鼓励他人去当卷王。

但我想说另外一个观点:工作当中,薪酬当然重要;但更重要的是你投入了你的时间和生命来为这件事付出。如果从这个视角来看,你应该从你所做的事情中收获更多的价值,这些价值不应该只是金钱。

尝试用发展的眼光去看待我们的工作和生活,你就会发现,工作不仅仅是你当下的价值,也同样代表着你未来的可能性。你可以通过工作来提升自己的技能,你可以通过工作来为自己拓展可能性。

你必须意识到,人的一生是一个无限游戏,在无限游戏中,你需要不断的闯关。并没有一个明确的关卡是你已经完成了所有的事情,生活也好,工作也罢,总是会有更多的问题和挑战来袭。你需要在这个无限游戏中不断的提升自己、不断的让自己变得更强,才能不断的坦然面对来自工作和生活的挑战。

大部分将工作看作「拿钱办事」的人,往往是秉承着「我就是一个静态的人」的心态来看,即使他内心并不这样看,但确实做着这样的选择。但生活并不是静态的,你面临的问题也不是静态的,你唯一要做和唯一能做的,便是用发展的眼光看待问题,正视自己在做的每一件事,并通过每一件事提升自己。

text

在油猴脚本中实现新增按钮和按钮的点击效果

在油猴脚本中,有些时候,我们需要在界面当中添加一个新的按钮。这个时候我们可以使用 document.getElementById("id").innerHTML=xxx 来指定某个元素中的内容是特定的 HTML,从而实现添加一个新的按钮。

但在这个按钮上绑定事件则不是通过简单的指定 button 的 onclick 来完成的。核心原因是默认情况下,你在油猴脚本中所写的函数只运行在油猴脚本中的 Scope ,而 button 则是运行在 Document 的 Scope 下。直接绑定事件在触发时会无法找到对应的函数。

一个好的办法是为你新增的 Button 带上 ID,并通过 ID 找到对应的 Element 并添加事件绑定来实现。

参考代码如下:

// ==UserScript==
// @name         示例代码
// @namespace    https://www.ixiqin.com
// @version      0.0.1
// @description  示例代码
// @author       bestony
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';
  window.addEventListener('load', function () {
    function viewAuthor() {
      // button click event
    }

    var targetElement =document.getElementById("xxx")

    targetElement[0].innerHTML = targetElement[0].innerHTML + ` &nbsp;<a id="view-author">查看作者</a>`

    var link = document.getElementById("view-author");
    if (link) {
      link.addEventListener("click", viewAuthor, false);
    }
  }, false);
})();
Code language: JavaScript (javascript)
text

油猴脚本不支持 Modules Javascript 导致空白脚本报错

最近在写一个油猴脚本时,因为懒得写 DOM 处理函数,我试图在油猴脚本当中引入 Zepto.js, 用于实现 DOM 操作。

d2b5ca33bd970f64a6301fa75ae2eb22

但在引入 Zepto 之后,发现即使是空白的脚本文件,在网页加载时依然会报错。经过排查发现,是我引入的 Zepto 文件导致的,进一步研究后发现,之所以有这个问题,是目前油猴脚本仍不支持 Modules ,因此,我引入 Zepto 就会报错。

想要解决这个问题倒是也简单,将 Zepto 替换为 JQuery 即可。本来想着用 Zepto 会轻量一点, 最后发现还是要上 JQuery。好在是目前 JQuery 提供了不含 Ajax 和 Effect 的 Slim 版本,倒是也不用担心引入的依赖文件特别的大。

灵光一闪

拥抱湿货

早年间我对于干货有着迷恋,总感觉自己需要干货来快速学习、快速成长。但随着时间的推移,我对于干货的需求越来越少,反而是愈加喜欢「湿货」。

回想自己当年,喜欢湿货大抵是因为时间不足,总想着用最短的时间,学习最多的知识,成为强者。所以能够短时间收获大量信息的「干货」就成为那个年纪的最爱。

但随着回到天津,生活节奏放缓,开始放过自己,不再追求成为强者。开始对于时间、节奏有了更多的容忍度。不再追求用最短的时间学习到最多的知识,也就对于「干货」没了那么强的诉求。

当然,更重要的是,我意识到,「干货」的好处是通过压缩信息量,让你可以最短时间获得到了最多的知识,但另外一个层面来看,也使得这些「干货」失去了执行的可能性,我们并不能直接从这些干货当中得到什么(嗯,这段话还有点追求得到的意味)。而湿货,虽然没有高度压缩的信息,但却提供了丰富的上下文,让我们可以知道一个道理、一个方法的适用场景、使用手段等一系列信息,帮助我们更好的改进我们的生活。

干货我们往往得到的是「我知道很多道理,却过不好这一生」,而湿货,却可以真真切切的指导我们的生活。

email

一个邮件转发服务 – Forward Email

我并没有自建一套邮件服务器(主要是懒得维护),但我又需要邮件转发服务,所以我选择了使用 ForwardEmai 的服务。

Forward Email 是一个开源的产品,并基于开源的版本提供了 SaaS 的产品,如果你懒得维护自己的服务器,则可以使用他们的 SaaS 产品。

在使用上颇为简单,添加域名、配置 MX 记录,设置 TXT 记录,就可以实现转发功能了,从而实现我之前提到过的 数字所有权 中的实现。对于没有技术背景的人来说,这可能是成本最低获得个人域名邮箱的方式方法了。

Github 开源地址:https://github.com/forwardemail/forwardemail.net

服务地址:https://forwardemail.net/