mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-21 02:10:11 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
73d3238a05
@ -1,19 +1,20 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12872-1.html)
|
||||
[#]: subject: (Add throwing mechanics to your Python game)
|
||||
[#]: via: (https://opensource.com/article/20/9/add-throwing-python-game)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
在你的 Python 游戏中添加投掷技巧
|
||||
在你的 Python 游戏中添加投掷机制
|
||||
======
|
||||
四处奔跑躲避敌人是一回事。反击敌人是另一回事。
|
||||
学习如何在这系列的第十二篇文章中创建在 Pygame 中的平台游戏
|
||||
![使用企鹅兵来在格子上完游戏][1]
|
||||
|
||||
这是仍在进行中的关于使用 [Pygame][3] 模块来 [Python 3][2] 中创建电脑游戏的第十二部分。先前的文章是:
|
||||
> 四处奔跑躲避敌人是一回事,反击敌人是另一回事。学习如何在这系列的第十二篇文章中在 Pygame 中创建平台游戏。
|
||||
|
||||

|
||||
|
||||
这是仍在进行中的关于使用 [Pygame][3] 模块在 [Python 3][2] 中创建电脑游戏的第十二部分。先前的文章是:
|
||||
|
||||
1. [通过构建一个简单的掷骰子游戏去学习怎么用 Python 编程][4]
|
||||
2. [使用 Python 和 Pygame 模块构建一个游戏框架][5]
|
||||
@ -27,25 +28,22 @@
|
||||
10. [在你的 Python 平台类游戏中放一些奖励][13]
|
||||
11. [添加计分到你的 Python 游戏][14]
|
||||
|
||||
我的上一篇文章本来是这一系列文章的最后一篇,它鼓励你为这个游戏编写自己的附加程序。你们很多人都这么做了!我收到了一些电子邮件,要求帮助我还没有涵盖的常用机制:战斗。毕竟,跳起来躲避坏人是一回事,但是有时候让他们走开是一件非常令人满意的事。在电脑游戏中向你的敌人投掷一些物品是很常见的,不管是一个火球、一支箭、一道闪电,还是其它适合游戏的东西。
|
||||
|
||||
与迄今为止你在这个系列中为你的平台游戏编程的任何东西不同,可投掷物品有一个*生存时间*。在你投掷一个物品后,它会如期在移动一段距离后消失。如果它是一支箭或其它类似的东西,它可能会在通过屏幕的边缘时而消失。如果它是一个火球或一道闪电,它可能会在一段时间后熄灭。
|
||||
|
||||
上一篇文章是这一系列文章的最后一篇,它鼓励你为这个游戏编写自己的附加程序。你们很多人都这么做了!我收到了一名普通的机械师的一些电子邮件,要求帮助我还没有涵盖的服务:战斗。毕竟,跳起来躲避坏人是一回事,但是有时候让他们走开是一件非常令人满意的事。在电脑游戏中向你的敌人投掷一些东西是很常见的,不管是一个火球,一支箭,一道闪电,还是其它适合游戏的东西。
|
||||
|
||||
在这个系列中,到目前为止,投掷项目不像你在平台类游戏中编程的任何东西,它有一个 _生存时间_。 在你投掷一个对象后,它会如期在移动一段距离后消失。如果它是一支箭或其它类似的东西,它可能会在通过屏幕的边缘时而消失。如果它是一个火球或一道闪电,它可能会在一段时间后熄灭。
|
||||
|
||||
这意味着每次生成一个可丢弃的项目时,它的生存时间也必需生成一个独特的衡量标准。为了介绍这个概念,这篇文章演示如何一次只投掷一个项目。(换句话说,每次仅存在一个投掷项目)。 一方面,这是一个游戏的限制条件,但另一方面,它却是游戏本身的运行机制。你的玩家不能每次都投掷 50 个火球,因为每次仅允许一个投掷项目,所以当你的玩家释放一个火球来尝试击中一名敌人就成为了的一项挑战。在幕后,这也使你的代码保持简单。
|
||||
这意味着每次生成一个可投掷的物品时,也必须生成一个独特的衡量其生存时间的标准。为了介绍这个概念,这篇文章演示如何一次只投掷一个物品。(换句话说,每次仅存在一个投掷物品)。 一方面,这是一个游戏的限制条件,但另一方面,它却是游戏本身的运行机制。你的玩家不能每次同时投掷 50 个火球,因为每次仅允许一个投掷物品,所以当你的玩家释放一个火球来尝试击中一名敌人就成为了一项挑战。而在幕后,这也使你的代码保持简单。
|
||||
|
||||
如果你想启用每次投掷多个项目,在完成这篇教程后,通过学习这篇教程所获取的知识来挑战你自己。
|
||||
|
||||
### 创建 throwable 类
|
||||
|
||||
如果你跟随学习这系列的其它文章,那么你应该熟悉基础的在屏幕上生成一个新的对象的 `__init__` 函数。这和你用来生成你的 [玩家][6] 和 [敌人][8] 的功能是一样的。这里是一个 `__init__` 函数来生成一个 投掷对象:
|
||||
### 创建 Throwable 类
|
||||
|
||||
如果你跟随学习这系列的其它文章,那么你应该熟悉在屏幕上生成一个新的对象基础的 `__init__` 函数。这和你用来生成你的 [玩家][6] 和 [敌人][8] 的函数是一样的。这里是生成一个 `throwable` 对象的 `__init__` 函数来:
|
||||
|
||||
```
|
||||
class Throwable(pygame.sprite.Sprite):
|
||||
"""
|
||||
生成一个投掷对象
|
||||
生成一个 throwable 对象
|
||||
"""
|
||||
def __init__(self, x, y, img, throw):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
@ -58,21 +56,18 @@ class Throwable(pygame.sprite.Sprite):
|
||||
self.firing = throw
|
||||
```
|
||||
|
||||
同你的 `Player` 类或 `Enemy` 类的 `__init__` 函数相比,这个函数的主要区别是,它有一个 `self.firing` 变量。这个变量保持跟踪一个投掷对象是否在当前屏幕上活动,因此当一个投掷对象创建时,将变量设置为 `1` 的合乎情理的。
|
||||
同你的 `Player` 类或 `Enemy` 类的 `__init__` 函数相比,这个函数的主要区别是,它有一个 `self.firing` 变量。这个变量保持跟踪一个投掷的物品是否在当前屏幕上活动,因此当一个 `throwable` 对象创建时,将变量设置为 `1` 的合乎情理的。
|
||||
|
||||
### 判断活动时间
|
||||
### 判断存活时间
|
||||
|
||||
接下来,就像使用 `Player` 和 `Enemy` 一样,你需要一个 `update` 函数,以便投掷对象在瞄准敌人抛向空中时,它会自己移动。
|
||||
接下来,就像使用 `Player` 和 `Enemy` 一样,你需要一个 `update` 函数,以便投掷的物品在瞄准敌人抛向空中时,它会自己移动。
|
||||
|
||||
测定一个投掷对象活动时间的最简单方法是侦测它何时离开屏幕。你需要监视的屏幕边缘取决于你投掷对象的物理特性。
|
||||
测定一个投掷的物品存活时间的最简单方法是侦测它何时离开屏幕。你需要监视的屏幕边缘取决于你投掷的物品的物理特性。
|
||||
|
||||
* 如果你的玩家正在投掷的东西是沿着水平轴快速移动的,像一只弩箭或箭或一股非常快的魔法力量,而你想监视你游戏屏幕的水平轴极限。这可以通过 `worldx` 定义。
|
||||
* 如果你的玩家正在投掷的东西是沿着垂直方向或同时沿着水平方向和垂直方向移动的,那么吗必需监视你游戏屏幕的垂直轴极限。这可以通过 `worldy` 定义。
|
||||
|
||||
|
||||
|
||||
这个示例假设你的投掷对象向前移动一点并最终落地地面上。不过,投掷对象不会从地面上反弹起来,而是继续掉落出屏幕。你可以尝试不同的设置来看看什么最适合你的游戏:
|
||||
* 如果你的玩家正在投掷的物品是沿着水平轴快速移动的,像一只弩箭或箭或一股非常快的魔法力量,而你想监视你游戏屏幕的水平轴极限。这可以通过 `worldx` 定义。
|
||||
* 如果你的玩家正在投掷的物品是沿着垂直方向或同时沿着水平方向和垂直方向移动的,那么你必须监视你游戏屏幕的垂直轴极限。这可以通过 `worldy` 定义。
|
||||
|
||||
这个示例假设你投掷的物品向前移动一点并最终落到地面上。不过,投掷的物品不会从地面上反弹起来,而是继续掉落出屏幕。你可以尝试不同的设置来看看什么最适合你的游戏:
|
||||
|
||||
```
|
||||
def update(self,worldy):
|
||||
@ -87,21 +82,20 @@ class Throwable(pygame.sprite.Sprite):
|
||||
self.firing = 0 #解除火力发射
|
||||
```
|
||||
|
||||
为使你的投掷对象移动地更快,增加 `self.rect` 的动量值。
|
||||
为使你的投掷物品移动地更快,增加 `self.rect` 的动量值。
|
||||
|
||||
如果投掷对象不在屏幕上,那么对象将被销毁,以及释放其所占用的寄存器。另外,`self.firing` 将被设置回 `0` 以允许你的玩家来进行另一次射击。
|
||||
如果投掷物品不在屏幕上,那么该物品将被销毁,以及释放其所占用的寄存器。另外,`self.firing` 将被设置回 `0` 以允许你的玩家来进行另一次射击。
|
||||
|
||||
### 设置你的投掷对象
|
||||
|
||||
就像使用你的玩家和敌人一样,你必需在你的 setup 部分中创建一个精灵组来保持投资对象。
|
||||
就像使用你的玩家和敌人一样,你必须在你的设置部分中创建一个精灵组来保持投掷对象。
|
||||
|
||||
此外,你必需创建一个非活动的投掷对象来供开始的游戏使用。如果在游戏开始时却没有一个投掷对象,那么玩家在第一次尝试投掷一柄武器时,投掷将失败。
|
||||
此外,你必须创建一个非活动的投掷对象来供开始的游戏使用。如果在游戏开始时却没有一个投掷对象,那么玩家在第一次尝试投掷一柄武器时,投掷将失败。
|
||||
|
||||
这个示例假设你的玩家使用一个火球作为开始的武器,因此,每一个投掷实例都是由 `fire` 变量指派的。在后面的关卡中,当玩家获取新的技能时,你可以使用相同的 `Throwable` 类来引入一个新的变量以使用一张不同的图像。
|
||||
|
||||
在这代码块中,前两行已经在你的代码中,因此不要重新键入它们:
|
||||
|
||||
|
||||
```
|
||||
player_list = pygame.sprite.Group() #上下文
|
||||
player_list.add(player) #上下文
|
||||
@ -111,14 +105,13 @@ firepower = pygame.sprite.Group()
|
||||
|
||||
注意,每一个投掷对象的起始位置都是和玩家所在的位置相同。这使得它看起来像是投掷对象来自玩家。在第一个火球生成时,使用 `0` 来显示 `self.firing` 是可用的。
|
||||
|
||||
### 在主循环中获取 throwing
|
||||
### 在主循环中获取投掷行为
|
||||
|
||||
没有在主循环中出现的代码将不会在游戏中使用,因此你需要在你的主循环中添加一些东西,以便能在你的游戏世界中获取投掷东西。
|
||||
没有在主循环中出现的代码不会在游戏中使用,因此你需要在你的主循环中添加一些东西,以便能在你的游戏世界中获取投掷对象。
|
||||
|
||||
首先,添加玩家控制。当前,你没有火力触发器。在键盘上的按键是有两种状态的:按键能够在上面,也能够在下面。为了移动,你要使用这两种状态:按下按键来启动玩家移动,释放按键 ( 按键是在上面的 ) 来停止玩家移动。开火仅需要一个信号。你使用哪个按键事件 ( 按键按下或按键释放 ) 来触发你的投掷对象取决于你的品味。
|
||||
|
||||
在这个代码语句块中,前两行是用于上下文的:
|
||||
首先,添加玩家控制。当前,你没有火力触发器。在键盘上的按键是有两种状态的:释放的按键,按下的按键。为了移动,你要使用这两种状态:按下按键来启动玩家移动,释放按键来停止玩家移动。开火仅需要一个信号。你使用哪个按键事件(按键按下或按键释放)来触发你的投掷对象取决于你的品味。
|
||||
|
||||
在这个代码语句块中,前两行是用于上下文的:
|
||||
|
||||
```
|
||||
if event.key == pygame.K_UP or event.key == ord('w'):
|
||||
@ -129,10 +122,9 @@ firepower = pygame.sprite.Group()
|
||||
firepower.add(fire)
|
||||
```
|
||||
|
||||
与你在你 setup 部分创建的火球不同,你使用一个 `1` 来设置 `self.firing` 为不可用。
|
||||
|
||||
最后,你必需更新和绘制你的投掷对象。这个顺序很重要,因此把这段代码放置到你现有的 `enemy.move` 和 `player_list.draw` 的代码行之间:
|
||||
与你在设置部分创建的火球不同,你使用一个 `1` 来设置 `self.firing` 为不可用。
|
||||
|
||||
最后,你必须更新和绘制你的投掷物品。这个顺序很重要,因此把这段代码放置到你现有的 `enemy.move` 和 `player_list.draw` 的代码行之间:
|
||||
|
||||
```
|
||||
enemy.move() # 上下文
|
||||
@ -144,18 +136,17 @@ firepower = pygame.sprite.Group()
|
||||
enemy_list.draw(screen) # 上下文
|
||||
```
|
||||
|
||||
注意,这些更新仅在 `self.firing` 变量被设置为 1 时执行。如果它被设置为 0 ,那么 `fire.firing` 就不是真的,接下来就跳过更新。如果你尝试做上述这些更新,不管怎样,你的游戏都会崩溃,因为在游戏中将不会更新或绘制一个 `火球` 对象。
|
||||
注意,这些更新仅在 `self.firing` 变量被设置为 1 时执行。如果它被设置为 0 ,那么 `fire.firing` 就不为 `true`,接下来就跳过更新。如果你尝试做上述这些更新,不管怎样,你的游戏都会崩溃,因为在游戏中将不会更新或绘制一个 `fire` 对象。
|
||||
|
||||
启动你的游戏,尝试挑战你的武器。
|
||||
|
||||
### 检测碰撞
|
||||
|
||||
如果你玩使用新投掷技巧的游戏,你可能会注意到,你可以投掷对象,但是它却不会对你的敌人有任何影响。
|
||||
如果你玩使用了新投掷技巧的游戏,你可能会注意到,你可以投掷对象,但是它却不会对你的敌人有任何影响。
|
||||
|
||||
原因是你的敌人没有被查到碰撞事故。一名敌人可能会被你的投掷对象所击中,但是敌人却从来不知道被击中了。
|
||||
|
||||
你已经在你的 `Player` 类中完成了碰撞检测,这非常类似。在你的 `Enemy` 类中,添加一个新的 `update` 函数:
|
||||
原因是你的敌人没有被查到碰撞事故。一名敌人可能会被你的投掷物品所击中,但是敌人却从来不知道被击中了。
|
||||
|
||||
你已经在你的 `Player` 类中完成了碰撞检测,这非常类似。在你的 `Enemy` 类中,添加一个新的 `update` 函数:
|
||||
|
||||
```
|
||||
def update(self,firepower, enemy_list):
|
||||
@ -169,8 +160,7 @@ firepower = pygame.sprite.Group()
|
||||
|
||||
代码很简单。每个敌人对象都检查并看看它自己是否被 `firepower` 精灵组的成员所击中。如果它被击中,那么敌人就会从敌人组中移除和消失。
|
||||
|
||||
为集成这些功能到你的游戏之中,在主循环中调用位于新触发语句块中的函数:
|
||||
|
||||
为集成这些功能到你的游戏之中,在主循环中调用位于新触发语句块中的函数:
|
||||
|
||||
```
|
||||
if fire.firing: # 上下文
|
||||
@ -181,14 +171,13 @@ firepower = pygame.sprite.Group()
|
||||
|
||||
你现在可以尝试一下你的游戏了,大多数的事情都如预期般的那样工作。不过,这里仍然有一个问题,那就是投掷的方向。
|
||||
|
||||
### 更改投掷技巧的方向
|
||||
### 更改投掷机制的方向
|
||||
|
||||
当前,你英雄的火球只会向右移动。这是因为 `Throwable` 类的 `update` 函数将像素添加到火球的位置,在 Pygame 中,在 X 轴上一个较大的数字意味着向屏幕的右侧移动。当你的英雄转向另一个方向时,你可能希望它投掷的火球也抛向左侧。
|
||||
|
||||
到目前为止,你已经知道如何实现这一点,至少在技术上是这样的。然而,最简单的解决方案却是使用一个变量,在一定程度上对你来说可能是一种新的方法。一般来说,你可以 "设置一个标记" ( 有时也被称为 "转刀" ) 来标明你的英雄所面向的方向。在你做完后,你就可以检查这个变量来得知火球是向左移动还是向右移动。
|
||||
|
||||
首先,在你的 `Player` 类中创建一个新的变量来代表你的游戏所面向的方向。因为我的游戏天然地面向右侧,由此我把面向右侧作为默认值:
|
||||
到目前为止,你已经知道如何实现这一点,至少在技术上是这样的。然而,最简单的解决方案却是使用一个变量,在一定程度上对你来说可能是一种新的方法。一般来说,你可以“设置一个标记”(有时也被称为“翻转一个位”)来标明你的英雄所面向的方向。在你做完后,你就可以检查这个变量来得知火球是向左移动还是向右移动。
|
||||
|
||||
首先,在你的 `Player` 类中创建一个新的变量来代表你的游戏所面向的方向。因为我的游戏天然地面向右侧,由此我把面向右侧作为默认值:
|
||||
|
||||
```
|
||||
self.score = 0
|
||||
@ -196,8 +185,7 @@ firepower = pygame.sprite.Group()
|
||||
self.is_jumping = True
|
||||
```
|
||||
|
||||
当这个变量是 `True` 时,你的英雄精灵是面向右侧的。当玩家每次更改英雄的方向时,变量也必需重新设置,因此,在你的主循环中相关的 `keyup` 事件中这样做:
|
||||
|
||||
当这个变量是 `True` 时,你的英雄精灵是面向右侧的。当玩家每次更改英雄的方向时,变量也必须重新设置,因此,在你的主循环中相关的 `keyup` 事件中这样做:
|
||||
|
||||
```
|
||||
if event.type == pygame.KEYUP:
|
||||
@ -209,8 +197,7 @@ firepower = pygame.sprite.Group()
|
||||
player.facing_right = True # 添加这行
|
||||
```
|
||||
|
||||
最后,更改你的 `Throwable` 类的 `update` 函数,以检测英雄是否面向右侧,并恰当地添加或减去来自火球位置的像素:
|
||||
|
||||
最后,更改你的 `Throwable` 类的 `update` 函数,以检测英雄是否面向右侧,并恰当地添加或减去来自火球位置的像素:
|
||||
|
||||
```
|
||||
if self.rect.y < worldy:
|
||||
@ -225,13 +212,10 @@ firepower = pygame.sprite.Group()
|
||||
|
||||
![Python 平台类使用投掷能力][15]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][16])
|
||||
|
||||
作为一项额外的挑战,当彻底打败敌人时,尝试增加你玩家的得分。
|
||||
|
||||
### 完整的代码
|
||||
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
# 作者: Seth Kenlon
|
||||
@ -656,7 +640,7 @@ via: https://opensource.com/article/20/9/add-throwing-python-game
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -665,17 +649,17 @@ via: https://opensource.com/article/20/9/add-throwing-python-game
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/game_pawn_grid_linux.png?itok=4gERzRkg (Gaming on a grid with penguin pawns)
|
||||
[2]: https://www.python.org/
|
||||
[3]: https://www.pygame.org/news
|
||||
[4]: https://opensource.com/article/17/10/python-101
|
||||
[5]: https://opensource.com/article/17/12/game-framework-python
|
||||
[6]: https://opensource.com/article/17/12/game-python-add-a-player
|
||||
[7]: https://opensource.com/article/17/12/game-python-moving-player
|
||||
[8]: https://opensource.com/article/18/5/pygame-enemy
|
||||
[9]: https://opensource.com/article/18/7/put-platforms-python-game
|
||||
[10]: https://opensource.com/article/19/11/simulate-gravity-python
|
||||
[11]: https://opensource.com/article/19/12/jumping-python-platformer-game
|
||||
[12]: https://opensource.com/article/19/12/python-platformer-game-run
|
||||
[13]: https://opensource.com/article/19/12/loot-python-platformer-game
|
||||
[14]: https://opensource.com/article/20/1/add-scorekeeping-your-python-game
|
||||
[4]: https://linux.cn/article-9071-1.html
|
||||
[5]: https://linux.cn/article-10850-1.html
|
||||
[6]: https://linux.cn/article-10858-1.html
|
||||
[7]: https://linux.cn/article-10874-1.html
|
||||
[8]: https://linux.cn/article-10883-1.html
|
||||
[9]: https://linux.cn/article-10902-1.html
|
||||
[10]: https://linux.cn/article-11780-1.html
|
||||
[11]: https://linux.cn/article-11790-1.html
|
||||
[12]: https://linux.cn/article-11819-1.html
|
||||
[13]: https://linux.cn/article-11828-1.html
|
||||
[14]: https://linux.cn/article-11839-1.html
|
||||
[15]: https://opensource.com/sites/default/files/uploads/pygame-throw.jpg (Python platformer with throwing capability)
|
||||
[16]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[17]: http://www.gnu.org/licenses/\>
|
@ -1,514 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chenmu-kk)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Linux Desktop Setup · HookRace Blog)
|
||||
[#]: via: (https://hookrace.net/blog/linux-desktop-setup/)
|
||||
[#]: author: (Dennis Felsing http://felsin9.de/nnis/)
|
||||
|
||||
Linux Desktop Setup
|
||||
======
|
||||
|
||||
|
||||
My software setup has been surprisingly constant over the last decade, after a few years of experimentation since I initially switched to Linux in 2006. It might be interesting to look back in another 10 years and see what changed. A quick overview of what’s running as I’m writing this post:
|
||||
|
||||
[![htop overview][1]][2]
|
||||
|
||||
### Motivation
|
||||
|
||||
My software priorities are, in no specific order:
|
||||
|
||||
* Programs should run on my local system so that I’m in control of them, this excludes cloud solutions.
|
||||
* Programs should run in the terminal, so that they can be used consistently from anywhere, including weak computers or a phone.
|
||||
* Keyboard focused is nearly automatic by using terminal software. I prefer to use the mouse where it makes sense only, reaching for the mouse all the time during typing feels like a waste of time. Occasionally it took me an hour to notice that the mouse wasn’t even plugged in.
|
||||
* Ideally use fast and efficient software, I don’t like hearing the fan and feeling the room heat up. I can also keep running older hardware for much longer, my 10 year old Thinkpad x200s is still fine for all the software I use.
|
||||
* Be composable. I don’t want to do every step manually, instead automate more when it makes sense. This naturally favors the shell.
|
||||
|
||||
|
||||
|
||||
### Operating Systems
|
||||
|
||||
I had a hard start with Linux 12 years ago by removing Windows, armed with just the [Gentoo Linux][3] installation CD and a printed manual to get a functioning Linux system. It took me a few days of compiling and tinkering, but in the end I felt like I had learnt a lot.
|
||||
|
||||
I haven’t looked back to Windows since then, but I switched to [Arch Linux][4] on my laptop after having the fan fail from the constant compilation stress. Later I also switched all my other computers and private servers to Arch Linux. As a rolling release distribution you get package upgrades all the time, but the most important breakages are nicely reported in the [Arch Linux News][5].
|
||||
|
||||
One annoyance though is that Arch Linux removes the old kernel modules once you upgrade it. I usually notice that once I try plugging in a USB flash drive and the kernel fails to load the relevant module. Instead you’re supposed to reboot after each kernel upgrade. There are a few [hacks][6] around to get around the problem, but I haven’t been bothered enough to actually use them.
|
||||
|
||||
Similar problems happen with other programs, commonly Firefox, cron or Samba requiring a restart after an upgrade, but annoyingly not warning you that that’s the case. [SUSE][7], which I use at work, nicely warns about such cases.
|
||||
|
||||
For the [DDNet][8] production servers I prefer [Debian][9] over Arch Linux, so that I have a lower chance of breakage on each upgrade. For my firewall and router I used [OpenBSD][10] for its clean system, documentation and great [pf firewall][11], but right now I don’t have a need for a separate router anymore.
|
||||
|
||||
### Window Manager
|
||||
|
||||
Since I started out with Gentoo I quickly noticed the huge compile time of KDE, which made it a no-go for me. I looked around for more minimal solutions, and used [Openbox][12] and [Fluxbox][13] initially. At some point I jumped on the tiling window manager train in order to be more keyboard-focused and picked up [dwm][14] and [awesome][15] close to their initial releases.
|
||||
|
||||
In the end I settled on [xmonad][16] thanks to its flexibility, extendability and being written and configured in pure [Haskell][17], a great functional programming language. One example of this is that at home I run a single 40” 4K screen, but often split it up into four virtual screens, each displaying a workspace on which my windows are automatically arranged. Of course xmonad has a [module][18] for that.
|
||||
|
||||
[dzen][19] and [conky][20] function as a simple enough status bar for me. My entire conky config looks like this:
|
||||
|
||||
```
|
||||
out_to_console yes
|
||||
update_interval 1
|
||||
total_run_times 0
|
||||
|
||||
TEXT
|
||||
${downspeed eth0} ${upspeed eth0} | $cpu% ${loadavg 1} ${loadavg 2} ${loadavg 3} $mem/$memmax | ${time %F %T}
|
||||
```
|
||||
|
||||
And gets piped straight into dzen2 with `conky | dzen2 -fn '-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*' -bg '#000000' -fg '#ffffff' -p -e '' -x 1000 -w 920 -xs 1 -ta r`.
|
||||
|
||||
One important feature for me is to make the terminal emit a beep sound once a job is done. This is done simply by adding a `\a` character to the `PR_TITLEBAR` variable in zsh, which is shown whenever a job is done. Of course I disable the actual beep sound by blacklisting the `pcspkr` kernel module with `echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf`. Instead the sound gets turned into an urgency by urxvt’s `URxvt.urgentOnBell: true` setting. Then xmonad has an urgency hook to capture this and I can automatically focus the currently urgent window with a key combination. In dzen I get the urgent windowspaces displayed with a nice and bright `#ff0000`.
|
||||
|
||||
The final result in all its glory on my Laptop:
|
||||
|
||||
[![Laptop screenshot][21]][22]
|
||||
|
||||
I hear that [i3][23] has become quite popular in the last years, but it requires more manual window alignment instead of specifying automated methods to do it.
|
||||
|
||||
I realize that there are also terminal multiplexers like [tmux][24], but I still require a few graphical applications, so in the end I never used them productively.
|
||||
|
||||
### Terminal Persistency
|
||||
|
||||
In order to keep terminals alive I use [dtach][25], which is just the detach feature of screen. In order to make every terminal on my computer detachable I wrote a [small wrapper script][26]. This means that even if I had to restart my X server I could keep all my terminals running just fine, both local and remote.
|
||||
|
||||
### Shell & Programming
|
||||
|
||||
Instead of [bash][27] I use [zsh][28] as my shell for its huge number of features.
|
||||
|
||||
As a terminal emulator I found [urxvt][29] to be simple enough, support Unicode and 256 colors and has great performance. Another great feature is being able to run the urxvt client and daemon separately, so that even a large number of terminals barely takes up any memory (except for the scrollback buffer).
|
||||
|
||||
There is only one font that looks absolutely clean and perfect to me: [Terminus][30]. Since i’s a bitmap font everything is pixel perfect and renders extremely fast and at low CPU usage. In order to switch fonts on-demand in each terminal with `CTRL-WIN-[1-7]` my ~/.Xdefaults contains:
|
||||
|
||||
```
|
||||
URxvt.font: -xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*
|
||||
dzen2.font: -xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*
|
||||
|
||||
URxvt.keysym.C-M-1: command:\033]50;-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-2: command:\033]50;-xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-3: command:\033]50;-xos4-terminus-medium-r-normal-*-18-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-4: command:\033]50;-xos4-terminus-medium-r-normal-*-22-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-5: command:\033]50;-xos4-terminus-medium-r-normal-*-24-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-6: command:\033]50;-xos4-terminus-medium-r-normal-*-28-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-7: command:\033]50;-xos4-terminus-medium-r-normal-*-32-*-*-*-*-*-*-*\007
|
||||
|
||||
URxvt.keysym.C-M-n: command:\033]10;#ffffff\007\033]11;#000000\007\033]12;#ffffff\007\033]706;#00ffff\007\033]707;#ffff00\007
|
||||
URxvt.keysym.C-M-b: command:\033]10;#000000\007\033]11;#ffffff\007\033]12;#000000\007\033]706;#0000ff\007\033]707;#ff0000\007
|
||||
```
|
||||
|
||||
For programming and writing I use [Vim][31] with syntax highlighting and [ctags][32] for indexing, as well as a few terminal windows with grep, sed and the other usual suspects for search and manipulation. This is probably not at the same level of comfort as an IDE, but allows me more automation.
|
||||
|
||||
One problem with Vim is that you get so used to its key mappings that you’ll want to use them everywhere.
|
||||
|
||||
[Python][33] and [Nim][34] do well as scripting languages where the shell is not powerful enough.
|
||||
|
||||
### System Monitoring
|
||||
|
||||
[htop][35] (look at the background of that site, it’s a live view of the server that’s hosting it) works great for getting a quick overview of what the software is currently doing. [lm_sensors][36] allows monitoring the hardware temperatures, fans and voltages. [powertop][37] is a great little tool by Intel to find power savings. [ncdu][38] lets you analyze disk usage interactively.
|
||||
|
||||
[nmap][39], iptraf-ng, [tcpdump][40] and [Wireshark][41] are essential tools for analyzing network problems.
|
||||
|
||||
There are of course many more great tools.
|
||||
|
||||
### Mails & Synchronization
|
||||
|
||||
On my home server I have a [fetchmail][42] daemon running for each email acccount that I have. Fetchmail just retrieves the incoming emails and invokes [procmail][43]:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
for i in /home/deen/.fetchmail/*; do
|
||||
FETCHMAILHOME=$i /usr/bin/fetchmail -m 'procmail -d %T' -d 60
|
||||
done
|
||||
```
|
||||
|
||||
The configuration is as simple as it could be and waits for the server to inform us of fresh emails:
|
||||
|
||||
```
|
||||
poll imap.1und1.de protocol imap timeout 120 user "dennis@felsin9.de" password "XXX" folders INBOX keep ssl idle
|
||||
```
|
||||
|
||||
My `.procmailrc` config contains a few rules to backup all mails and sort them into the correct directories, for example based on the mailing list id or from field in the mail header:
|
||||
|
||||
```
|
||||
MAILDIR=/home/deen/shared/Maildir
|
||||
LOGFILE=$HOME/.procmaillog
|
||||
LOGABSTRACT=no
|
||||
VERBOSE=off
|
||||
FORMAIL=/usr/bin/formail
|
||||
NL="
|
||||
"
|
||||
|
||||
:0wc
|
||||
* ! ? test -d /media/mailarchive/`date +%Y`
|
||||
| mkdir -p /media/mailarchive/`date +%Y`
|
||||
|
||||
# Make backups of all mail received in format YYYY/YYYY-MM
|
||||
:0c
|
||||
/media/mailarchive/`date +%Y`/`date +%Y-%m`
|
||||
|
||||
:0
|
||||
* ^From: .*(.*@.*.kit.edu|.*@.*.uka.de|.*@.*.uni-karlsruhe.de)
|
||||
$MAILDIR/.uni/
|
||||
|
||||
:0
|
||||
* ^list-Id:.*lists.kit.edu
|
||||
$MAILDIR/.uni-ml/
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
To send emails I use [msmtp][44], which is also great to configure:
|
||||
|
||||
```
|
||||
account default
|
||||
host smtp.1und1.de
|
||||
tls on
|
||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
||||
auth on
|
||||
from dennis@felsin9.de
|
||||
user dennis@felsin9.de
|
||||
password XXX
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
But so far the emails are still on the server. My documents are all stored in a directory that I synchronize between all computers using [Unison][45]. Think of Unison as a bidirectional interactive [rsync][46]. My emails are part of this documents directory and thus they end up on my desktop computers.
|
||||
|
||||
This also means that while the emails reach my server immediately, I only fetch them on deman instead of getting instant notifications when an email comes in.
|
||||
|
||||
From there I read the mails with [mutt][47], using the sidebar plugin to display my mail directories. The `/etc/mailcap` file is essential to display non-plaintext mails containing HTML, Word or PDF:
|
||||
|
||||
```
|
||||
text/html;w3m -I %{charset} -T text/html; copiousoutput
|
||||
application/msword; antiword %s; copiousoutput
|
||||
application/pdf; pdftotext -layout /dev/stdin -; copiousoutput
|
||||
```
|
||||
|
||||
### News & Communication
|
||||
|
||||
[Newsboat][48] is a nice little RSS/Atom feed reader in the terminal. I have it running on the server in a `tach` session with about 150 feeds. Filtering feeds locally is also possible, for example:
|
||||
|
||||
```
|
||||
ignore-article "https://forum.ddnet.tw/feed.php" "title =~ \"Map Testing •\" or title =~ \"Old maps •\" or title =~ \"Map Bugs •\" or title =~ \"Archive •\" or title =~ \"Waiting for mapper •\" or title =~ \"Other mods •\" or title =~ \"Fixes •\""
|
||||
```
|
||||
|
||||
I use [Irssi][49] the same way for communication via IRC.
|
||||
|
||||
### Calendar
|
||||
|
||||
[remind][50] is a calendar that can be used from the command line. Setting new reminders is done by editing the `rem` files:
|
||||
|
||||
```
|
||||
# One time events
|
||||
REM 2019-01-20 +90 Flight to China %b
|
||||
|
||||
# Recurring Holidays
|
||||
REM 1 May +90 Holiday "Tag der Arbeit" %b
|
||||
REM [trigger(easterdate(year(today()))-2)] +90 Holiday "Karfreitag" %b
|
||||
|
||||
# Time Change
|
||||
REM Nov Sunday 1 --7 +90 Time Change (03:00 -> 02:00) %b
|
||||
REM Apr Sunday 1 --7 +90 Time Change (02:00 -> 03:00) %b
|
||||
|
||||
# Birthdays
|
||||
FSET birthday(x) "'s " + ord(year(trigdate())-x) + " birthday is %b"
|
||||
REM 16 Apr +90 MSG Andreas[birthday(1994)]
|
||||
|
||||
# Sun
|
||||
SET $LatDeg 49
|
||||
SET $LatMin 19
|
||||
SET $LatSec 49
|
||||
SET $LongDeg -8
|
||||
SET $LongMin -40
|
||||
SET $LongSec -24
|
||||
|
||||
MSG Sun from [sunrise(trigdate())] to [sunset(trigdate())]
|
||||
[...]
|
||||
```
|
||||
|
||||
Unfortunately there is no Chinese Lunar calendar function in remind yet, so Chinese holidays can’t be calculated easily.
|
||||
|
||||
I use two aliases for remind:
|
||||
|
||||
```
|
||||
rem -m -b1 -q -g
|
||||
```
|
||||
|
||||
to see a list of the next events in chronological order and
|
||||
|
||||
```
|
||||
rem -m -b1 -q -cuc12 -w$(($(tput cols)+1)) | sed -e "s/\f//g" | less
|
||||
```
|
||||
|
||||
to show a calendar fitting just the width of my terminal:
|
||||
|
||||
![remcal][51]
|
||||
|
||||
### Dictionary
|
||||
|
||||
[rdictcc][52] is a little known dictionary tool that uses the excellent dictionary files from [dict.cc][53] and turns them into a local database:
|
||||
|
||||
```
|
||||
$ rdictcc rasch
|
||||
====================[ A => B ]====================
|
||||
rasch:
|
||||
- apace
|
||||
- brisk [speedy]
|
||||
- cursory
|
||||
- in a timely manner
|
||||
- quick
|
||||
- quickly
|
||||
- rapid
|
||||
- rapidly
|
||||
- sharpish [Br.] [coll.]
|
||||
- speedily
|
||||
- speedy
|
||||
- swift
|
||||
- swiftly
|
||||
rasch [gehen]:
|
||||
- smartly [quickly]
|
||||
Rasch {n} [Zittergras-Segge]:
|
||||
- Alpine grass [Carex brizoides]
|
||||
- quaking grass sedge [Carex brizoides]
|
||||
Rasch {m} [regional] [Putzrasch]:
|
||||
- scouring pad
|
||||
====================[ B => A ]====================
|
||||
Rasch model:
|
||||
- Rasch-Modell {n}
|
||||
```
|
||||
|
||||
### Writing and Reading
|
||||
|
||||
I have a simple todo file containing my tasks, that is basically always sitting open in a Vim session. For work I also use the todo file as a “done” file so that I can later check what tasks I finished on each day.
|
||||
|
||||
For writing documents, letters and presentations I use [LaTeX][54] for its superior typesetting. A simple letter in German format can be set like this for example:
|
||||
|
||||
```
|
||||
\documentclass[paper = a4, fromalign = right]{scrlttr2}
|
||||
\usepackage{german}
|
||||
\usepackage{eurosym}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\setlength{\parskip}{6pt}
|
||||
\setlength{\parindent}{0pt}
|
||||
|
||||
\setkomavar{fromname}{Dennis Felsing}
|
||||
\setkomavar{fromaddress}{Meine Str. 1\\69181 Leimen}
|
||||
\setkomavar{subject}{Titel}
|
||||
|
||||
\setkomavar*{enclseparator}{Anlagen}
|
||||
|
||||
\makeatletter
|
||||
\@setplength{refvpos}{89mm}
|
||||
\makeatother
|
||||
|
||||
\begin{document}
|
||||
\begin{letter} {Herr Soundso\\Deine Str. 2\\69121 Heidelberg}
|
||||
\opening{Sehr geehrter Herr Soundso,}
|
||||
|
||||
Sie haben bei mir seit dem Bla Bla Bla.
|
||||
|
||||
Ich fordere Sie hiermit zu Bla Bla Bla auf.
|
||||
|
||||
\closing{Mit freundlichen Grüßen}
|
||||
|
||||
\end{letter}
|
||||
\end{document}
|
||||
```
|
||||
|
||||
Further example documents and presentations can be found over at [my private site][55].
|
||||
|
||||
To read PDFs [Zathura][56] is fast, has Vim-like controls and even supports two different PDF backends: Poppler and MuPDF. [Evince][57] on the other hand is more full-featured for the cases where I encounter documents that Zathura doesn’t like.
|
||||
|
||||
### Graphical Editing
|
||||
|
||||
[GIMP][58] and [Inkscape][59] are easy choices for photo editing and interactive vector graphics respectively.
|
||||
|
||||
In some cases [Imagemagick][60] is good enough though and can be used straight from the command line and thus automated to edit images. Similarly [Graphviz][61] and [TikZ][62] can be used to draw graphs and other diagrams.
|
||||
|
||||
### Web Browsing
|
||||
|
||||
As a web browser I’ve always used [Firefox][63] for its extensibility and low resource usage compared to Chrome.
|
||||
|
||||
Unfortunately the [Pentadactyl][64] extension development stopped after Firefox switched to Chrome-style extensions entirely, so I don’t have satisfying Vim-like controls in my browser anymore.
|
||||
|
||||
### Media Players
|
||||
|
||||
[mpv][65] with hardware decoding allows watching videos at 5% CPU load using the `vo=gpu` and `hwdec=vaapi` config settings. `audio-channels=2` in mpv seems to give me clearer downmixing to my stereo speakers / headphones than what PulseAudio does by default. A great little feature is exiting with `Shift-Q` instead of just `Q` to save the playback location. When watching with someone with another native tongue you can use `--secondary-sid=` to show two subtitles at once, the primary at the bottom, the secondary at the top of the screen
|
||||
|
||||
My wirelss mouse can easily be made into a remote control with mpv with a small `~/.config/mpv/input.conf`:
|
||||
|
||||
```
|
||||
MOUSE_BTN5 run "mixer" "pcm" "-2"
|
||||
MOUSE_BTN6 run "mixer" "pcm" "+2"
|
||||
MOUSE_BTN1 cycle sub-visibility
|
||||
MOUSE_BTN7 add chapter -1
|
||||
MOUSE_BTN8 add chapter 1
|
||||
```
|
||||
|
||||
[youtube-dl][66] works great for watching videos hosted online, best quality can be achieved with `-f bestvideo+bestaudio/best --all-subs --embed-subs`.
|
||||
|
||||
As a music player [MOC][67] hasn’t been actively developed for a while, but it’s still a simple player that plays every format conceivable, including the strangest Chiptune formats. In the AUR there is a [patch][68] adding PulseAudio support as well. Even with the CPU clocked down to 800 MHz MOC barely uses 1-2% of a single CPU core.
|
||||
|
||||
![moc][69]
|
||||
|
||||
My music collection sits on my home server so that I can access it from anywhere. It is mounted using [SSHFS][70] and automount in the `/etc/fstab/`:
|
||||
|
||||
```
|
||||
root@server:/media/media /mnt/media fuse.sshfs noauto,x-systemd.automount,idmap=user,IdentityFile=/root/.ssh/id_rsa,allow_other,reconnect 0 0
|
||||
```
|
||||
|
||||
### Cross-Platform Building
|
||||
|
||||
Linux is great to build packages for any major operating system except Linux itself! In the beginning I used [QEMU][71] to with an old Debian, Windows and Mac OS X VM to build for these platforms.
|
||||
|
||||
Nowadays I switched to using chroot for the old Debian distribution (for maximum Linux compatibility), [MinGW][72] to cross-compile for Windows and [OSXCross][73] to cross-compile for Mac OS X.
|
||||
|
||||
The script used to [build DDNet][74] as well as the [instructions for updating library builds][75] are based on this.
|
||||
|
||||
### Backups
|
||||
|
||||
As usual, we nearly forgot about backups. Even if this is the last chapter, it should not be an afterthought.
|
||||
|
||||
I wrote [rrb][76] (reverse rsync backup) 10 years ago to wrap rsync so that I only need to give the backup server root SSH rights to the computers that it is backing up. Surprisingly rrb needed 0 changes in the last 10 years, even though I kept using it the entire time.
|
||||
|
||||
The backups are stored straight on the filesystem. Incremental backups are implemented using hard links (`--link-dest`). A simple [config][77] defines how long backups are kept, which defaults to:
|
||||
|
||||
```
|
||||
KEEP_RULES=( \
|
||||
7 7 \ # One backup a day for the last 7 days
|
||||
31 8 \ # 8 more backups for the last month
|
||||
365 11 \ # 11 more backups for the last year
|
||||
1825 4 \ # 4 more backups for the last 5 years
|
||||
)
|
||||
```
|
||||
|
||||
Since some of my computers don’t have a static IP / DNS entry and I still want to back them up using rrb I use a reverse SSH tunnel (as a systemd service) for them:
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Reverse SSH Tunnel
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/ssh -N -R 27276:localhost:22 -o "ExitOnForwardFailure yes" server
|
||||
KillMode=process
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Now the server can reach the client through `ssh -p 27276 localhost` while the tunnel is running to perform the backup, or in `.ssh/config` format:
|
||||
|
||||
```
|
||||
Host cr-remote
|
||||
HostName localhost
|
||||
Port 27276
|
||||
```
|
||||
|
||||
While talking about SSH hacks, sometimes a server is not easily reachable thanks to some bad routing. In that case you can route the SSH connection through another server to get better routing, in this case going through the USA to reach my Chinese server which had not been reliably reachable from Germany for a few weeks:
|
||||
|
||||
```
|
||||
Host chn.ddnet.tw
|
||||
ProxyCommand ssh -q usa.ddnet.tw nc -q0 chn.ddnet.tw 22
|
||||
Port 22
|
||||
```
|
||||
|
||||
### Final Remarks
|
||||
|
||||
Thanks for reading my random collection of tools. I probably forgot many programs that I use so naturally every day that I don’t even think about them anymore. Let’s see how stable my software setup stays in the next years. If you have any questions, feel free to get in touch with me at [dennis@felsin9.de][78].
|
||||
|
||||
Comments on [Hacker News][79].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://hookrace.net/blog/linux-desktop-setup/
|
||||
|
||||
作者:[Dennis Felsing][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://felsin9.de/nnis/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://hookrace.net/public/linux-desktop/htop_small.png
|
||||
[2]: https://hookrace.net/public/linux-desktop/htop.png
|
||||
[3]: https://gentoo.org/
|
||||
[4]: https://www.archlinux.org/
|
||||
[5]: https://www.archlinux.org/news/
|
||||
[6]: https://www.reddit.com/r/archlinux/comments/4zrsc3/keep_your_system_fully_functional_after_a_kernel/
|
||||
[7]: https://www.suse.com/
|
||||
[8]: https://ddnet.tw/
|
||||
[9]: https://www.debian.org/
|
||||
[10]: https://www.openbsd.org/
|
||||
[11]: https://www.openbsd.org/faq/pf/
|
||||
[12]: http://openbox.org/wiki/Main_Page
|
||||
[13]: http://fluxbox.org/
|
||||
[14]: https://dwm.suckless.org/
|
||||
[15]: https://awesomewm.org/
|
||||
[16]: https://xmonad.org/
|
||||
[17]: https://www.haskell.org/
|
||||
[18]: http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Layout-LayoutScreens.html
|
||||
[19]: http://robm.github.io/dzen/
|
||||
[20]: https://github.com/brndnmtthws/conky
|
||||
[21]: https://hookrace.net/public/linux-desktop/laptop_small.png
|
||||
[22]: https://hookrace.net/public/linux-desktop/laptop.png
|
||||
[23]: https://i3wm.org/
|
||||
[24]: https://github.com/tmux/tmux/wiki
|
||||
[25]: http://dtach.sourceforge.net/
|
||||
[26]: https://github.com/def-/tach/blob/master/tach
|
||||
[27]: https://www.gnu.org/software/bash/
|
||||
[28]: http://www.zsh.org/
|
||||
[29]: http://software.schmorp.de/pkg/rxvt-unicode.html
|
||||
[30]: http://terminus-font.sourceforge.net/
|
||||
[31]: https://www.vim.org/
|
||||
[32]: http://ctags.sourceforge.net/
|
||||
[33]: https://www.python.org/
|
||||
[34]: https://nim-lang.org/
|
||||
[35]: https://hisham.hm/htop/
|
||||
[36]: http://lm-sensors.org/
|
||||
[37]: https://01.org/powertop/
|
||||
[38]: https://dev.yorhel.nl/ncdu
|
||||
[39]: https://nmap.org/
|
||||
[40]: https://www.tcpdump.org/
|
||||
[41]: https://www.wireshark.org/
|
||||
[42]: http://www.fetchmail.info/
|
||||
[43]: http://www.procmail.org/
|
||||
[44]: https://marlam.de/msmtp/
|
||||
[45]: https://www.cis.upenn.edu/~bcpierce/unison/
|
||||
[46]: https://rsync.samba.org/
|
||||
[47]: http://www.mutt.org/
|
||||
[48]: https://newsboat.org/
|
||||
[49]: https://irssi.org/
|
||||
[50]: https://www.roaringpenguin.com/products/remind
|
||||
[51]: https://hookrace.net/public/linux-desktop/remcal.png
|
||||
[52]: https://github.com/tsdh/rdictcc
|
||||
[53]: https://www.dict.cc/
|
||||
[54]: https://www.latex-project.org/
|
||||
[55]: http://felsin9.de/nnis/research/
|
||||
[56]: https://pwmt.org/projects/zathura/
|
||||
[57]: https://wiki.gnome.org/Apps/Evince
|
||||
[58]: https://www.gimp.org/
|
||||
[59]: https://inkscape.org/
|
||||
[60]: https://imagemagick.org/Usage/
|
||||
[61]: https://www.graphviz.org/
|
||||
[62]: https://sourceforge.net/projects/pgf/
|
||||
[63]: https://www.mozilla.org/en-US/firefox/new/
|
||||
[64]: https://github.com/5digits/dactyl
|
||||
[65]: https://mpv.io/
|
||||
[66]: https://rg3.github.io/youtube-dl/
|
||||
[67]: http://moc.daper.net/
|
||||
[68]: https://aur.archlinux.org/packages/moc-pulse/
|
||||
[69]: https://hookrace.net/public/linux-desktop/moc.png
|
||||
[70]: https://github.com/libfuse/sshfs
|
||||
[71]: https://www.qemu.org/
|
||||
[72]: http://www.mingw.org/
|
||||
[73]: https://github.com/tpoechtrager/osxcross
|
||||
[74]: https://github.com/ddnet/ddnet-scripts/blob/master/ddnet-release.sh
|
||||
[75]: https://github.com/ddnet/ddnet-scripts/blob/master/ddnet-lib-update.sh
|
||||
[76]: https://github.com/def-/rrb/blob/master/rrb
|
||||
[77]: https://github.com/def-/rrb/blob/master/config.example
|
||||
[78]: mailto:dennis@felsin9.de
|
||||
[79]: https://news.ycombinator.com/item?id=18979731
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (alim0x)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
513
translated/tech/20190115 Linux Desktop Setup - HookRace Blog.md
Normal file
513
translated/tech/20190115 Linux Desktop Setup - HookRace Blog.md
Normal file
@ -0,0 +1,513 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chenmu-kk)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Linux Desktop Setup · HookRace Blog)
|
||||
[#]: via: (https://hookrace.net/blog/linux-desktop-setup/)
|
||||
[#]: author: (Dennis Felsing http://felsin9.de/nnis/)
|
||||
|
||||
Linux桌面设置
|
||||
======
|
||||
|
||||
|
||||
从 2006 年开始转战 Linux 系统后,经过几年的实践,我的软件设置在过去十年内出人意料的固定。再过十年回顾一下,看看发生了什么,也许会非常有趣。在写这篇推文时,我迅速回顾了正在运行的内容:
|
||||
|
||||
[![htop overview][1]][2]
|
||||
|
||||
### 契机
|
||||
|
||||
我的软件介绍排序不分先后:
|
||||
|
||||
* 程序应该运行在本地系统中以便我可以控制它,这其中并不包括云解决方案。
|
||||
* 程序应在终端中运行,以便于在任何地方连贯地使用它们,包括性能稍差的电脑或手机。
|
||||
* 通过使用终端软件,可以实现自动聚焦键盘。只有在一些有意义的地方,我会更喜欢使用鼠标,因为在打字期间一直伸手去拿鼠标感觉像在浪费时间。有时候过了一个小时我才注意到甚至还没有插鼠标。
|
||||
* 最好使用快速高效的软件,我不喜欢听到风扇的声音和感到房间在变热。我还可以继续长久地运行旧硬件,已经使用了 10 年的 Thinkpad x200s 还能很好地支持我所使用的软件。
|
||||
* 组合。我不想手动执行每个步骤,而是在需要时自动执行更多操作,这时自然是支持 shell。
|
||||
|
||||
|
||||
|
||||
### 操作系统
|
||||
|
||||
十二年前移除 Windows 系统后,我在 Linux 系统上经历了一个艰难的开始,当时我手上只有 [Gentoo Linux][3] 系统的安装光盘和一本打印的说明书,要用它们来实现一个可运行的 Linux 系统。虽然花费了几天的时间去编辑和修整,但最终还是觉得自己受益颇多。
|
||||
|
||||
自此我再也没有转回 Windows 系统,但在持续的编译压力导致风扇失灵后,我将我的电脑系统切换到 [Arch Linux][4]。之后我将其他的电脑和私人服务器也切换到了 Arch Linux。作为一个滚动发布发行版,你可以随时升级软件包,但 [Arch Linux News][5] 已经详细报道了其中最主要的漏洞。
|
||||
|
||||
不过,令人烦恼的事一旦你更新了旧的内核模组, Arch Linux 就会移除旧版的相关信息。我经常注意到一旦我试着插入一个 USB 闪存驱动,内核就无法加载相关组件。相反,每次内核升级后都应该进行重启。有一些 [方法][6] 可以解决这个问题,但我还没有实际地使用它们。
|
||||
|
||||
其他程序也会出现类似的情况,通常 Firefox 、 cron 或者 Samba 在升级后都需要重启,但恼人的是,它们没有警告你存在这种情况不是提醒你这件事本身。我在工作中使用的 [SUSE][7] 很好地提醒了这种情况。
|
||||
|
||||
对于 [DDNet][8] ,我更喜欢使用 Arch Linux 的 [Debian][9] 系统,这样在每次升级时出现故障的几率更低。我的防火墙和路由器使用了拥有干净系统、文件和强大的 [OpenBSD][10] 的 [pf firewall][11]。
|
||||
|
||||
### 视窗管理
|
||||
|
||||
从我开始使用 Gentoo 后,我很快注意到 KDE 的编译时间非常长,这让我没办法继续使用它。我四处寻找更简单的解决方案,最初使用了 [Openbox][12] 和 [Fluxbox][13]。某次,为了能更多进行纯键盘操作,我开始转入平铺窗口管理器训练,并在研究其初始版本的时候学习了 [dwm][14] 和 [awesome][15]。
|
||||
|
||||
最终,由于 [xmonad][16]的灵活性,可扩展性以及使用纯 [Haskell][17] 一种出色的功能编程语言)编写和配置,最终选择了它。一个例子是,我在家中运行一个 40" 4K 的屏幕,但经常会将它分为四个虚拟屏幕,每个虚拟屏幕显示一个工作区,每个工作区自动排列在我的窗口上。 当然, xmonad 有一个对应的 [模块][18]。
|
||||
|
||||
[dzen][19] 和 [conky][20] 对我来说是一个非常简单的状态栏。我的整体conky配置看起来是这样的:
|
||||
|
||||
```
|
||||
out_to_console yes
|
||||
update_interval 1
|
||||
total_run_times 0
|
||||
|
||||
TEXT
|
||||
${downspeed eth0} ${upspeed eth0} | $cpu% ${loadavg 1} ${loadavg 2} ${loadavg 3} $mem/$memmax | ${time %F %T}
|
||||
```
|
||||
|
||||
输入命令直接通过管道输入dzen2 `conky | dzen2 -fn '-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*' -bg '#000000' -fg '#ffffff' -p -e '' -x 1000 -w 920 -xs 1 -ta r`.
|
||||
|
||||
对我而言,一项重要功能是在完成工作后使终端发出蜂鸣声。只需要简单地在 zsh 中的 `PR_TITLEBAR` 变量中添加一个 `\a` 字符就可以做到,只要工作完成就可以发出蜂鸣声。当然,我使用了 `echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf` 命令,将 `pcspkr` 内核模块列入黑名单来禁用实际的蜂鸣声。相反 urxvt 的`URxvt.urgentOnBell: true` 设置会将声音变为尖锐。之后 xmonad 有一个 urgency hook 来捕捉这类信号,并且我可以使用组合键自动聚焦到当前紧急窗口。在 dzen 中我可以看到一个漂亮且明亮的 `#ff0000`紧急窗口。
|
||||
|
||||
在我笔记本上所得到的最终成品是:
|
||||
|
||||
[![Laptop screenshot][21]][22]
|
||||
|
||||
我听说前几年 [i3][23] 变得非常流行,但它要求更多的手动窗口对齐而不是自动对齐。
|
||||
|
||||
我意识到也有像 [tmux][24] 那样的终端多路复用器,但我仍想要一些图形化应用程序,因此最终我没有有效地使用它们。
|
||||
|
||||
### 终端连续性
|
||||
|
||||
为了使终端保持活跃状态,我使用了 [dtach][25] ,它只是模拟屏幕分离功能。 为了使计算机上的每个终端都可连接和断开,我编写了一个小的封装脚本。 这意味着,即使必须重新启动 X 服务器,我也可以使所有终端都运行良好,包括本地和远程终端。
|
||||
|
||||
### Shell & 编程
|
||||
|
||||
对于 shell,我使用 [zsh][28] 而不是 [bash][27],因为它有众多的功能。
|
||||
|
||||
作为终端模拟,我发现 [urxvt][29] 足够轻巧,支持 Unicode 编码和 256 色,具有出色的性能。另一个重要的功能是可以分别运行 urxvt client 客户端和守护进程。因此,即使大量终端也几乎不占用任何内存( scrollback 除外)。
|
||||
|
||||
对我而言,只有一种字体看起来绝对干净和完美: [Terminus][30]。 由于我是位图字体,因此所有内容都是完美像素,渲染速度极快且 CPU 使用率低。为了能使用 `CTRL-WIN-[1-7]` 在每个终端按需切换字体,我的 ~/.Xdefaults 包含:
|
||||
|
||||
```
|
||||
URxvt.font: -xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*
|
||||
dzen2.font: -xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*
|
||||
|
||||
URxvt.keysym.C-M-1: command:\033]50;-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-2: command:\033]50;-xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-3: command:\033]50;-xos4-terminus-medium-r-normal-*-18-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-4: command:\033]50;-xos4-terminus-medium-r-normal-*-22-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-5: command:\033]50;-xos4-terminus-medium-r-normal-*-24-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-6: command:\033]50;-xos4-terminus-medium-r-normal-*-28-*-*-*-*-*-*-*\007
|
||||
URxvt.keysym.C-M-7: command:\033]50;-xos4-terminus-medium-r-normal-*-32-*-*-*-*-*-*-*\007
|
||||
|
||||
URxvt.keysym.C-M-n: command:\033]10;#ffffff\007\033]11;#000000\007\033]12;#ffffff\007\033]706;#00ffff\007\033]707;#ffff00\007
|
||||
URxvt.keysym.C-M-b: command:\033]10;#000000\007\033]11;#ffffff\007\033]12;#000000\007\033]706;#0000ff\007\033]707;#ff0000\007
|
||||
```
|
||||
|
||||
对于编程和书写,我使用 [Vim][31] 语法高亮显示和 [ctags][32] 进行索引,以及一些带有 grep 、sed 和其他用于搜索和操作的常用终端窗口。这可能不像 IDE 那样舒适,可以实现更多的自动化。
|
||||
|
||||
Vim 的一个问题是你已经习惯了它的键映射,因此希望在任何地方都使用它们。
|
||||
|
||||
在 shell 功能不够强大时,[Python][33] 和 [Nim][34] 作为脚本语言也不错。
|
||||
|
||||
### 系统监控
|
||||
|
||||
[htop][35] (查看当前站点的后台运行,是托管服务器的实时视图)非常适合快速了解软件的当前运行状态。 [lm_sensors][36] 可以监控硬件温度、风扇和电压。 [powertop][37] 是一款由 Intel 发布的优秀省电小工具。 [ncdu][38] 可以交互式分析磁盘使用情况。
|
||||
|
||||
[nmap][39]、 iptraf-ng、 [tcpdump][40] 和 [Wireshark][41] 都是分析网络问题的基本工具。
|
||||
|
||||
当然还有很多更优秀的工具。
|
||||
|
||||
### 邮件 & 同步
|
||||
|
||||
在我的 home server 服务器上,我为自己所有的邮箱账号运行了 [fetchmail][42] 守护进程。Fetchmail 只检索收到的邮件并调用 [procmail][43]:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
for i in /home/deen/.fetchmail/*; do
|
||||
FETCHMAILHOME=$i /usr/bin/fetchmail -m 'procmail -d %T' -d 60
|
||||
done
|
||||
```
|
||||
|
||||
配置非常简单,然后等待服务器通知我们有新的邮件:
|
||||
|
||||
```
|
||||
poll imap.1und1.de protocol imap timeout 120 user "dennis@felsin9.de" password "XXX" folders INBOX keep ssl idle
|
||||
```
|
||||
|
||||
我的 `.procmailrc` 配置包含一些备份全部邮件的规则,并将邮件整理在对应的目录下面。例如,基于邮件列表名或者邮件标题:
|
||||
|
||||
```
|
||||
MAILDIR=/home/deen/shared/Maildir
|
||||
LOGFILE=$HOME/.procmaillog
|
||||
LOGABSTRACT=no
|
||||
VERBOSE=off
|
||||
FORMAIL=/usr/bin/formail
|
||||
NL="
|
||||
"
|
||||
|
||||
:0wc
|
||||
* ! ? test -d /media/mailarchive/`date +%Y`
|
||||
| mkdir -p /media/mailarchive/`date +%Y`
|
||||
|
||||
# Make backups of all mail received in format YYYY/YYYY-MM
|
||||
:0c
|
||||
/media/mailarchive/`date +%Y`/`date +%Y-%m`
|
||||
|
||||
:0
|
||||
* ^From: .*(.*@.*.kit.edu|.*@.*.uka.de|.*@.*.uni-karlsruhe.de)
|
||||
$MAILDIR/.uni/
|
||||
|
||||
:0
|
||||
* ^list-Id:.*lists.kit.edu
|
||||
$MAILDIR/.uni-ml/
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
我使用 [msmtp][44] 来发送邮件,它也很好配置:
|
||||
|
||||
```
|
||||
account default
|
||||
host smtp.1und1.de
|
||||
tls on
|
||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
||||
auth on
|
||||
from dennis@felsin9.de
|
||||
user dennis@felsin9.de
|
||||
password XXX
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
但是到目前为止,邮件还在服务器上。 我的文档全部存储在一个目录中,我使用 [Unison][45] 在所有计算机之间进行同步。将 Unison 视为双向交互 [rsync][46],我的邮件是这个文件目录下的一部分因此它们最终存储在我的电脑上。
|
||||
|
||||
这也意味着,尽管邮件会立即到达我的邮箱,但我只是按需拿取,而不是邮件一到达时就立即收到通知。
|
||||
|
||||
从此我使用 [mutt][47] 阅读邮件,使用侧边栏显示我的邮件目录。 `/etc/mailcap` 文件对于显示非纯文本邮件( HTML, Word 或者 PDF)不可或缺:
|
||||
|
||||
```
|
||||
text/html;w3m -I %{charset} -T text/html; copiousoutput
|
||||
application/msword; antiword %s; copiousoutput
|
||||
application/pdf; pdftotext -layout /dev/stdin -; copiousoutput
|
||||
```
|
||||
|
||||
### 新闻 & 通讯
|
||||
|
||||
[Newsboat][48] 是一个非常棒的终端 RSS/Atom 阅读器。我在一个有约 150 个提要的 `tach` 会话服务器上运行它。也可以在本地选择提要,例如:
|
||||
|
||||
```
|
||||
ignore-article "https://forum.ddnet.tw/feed.php" "title =~ \"Map Testing •\" or title =~ \"Old maps •\" or title =~ \"Map Bugs •\" or title =~ \"Archive •\" or title =~ \"Waiting for mapper •\" or title =~ \"Other mods •\" or title =~ \"Fixes •\""
|
||||
```
|
||||
|
||||
我以同样的方式使用 [Irssi][49] 进行 IRC 通讯。
|
||||
|
||||
### 日历
|
||||
|
||||
[remind][50] 是一个可以从命令行获取的日历。通过编辑 `rem` 文件可以设置新的提醒:
|
||||
|
||||
```
|
||||
# One time events
|
||||
REM 2019-01-20 +90 Flight to China %b
|
||||
|
||||
# Recurring Holidays
|
||||
REM 1 May +90 Holiday "Tag der Arbeit" %b
|
||||
REM [trigger(easterdate(year(today()))-2)] +90 Holiday "Karfreitag" %b
|
||||
|
||||
# Time Change
|
||||
REM Nov Sunday 1 --7 +90 Time Change (03:00 -> 02:00) %b
|
||||
REM Apr Sunday 1 --7 +90 Time Change (02:00 -> 03:00) %b
|
||||
|
||||
# Birthdays
|
||||
FSET birthday(x) "'s " + ord(year(trigdate())-x) + " birthday is %b"
|
||||
REM 16 Apr +90 MSG Andreas[birthday(1994)]
|
||||
|
||||
# Sun
|
||||
SET $LatDeg 49
|
||||
SET $LatMin 19
|
||||
SET $LatSec 49
|
||||
SET $LongDeg -8
|
||||
SET $LongMin -40
|
||||
SET $LongSec -24
|
||||
|
||||
MSG Sun from [sunrise(trigdate())] to [sunset(trigdate())]
|
||||
[...]
|
||||
```
|
||||
|
||||
遗憾的是,目前 remind 中还没有中国农历的提醒功能,因此中国的节日不易计算。
|
||||
我给提醒设置了两个名字:
|
||||
|
||||
```
|
||||
rem -m -b1 -q -g
|
||||
```
|
||||
|
||||
按时间顺序查看待办事项清单
|
||||
|
||||
```
|
||||
rem -m -b1 -q -cuc12 -w$(($(tput cols)+1)) | sed -e "s/\f//g" | less
|
||||
```
|
||||
|
||||
显示适应终端宽度的日历:
|
||||
|
||||
![remcal][51]
|
||||
|
||||
### 字典
|
||||
|
||||
[rdictcc][52] 是鲜为人知的字典工具,它可以从 [dict.cc][53] 使用高级词典并将他们转存在本地数据库中:
|
||||
|
||||
```
|
||||
$ rdictcc rasch
|
||||
====================[ A => B ]====================
|
||||
rasch:
|
||||
- apace
|
||||
- brisk [speedy]
|
||||
- cursory
|
||||
- in a timely manner
|
||||
- quick
|
||||
- quickly
|
||||
- rapid
|
||||
- rapidly
|
||||
- sharpish [Br.] [coll.]
|
||||
- speedily
|
||||
- speedy
|
||||
- swift
|
||||
- swiftly
|
||||
rasch [gehen]:
|
||||
- smartly [quickly]
|
||||
Rasch {n} [Zittergras-Segge]:
|
||||
- Alpine grass [Carex brizoides]
|
||||
- quaking grass sedge [Carex brizoides]
|
||||
Rasch {m} [regional] [Putzrasch]:
|
||||
- scouring pad
|
||||
====================[ B => A ]====================
|
||||
Rasch model:
|
||||
- Rasch-Modell {n}
|
||||
```
|
||||
|
||||
### 记录和阅读
|
||||
|
||||
我有一个简单记录任务的备忘录,在 Vim 会话中基本上一直处于打开状态。我也使用备忘录作为工作中已做工作的记录,这样就可以检查自己每天完成了哪些任务。
|
||||
|
||||
对于写文件,信件和演示文稿,我会使用 [LaTeX][54] 进行高级排版。德式的简单信件可以这样设置,例如:
|
||||
|
||||
```
|
||||
\documentclass[paper = a4, fromalign = right]{scrlttr2}
|
||||
\usepackage{german}
|
||||
\usepackage{eurosym}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\setlength{\parskip}{6pt}
|
||||
\setlength{\parindent}{0pt}
|
||||
|
||||
\setkomavar{fromname}{Dennis Felsing}
|
||||
\setkomavar{fromaddress}{Meine Str. 1\\69181 Leimen}
|
||||
\setkomavar{subject}{Titel}
|
||||
|
||||
\setkomavar*{enclseparator}{Anlagen}
|
||||
|
||||
\makeatletter
|
||||
\@setplength{refvpos}{89mm}
|
||||
\makeatother
|
||||
|
||||
\begin{document}
|
||||
\begin{letter} {Herr Soundso\\Deine Str. 2\\69121 Heidelberg}
|
||||
\opening{Sehr geehrter Herr Soundso,}
|
||||
|
||||
Sie haben bei mir seit dem Bla Bla Bla.
|
||||
|
||||
Ich fordere Sie hiermit zu Bla Bla Bla auf.
|
||||
|
||||
\closing{Mit freundlichen Grüßen}
|
||||
|
||||
\end{letter}
|
||||
\end{document}
|
||||
```
|
||||
|
||||
在 [我的私人网站][55] 上可以找到更多的示例文档和演示文稿。
|
||||
|
||||
[Zathura][56] 读取 PDF 文件速度很快,支持 Vim 类控件,还支持两种不同的 PDF 后端: Poppler 和 MuPDF。另一方面,在偶尔遇到 Zathura 无法打开的文件时,[Evince][57] 则显得更全能一些。
|
||||
|
||||
### 图片编辑
|
||||
|
||||
[GIMP][58] 和 [Inkscape][59] 分别是照片编辑和交互式向量图形是一个简便的选择。
|
||||
|
||||
有时 [Imagemagick][60] 已经足够好了,它可以从命令行直接使用,从而自动编辑图片。同样 [Graphviz][61] 和 [TikZ][62] 可以用来绘制曲线图和其他图表。
|
||||
|
||||
### 网络浏览器
|
||||
|
||||
对于网络浏览器,我一直在使用 [Firefox][63]。相较于 Chrome,它的可扩展性更好,资源使用率更低。
|
||||
|
||||
不幸的是,在 Firefox 完全改用 Chrome 风格的扩展之后, [Pentadactyl][64] l扩展的开发就停止了,所以我的浏览器中再也没有令人满意的 Vim 类控件了。
|
||||
|
||||
### 媒体播放器
|
||||
|
||||
通过设置 `vo=gpu` 以及 `hwdec=vaapi`,具有硬件解码功能的 [mpv][65] 在播放期间 CPU 的占用率保持在 5%。相较于默认的t PulseAudio,mpv 中的 `audio-channels=2` 似乎可以使我的立体扬声器/耳机获得更清晰的降级混频。一个很棒的小功能是用 `Shift-Q` 退出,而不是只用 `Q` 来保存回放位置。当你与母语是其他语言的人一起看视频时,你可以使用 `--secondary-sid=` 同时显示两种字幕,主字幕位于底部,次字幕位于屏幕顶部。
|
||||
|
||||
我的无线鼠标可以简单地通过一个小的配置文件( `~/.config/mpv/input.conf` )实现远程控制 mpv :
|
||||
|
||||
```
|
||||
MOUSE_BTN5 run "mixer" "pcm" "-2"
|
||||
MOUSE_BTN6 run "mixer" "pcm" "+2"
|
||||
MOUSE_BTN1 cycle sub-visibility
|
||||
MOUSE_BTN7 add chapter -1
|
||||
MOUSE_BTN8 add chapter 1
|
||||
```
|
||||
|
||||
[youtube-dl][66] 非常适合观看在线托管的视频,使用 `-f bestvideo+bestaudio/best --all-subs --embed-subs` 命令可获得最高质量的视频。
|
||||
|
||||
作为音乐播放器, [MOC][67] 还未得到积极发展,但它仍是一个简易的播放器,可以播放各种可能的格式,包括最不常用的 Chiptune 格式。在 AUR 中有一个 [补丁][68] 增加了 PulseAudio 支持。即使在 CPU 时钟频率降到 800 MHz, MOC 也只使用了单核 CPU 的 1-2% 。
|
||||
|
||||
![moc][69]
|
||||
|
||||
我的音乐收藏夹保存在我的 home server 上,因此我可以从任何地方访问它。它使用 [SSHFS][70] 挂载并自动安装在 `/etc/fstab/` 目录下:
|
||||
|
||||
```
|
||||
root@server:/media/media /mnt/media fuse.sshfs noauto,x-systemd.automount,idmap=user,IdentityFile=/root/.ssh/id_rsa,allow_other,reconnect 0 0
|
||||
```
|
||||
|
||||
### 跨平台构建
|
||||
|
||||
除了系统本身,对于任何主流操作系统 Linux 在构建软件包方面都很优秀! 一开始,我使用 [QEMU][71] 与旧版 Debian、 Windows 以及 Mac OS X VM 一起构建这些平台。
|
||||
|
||||
现在我在旧版 Debian distribution 上转而使用 chroot (以获得最大的 Linux 兼容性),在 Windows 上使用 [MinGW][72] 进行交叉编译,在 Mac OS X 上则使用 [OSXCross][73]。
|
||||
|
||||
用于 [build DDNet][74] 以及 [instructions for updating library builds][75] 的脚本都基于此。
|
||||
|
||||
### 备份
|
||||
|
||||
通常,我们都会忘记备份。即使这是终章,它也不应该成为事后诸葛。
|
||||
|
||||
十年前我写了 [rrb][76] (反向rsync备份)重新包装了 rsync ,因此我只需要授予正在备份的计算机,备份服务器的 root SSH 权限。令人惊讶地是,尽管我一直在使用 rrb ,但它在过去十年里没有任何改变。
|
||||
|
||||
备份文件直接存储在文件系统中。使用硬链接实现增量备份 (`--link-dest`) 。一个简单的 [配置][77] 定义了备份保存时间,默认为:
|
||||
|
||||
```
|
||||
KEEP_RULES=( \
|
||||
7 7 \ # One backup a day for the last 7 days
|
||||
31 8 \ # 8 more backups for the last month
|
||||
365 11 \ # 11 more backups for the last year
|
||||
1825 4 \ # 4 more backups for the last 5 years
|
||||
)
|
||||
```
|
||||
|
||||
因为我的一些计算机没有静态 IP / DNS 但仍想使用 rrb 备份,那我会使用反向安全隧道(作为 systemd 服务):
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Reverse SSH Tunnel
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/ssh -N -R 27276:localhost:22 -o "ExitOnForwardFailure yes" server
|
||||
KillMode=process
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
现在,隧道运行备份时,服务器可以通过 `ssh -p 27276 localhost` 命令或者使用 `.ssh/config` 到达服务器端。
|
||||
|
||||
```
|
||||
Host cr-remote
|
||||
HostName localhost
|
||||
Port 27276
|
||||
```
|
||||
|
||||
在谈论 SSH 攻击时,有时由于某些中断的路由会很难访问到服务器。在那种情况下你可以借道其他服务器的 SSH 连接,以获得更好的路由。在这种情况下,你可能通过美国连接访问到我的中国服务器,而来自德国的不可靠连接可能需要几个周:
|
||||
|
||||
```
|
||||
Host chn.ddnet.tw
|
||||
ProxyCommand ssh -q usa.ddnet.tw nc -q0 chn.ddnet.tw 22
|
||||
Port 22
|
||||
```
|
||||
|
||||
### 结语
|
||||
|
||||
感谢阅读我工具的收藏。这其中我也许遗漏了许多日常中自然成习惯的步骤。让我们来看看我的软件设置在下一年里能多稳定吧。如果你有任何问题,随时联系我 [dennis@felsin9.de][78] 。
|
||||
|
||||
在 [Hacker News][79] 下评论吧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://hookrace.net/blog/linux-desktop-setup/
|
||||
|
||||
作者:[Dennis Felsing][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[chenmu-kk](https://github.com/chenmu-kk)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://felsin9.de/nnis/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://hookrace.net/public/linux-desktop/htop_small.png
|
||||
[2]: https://hookrace.net/public/linux-desktop/htop.png
|
||||
[3]: https://gentoo.org/
|
||||
[4]: https://www.archlinux.org/
|
||||
[5]: https://www.archlinux.org/news/
|
||||
[6]: https://www.reddit.com/r/archlinux/comments/4zrsc3/keep_your_system_fully_functional_after_a_kernel/
|
||||
[7]: https://www.suse.com/
|
||||
[8]: https://ddnet.tw/
|
||||
[9]: https://www.debian.org/
|
||||
[10]: https://www.openbsd.org/
|
||||
[11]: https://www.openbsd.org/faq/pf/
|
||||
[12]: http://openbox.org/wiki/Main_Page
|
||||
[13]: http://fluxbox.org/
|
||||
[14]: https://dwm.suckless.org/
|
||||
[15]: https://awesomewm.org/
|
||||
[16]: https://xmonad.org/
|
||||
[17]: https://www.haskell.org/
|
||||
[18]: http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Layout-LayoutScreens.html
|
||||
[19]: http://robm.github.io/dzen/
|
||||
[20]: https://github.com/brndnmtthws/conky
|
||||
[21]: https://hookrace.net/public/linux-desktop/laptop_small.png
|
||||
[22]: https://hookrace.net/public/linux-desktop/laptop.png
|
||||
[23]: https://i3wm.org/
|
||||
[24]: https://github.com/tmux/tmux/wiki
|
||||
[25]: http://dtach.sourceforge.net/
|
||||
[26]: https://github.com/def-/tach/blob/master/tach
|
||||
[27]: https://www.gnu.org/software/bash/
|
||||
[28]: http://www.zsh.org/
|
||||
[29]: http://software.schmorp.de/pkg/rxvt-unicode.html
|
||||
[30]: http://terminus-font.sourceforge.net/
|
||||
[31]: https://www.vim.org/
|
||||
[32]: http://ctags.sourceforge.net/
|
||||
[33]: https://www.python.org/
|
||||
[34]: https://nim-lang.org/
|
||||
[35]: https://hisham.hm/htop/
|
||||
[36]: http://lm-sensors.org/
|
||||
[37]: https://01.org/powertop/
|
||||
[38]: https://dev.yorhel.nl/ncdu
|
||||
[39]: https://nmap.org/
|
||||
[40]: https://www.tcpdump.org/
|
||||
[41]: https://www.wireshark.org/
|
||||
[42]: http://www.fetchmail.info/
|
||||
[43]: http://www.procmail.org/
|
||||
[44]: https://marlam.de/msmtp/
|
||||
[45]: https://www.cis.upenn.edu/~bcpierce/unison/
|
||||
[46]: https://rsync.samba.org/
|
||||
[47]: http://www.mutt.org/
|
||||
[48]: https://newsboat.org/
|
||||
[49]: https://irssi.org/
|
||||
[50]: https://www.roaringpenguin.com/products/remind
|
||||
[51]: https://hookrace.net/public/linux-desktop/remcal.png
|
||||
[52]: https://github.com/tsdh/rdictcc
|
||||
[53]: https://www.dict.cc/
|
||||
[54]: https://www.latex-project.org/
|
||||
[55]: http://felsin9.de/nnis/research/
|
||||
[56]: https://pwmt.org/projects/zathura/
|
||||
[57]: https://wiki.gnome.org/Apps/Evince
|
||||
[58]: https://www.gimp.org/
|
||||
[59]: https://inkscape.org/
|
||||
[60]: https://imagemagick.org/Usage/
|
||||
[61]: https://www.graphviz.org/
|
||||
[62]: https://sourceforge.net/projects/pgf/
|
||||
[63]: https://www.mozilla.org/en-US/firefox/new/
|
||||
[64]: https://github.com/5digits/dactyl
|
||||
[65]: https://mpv.io/
|
||||
[66]: https://rg3.github.io/youtube-dl/
|
||||
[67]: http://moc.daper.net/
|
||||
[68]: https://aur.archlinux.org/packages/moc-pulse/
|
||||
[69]: https://hookrace.net/public/linux-desktop/moc.png
|
||||
[70]: https://github.com/libfuse/sshfs
|
||||
[71]: https://www.qemu.org/
|
||||
[72]: http://www.mingw.org/
|
||||
[73]: https://github.com/tpoechtrager/osxcross
|
||||
[74]: https://github.com/ddnet/ddnet-scripts/blob/master/ddnet-release.sh
|
||||
[75]: https://github.com/ddnet/ddnet-scripts/blob/master/ddnet-lib-update.sh
|
||||
[76]: https://github.com/def-/rrb/blob/master/rrb
|
||||
[77]: https://github.com/def-/rrb/blob/master/config.example
|
||||
[78]: mailto:dennis@felsin9.de
|
||||
[79]: https://news.ycombinator.com/item?id=18979731
|
Loading…
Reference in New Issue
Block a user