米米的博客

做了一点微小的工作

ssh 连接远程服务器时,如果连接断开,那么当前的进程就会被杀死。运行系统备份或 ftp 传输这样耗时较长的任务,ssh 不方便一直挂着,那该怎么办呢?这种情况的应对方法是 GNU Screen,一款由 GNU 计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。

在执行快速和简单的任务时,往往不会使用 screen,因为这没有必要。但是,如果发现正在运行的任务花费的时间比预期的要长得多,或者只是单纯地忘记了在执行命令前进入 screen,该怎么办呢?这时退出 ssh 就会导致前功尽弃。在这种情况下,我们剩下三个选择:

  • 一直保持 ssh 连接,但不知道要等到什么时候
  • 退出当前进程,丢失所有未保存的工作,并可能浪费大量的时间来处理,或者
  • 将正在运行的进程移至新的 screen 中。这是笔者将在后文中描述的解决方案。

操作步骤如下。

挂起进程

我们需要做的第一件事是通过按 Ctrl+Z 挂起当前的进程。
这会向进程发送一个 TSTP 信号 —— 停止执行进程,并且内核将不再为该进程安排更多的 CPU 时间。

在后台恢复进程

输入 bg 命令。这会将 SIGCONT 信号发送到该进程,现在它会在后台欢快地运行起来。

disown 进程

现在,我们像这样运行 disown 命令:

1
disown %1

disown 从活动作业表中删除该进程,从本质上允许该进程被另一个会话接管。

新开 screen

执行 screen 即可,进入一个新的 screen 会话中。

查找进程的 PID

现在,我们需要找到要接管的进程的 PID。笔者使用和推荐的方法是 pgrep。例如,如果我们的进程称为 myprogram,则可以运行 pgrep myprogram 命令,该命令将返回其 PID。

使用 reptyr 接管进程

最后,我们将 PID 传递给 reptyr 来接管该进程。如果 pgrep 给我们的 PID 为 1234,我们现在可以使用以下命令:

1
reptyr 1234

最后两步也可以合在一起:

1
reptyr $(pgrep myprogram)

如果提示找不到 reptyr 命令,可以用包管理工具安装一下。reptyr 的源码在这个 GitHub 仓库中。


本文翻译自:Move a running process to screen

你们可能不知道,用 40 血通杀全场是什么概念。我们一般只会用四个字来形容这种人 —— 米尔菲斯。

我经常说一句话,当年卢本伟开自瞄爆头 29 杀,我巫妖巴兹亚尔锁 1 血不是问题。

埋伏他一手,这个牌不用捡,不能捡。他死定了。

扩展运算符(Spread operator)是 ES6 语法,推出距今已有数年,可以放心地在浏览器中使用。它有几种用例能让 JavaScript 代码更加简洁高效,本文将作一个梳理。

以数组形式传递参数

有时一个函数有很多参数,我们希望能够以一个 Array 的形式传递参数,数组的每个元素对应一个参数。JavaScript 提供了 Function.prototype.apply,用法如下。

1
2
3
4
function doStuff (x, y, z) {}
var args = [0, 1, 2];
// Call the function, passing args
doStuff.apply(null, args);

而通过扩展运算符,我们可以避免使用 apply 并且达到同样的效果。

1
doStuff(...args);

代码更少,更干净,而且不需要使用多余的 null

作用于数组

扩展运算符可以用来代替 concatslice 这些数组函数。

1
2
3
4
5
6
// joining arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6].concat(odd);
// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = arr.slice()

简写:

1
2
3
4
5
6
7
// joining arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6, ...odd];
console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]
// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = [...arr];

不像 concat 函数,可以使用扩展运算符来在一个数组中任意处插入另一个数组。

1
2
const odd = [1, 3, 5];
const nums = [2, ...odd, 4, 6];

展开 HTMLCollection

此外,扩展运算符在前端还有一个应用场景。通过 Element.children 选择的元素,返回的是一个 HTMLCollection 对象而非 Array。这意味着你不能直接调用 forEach 方法来遍历它,而是需要一些额外的代码。比较简单的有这样几种:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var targets = document.body.children;

[].forEach.call(targets, function(target) {
target.style.color = "red";
});

for (var i = 0; i < targets.length; ++i) {
targets[i].style.color = "green";
}

for (var target of targets) {
target.style.color = "blue";
}

Array.from(targets).forEach(function(target) {
target.style.color = "orange";
});

而直接使用扩展运算符展开 HTMLCollection 是这样的:

1
2
3
[...document.body.children].forEach(function(target) {
target.style.color = "black";
});

同理,document.querySelectorAll 返回的 NodeList 对象有 forEach 方法,但是却没有 map 方法。使用拓展运算符可以优美地解决这个问题。

1
2
3
[...document.querySelectorAll("p")].map(function(target) {
return target.innerText;
});

在 Hexo 的 NexT 主题中,就多次使用了这一技巧。

解构对象

JavaScript 对象也可以使用扩展运算符解构:

1
2
3
4
const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a) // 1
console.log(b) // 2
console.log(z) // { c: 3, d: 4 }

拆分字符串

用扩展运算符将字符串拆分成字符组成的数组。一个典型的例子是:

1
2
const str = "hello";
[...str]; // => ['h', 'e',' l',' l', 'o']

就连 Emoji 也能扩展

很多 Emoji 字符不是独立的 Unicode 字符,而是由多个 Emoji 组合而成。最常见的就是家庭 Emoji 和有肤色的 Emoji,例如👪和👨‍👩‍👧‍👧。这点在前面的文章 Unicode 字符与颜文字表情中也有提到。
神奇的事情是,如果使用扩展运算符的话,它们是可以拆散的!

这些复合 Emoji 字符甚至还允许做替换,形成新的 Emoji 字符。

不得不说这是一种绝妙的使用方式。


拓展阅读:[译] 6 种 JavaScript 展开操作符的绝妙使用

Boot Loader,或「引导程序」,是一个特殊的固件。对于 Arduino 单片机而言,每次按下复位键,或者编译上传新的程序时,都会先加载烧录的 Boot Loader;随后 Boot Loader 再来执行程序,或者根据电脑的指令,将新程序的代码写入闪存中。
在我们平常使用的 Arduino 开发板上,Boot Loader 是预置好的,用户只需要写程序然后上传,而不用关心其它的问题。但在有些情况下,还是需要用户自己来烧录 Boot Loader。例如,Arduino Nano 板有新旧两种 Boot Loader,升级旧的固件就需要重新烧录 Boot Loader。一些第三方厂家根据 Arduino 开源的电路图修改制造的开发板,也需要向其中的 ATmega 微控制器刷 Boot Loader 才能正常工作。

烧录 Boot Loader 的方式有很多种。在 Arduino IDE 的菜单中,选择「工具」 → 「编程器」,即可查看官方支持的方法:

本文将介绍其中的一种方法:使用另一块 Arduino 开发板,作为 ISP(即 in-system programmer),来进行烧录。为了避免歧义,我们将功能正常的版称为「ISP 板」,而需要烧录 Boot Loader 的版称为「空板」。在具体的例子中,将一块「Arduino Leonardo」作为「ISP 板」,一块「Arduino Mega 2560」作为「空板」。

上传程序

将「ISP 板」连接到电脑,并移除其它所有线缆。打开 Arduino IDE,在菜单中选择「文件」 → 「示例」 → 「11.ArduinoISP」 → 「ArduinoISP」。这是一个将 Arduino 变为 AVRISP 的程序,将其编译上传到「ISP 板」即可。

阅读全文 »

Charles 是一个功能强大的抓包软件,而 Proxifier 可以将流量通过 Socks5 或 http 代理进行转发。两者配合起来,即可完成对于手机应用或者命令行应用的流量代理和分析。本文将介绍它们的下载、安装和破解方法。

Charles

Charles 的官方下载页面是:https://www.charlesproxy.com/download/
完成下载后,将 Charles 拖进应用程序目录中。此时,一定要先启动一次,Charles 会提示你这是试用版本,需要进行注册。随后,再根据此网页进行破解即可,注意要选择正确的版本:https://www.zzzmode.com/mytools/charles/
破解程序的源代码在此:https://github.com/8enet/Charles-Crack

Proxifier

Proxifier 的官方下载页面是:https://www.proxifier.com/download/
安装方法类似,完成安装后打开 Proxifier 菜单栏中的 Help → Registration,Name 随便输入自己的即可,Key 输入 P427L-9Y552-5433E-8DSR3-58Z68。如果没有问题的话,注册成功,可以愉快地使用了。

0%