2021年7月

第一步是选择配置文件的格式:INI、JSON、YAML 或 TOML。

 title=

有时,程序需要足够的参数,将它们全部作为命令行参数或环境变量既不让人愉快也不可行。 在这些情况下,你将需要使用配置文件。

有几种流行的配置文件格式。其中包括古老的(虽然有时定义不明确)INI 格式,虽然流行但有时难以手写的 JSON 格式,使用广泛但有时在细节方面令人意外的 YAML 格式,以及很多人还没有听说过的最新出现的 TOML。

你的首要任务是选择一种格式,然后记录该选择。解决了这个简单的部分之后就是时候解析配置了。

有时,在配置中拥有一个与“抽象“数据相对应的类是一个不错的想法。因为这段代码不会对配置做任何事情,所以这是展示解析逻辑最简单的方式。

想象一下文件处理器的配置:它包括一个输入目录、一个输出目录和要提取的文件。

配置类的抽象定义可能类似于:

from __future__ import annotations
import attr

@attr.frozen
class Configuration:
    @attr.frozen
    class Files:
        input_dir: str
        output_dir: str
    files: Files
    @attr.frozen
    class Parameters:
        patterns: List[str]
    parameters: Parameters

为了使特定于格式的代码更简单,你还需要编写一个函数来从字典中解析此类。请注意,这假设配置将使用破折号,而不是下划线。 这种差异并不少见。

def configuration_from_dict(details):
    files = Configuration.Files(
        input_dir=details["files"]["input-dir"],
        output_dir=details["files"]["output-dir"],
    )
    parameters = Configuration.Paraneters(
        patterns=details["parameters"]["patterns"]
    )
    return Configuration(
        files=files,
        parameters=parameters,
    )

JSON

JSON(JavaScript Object Notation)是一种类似于 JavaScript 的格式。

以下是 JSON 格式的示例配置:

json_config = """
{
    "files": {
        "input-dir": "inputs",
        "output-dir": "outputs"
    },
    "parameters": {
        "patterns": [
            "*.txt",
            "*.md"
        ]
    }
}
"""

解析逻辑使用 json 模块将 JSON 解析为 Python 的内置数据结构(字典、列表、字符串),然后从字典中创建类:

import json
def configuration_from_json(data):
    parsed = json.loads(data)
    return configuration_from_dict(parsed)

INI

INI 格式,最初只在 Windows 上流行,之后成为配置标准格式。

这是与 INI 相同的配置:

ini_config="""
[files]
input-dir = inputs
output-dir = outputs

[parameters]
patterns = ['*.txt', '*.md']
"""

Python 可以使用内置的 configparser 模块解析它。解析器充当类似 dict 的对象,因此可以直接传递给 configuration_from_dict

import configparser

def configuration_from_ini(data):
    parser = configparser.ConfigParser()
    parser.read_string(data)
    return configuration_from_dict(parser)

YAML

YAML(Yet Another Markup Language)是 JSON 的扩展,旨在更易于手动编写。为了实现了这一点,部分原因是有一个很长的规范。

以下是 YAML 中的相同配置:

yaml_config = """
files:
  input-dir: inputs
  output-dir: outputs
parameters:
  patterns:
  - '*.txt'
  - '*.md'
"""

要让 Python 解析它,你需要安装第三方模块。最受欢迎的是PyYAMLpip install pyyaml)。 YAML 解析器还返回可以传递给 configuration_from_dict 的内置 Python 数据类型。但是,YAML 解析器需要一个字节流,因此你需要将字符串转换为字节流。

import io
import yaml
def configuration_from_yaml(data):
    fp = io.StringIO(data)
    parsed = yaml.safe_load(fp)
    return configuration_from_dict(parsed)

TOML

TOML(Tom's Own Markup Language)旨在成为 YAML 的轻量级替代品。其规范比较短,已经在一些地方流行了(比如 Rust 的包管理器 Cargo 就用它来进行包配置)。

这是与 TOML 相同的配置:

toml_config = """
[files]
input-dir = "inputs"
output-dir = "outputs"

[parameters]
patterns = [ "*.txt", "*.md",]
"""

为了解析 TOML,你需要安装第三方包。最流行的一种被简单地称为 toml。 与 YAML 和 JSON 一样,它返回基本的 Python 数据类型。

import toml
def configuration_from_toml(data):
    parsed = toml.loads(data)
    return configuration_from_dict(parsed)

总结

选择配置格式是一种微妙的权衡。但是,一旦你做出决定,Python 就可以使用少量代码来解析大多数流行的格式。


via: https://opensource.com/article/21/6/parse-configuration-files-python

作者:Moshe Zadka 选题:lujun9972 译者:zepoch 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

昨天我和一些人在闲聊的时候,他们说他们并不真正了解栈是如何工作的,而且也不知道如何去查看栈空间。

这是一个快速教程,介绍如何使用 GDB 查看 C 程序的栈空间。我认为这对于 Rust 程序来说也是相似的。但我这里仍然使用 C 语言,因为我发现用它更简单,而且用 C 语言也更容易写出错误的程序。

我们的测试程序

这里是一个简单的 C 程序,声明了一些变量,从标准输入读取两个字符串。一个字符串在堆上,另一个字符串在栈上。

#include <stdio.h>
#include <stdlib.h>

int main() {
    char stack_string[10] = "stack";
    int x = 10;
    char *heap_string;

    heap_string = malloc(50);

    printf("Enter a string for the stack: ");
    gets(stack_string);
    printf("Enter a string for the heap: ");
    gets(heap_string);
    printf("Stack string is: %s\n", stack_string);
    printf("Heap string is: %s\n", heap_string);
    printf("x is: %d\n", x);
}

这个程序使用了一个你可能从来不会使用的极为不安全的函数 gets 。但我是故意这样写的。当出现错误的时候,你就知道是为什么了。

第 0 步:编译这个程序

我们使用 gcc -g -O0 test.c -o test 命令来编译这个程序。

-g 选项会在编译程序中将调式信息也编译进去。这将会使我们查看我们的变量更加容易。

-O0 选项告诉 gcc 不要进行优化,我要确保我们的 x 变量不会被优化掉。

第一步:启动 GDB

像这样启动 GDB:

$ gdb ./test

它打印出一些 GPL 信息,然后给出一个提示符。让我们在 main 函数这里设置一个断点:

(gdb) b main

然后我们就可以运行程序:

(gdb) b main
Starting program: /home/bork/work/homepage/test
Breakpoint 1, 0x000055555555516d in main ()

(gdb) run
Starting program: /home/bork/work/homepage/test

Breakpoint 1, main () at test.c:4
4   int main() {

好了,现在程序已经运行起来了。我们就可以开始查看栈空间了。

第二步:查看我们变量的地址

让我们从了解我们的变量开始。它们每个都在内存中有一个地址,我们可以像这样打印出来:

(gdb) p &x
$3 = (int *) 0x7fffffffe27c
(gdb) p &heap_string
$2 = (char **) 0x7fffffffe280
(gdb) p &stack_string
$4 = (char (*)[10]) 0x7fffffffe28e

因此,如果我们查看那些地址的堆栈,那我们应该能够看到所有的这些变量!

概念:栈指针

我们将需要使用栈指针,因此我将尽力对其进行快速解释。

有一个名为 ESP 的 x86 寄存器,称为“ 栈指针 stack pointer ”。 基本上,它是当前函数的栈起始地址。 在 GDB 中,你可以使用 $sp 来访问它。 当你调用新函数或从函数返回时,栈指针的值会更改。

第三步:在 main 函数开始的时候,我们查看一下在栈上的变量

首先,让我们看一下 main 函数开始时的栈。 现在是我们的堆栈指针的值:

(gdb) p $sp
$7 = (void *) 0x7fffffffe270

因此,我们当前函数的栈起始地址是 0x7fffffffe270,酷极了。

现在,让我们使用 GDB 打印出当前函数堆栈开始后的前 40 个字(即 160 个字节)。 某些内存可能不是栈的一部分,因为我不太确定这里的堆栈有多大。 但是至少开始的地方是栈的一部分。

我已粗体显示了 stack_stringheap_stringx 变量的位置,并改变了颜色:

  • x 是红色字体,并且起始地址是 0x7fffffffe27c
  • heap_string 是蓝色字体,起始地址是 0x7fffffffe280
  • stack_string 是紫色字体,起始地址是 0x7fffffffe28e

你可能会在这里注意到的一件奇怪的事情是 x 的值是 0x5555,但是我们将 x 设置为 10! 那是因为直到我们的 main 函数运行之后才真正设置 x ,而我们现在才到了 main 最开始的地方。

第三步:运行到第十行代码后,再次查看一下我们的堆栈

让我们跳过几行,等待变量实际设置为其初始化值。 到第 10 行时,x 应该设置为 10

首先我们需要设置另一个断点:

(gdb) b test.c:10
Breakpoint 2 at 0x5555555551a9: file test.c, line 11.

然后继续执行程序:

(gdb) continue
Continuing.

Breakpoint 2, main () at test.c:11
11      printf("Enter a string for the stack: ");

好的! 让我们再来看看堆栈里的内容! gdb 在这里格式化字节的方式略有不同,实际上我也不太关心这些(LCTT 译注:可以查看 GDB 手册中 x 命令,可以指定 c 来控制输出的格式)。 这里提醒一下你,我们的变量在栈上的位置:

  • x 是红色字体,并且起始地址是 0x7fffffffe27c
  • heap_string 是蓝色字体,起始地址是 0x7fffffffe280
  • stack_string 是紫色字体,起始地址是 0x7fffffffe28e

在继续往下看之前,这里有一些有趣的事情要讨论。

stack_string 在内存中是如何表示的

现在(第 10 行),stack_string 被设置为字符串stack。 让我们看看它在内存中的表示方式。

我们可以像这样打印出字符串中的字节(LCTT 译注:可以通过 c 选项直接显示为字符):

(gdb) x/10x stack_string
0x7fffffffe28e: 0x73    0x74    0x61    0x63    0x6b    0x00    0x00    0x00
0x7fffffffe296: 0x00    0x00

stack 是一个长度为 5 的字符串,相对应 5 个 ASCII 码- 0x730x740x610x630x6b0x73 是字符 s 的 ASCII 码。 0x74t 的 ASCII 码。等等...

同时我们也使用 x/1s 可以让 GDB 以字符串的方式显示:

(gdb) x/1s stack_string
0x7fffffffe28e: "stack"

heap_stringstack_string 有何不同

你已经注意到了 stack_stringheap_string 在栈上的表示非常不同:

  • stack_string 是一段字符串内容(stack
  • heap_string 是一个指针,指向内存中的某个位置

这里是 heap_string 变量在内存中的内容:

0xa0  0x92  0x55  0x55  0x55  0x55  0x00  0x00

这些字节实际上应该是从右向左读:因为 x86 是小端模式,因此,heap_string 中所存放的内存地址 0x5555555592a0

另一种方式查看 heap_string 中存放的内存地址就是使用 p 命令直接打印 :

(gdb) p heap_string
$6 = 0x5555555592a0 ""

整数 x 的字节表示

x 是一个 32 位的整数,可由 0x0a 0x00 0x00 0x00 来表示。

我们还是需要反向来读取这些字节(和我们读取 heap_string 需要反过来读是一样的),因此这个数表示的是 0x000000000a 或者是 0x0a,它是一个数字 10;

这就让我把把 x 设置成了 10

第四步:从标准输入读取

好了,现在我们已经初始化我们的变量,我们来看一下当这段程序运行的时候,栈空间会如何变化:

printf("Enter a string for the stack: ");
gets(stack_string);
printf("Enter a string for the heap: ");
gets(heap_string);

我们需要设置另外一个断点:

(gdb) b test.c:16
Breakpoint 3 at 0x555555555205: file test.c, line 16.

然后继续执行程序:

(gdb) continue
Continuing.

我们输入两个字符串,为栈上存储的变量输入 123456789012 并且为在堆上存储的变量输入 bananas;

让我们先来看一下 stack_string(这里有一个缓存区溢出)

(gdb) x/1s stack_string
0x7fffffffe28e: "123456789012"

这看起来相当正常,对吗?我们输入了 12345679012,然后现在它也被设置成了 12345679012(LCTT 译注:实测 gcc 8.3 环境下,会直接段错误)。

但是现在有一些很奇怪的事。这是我们程序的栈空间的内容。有一些紫色高亮的内容。

令人奇怪的是 stack_string 只支持 10 个字节。但是现在当我们输入了 13 个字符以后,发生了什么?

这是一个典型的缓冲区溢出,stack_string 将自己的数据写在了程序中的其他地方。在我们的案例中,这还没有造成问题,但它会使你的程序崩溃,或者更糟糕的是,使你面临非常糟糕的安全问题。

例如,假设 stack_string 在内存里的位置刚好在 heap_string 之前。那我们就可能覆盖 heap_string 所指向的地址。我并不确定 stack_string 之后的内存里有一些什么。但我们也许可以用它来做一些诡异的事情。

确实检测到了有缓存区溢出

当我故意写很多字符的时候:

 ./test
Enter a string for the stack: 01234567891324143
Enter a string for the heap: adsf
Stack string is: 01234567891324143
Heap string is: adsf
x is: 10
*** stack smashing detected ***: terminated
fish: Job 1, './test' terminated by signal SIGABRT (Abort)

这里我猜是 stack_string 已经到达了这个函数栈的底部,因此额外的字符将会被写在另一块内存中。

当你故意去使用这个安全漏洞时,它被称为“堆栈粉碎”,而且不知何故有东西在检测这种情况的发生。

我也觉得这很有趣,虽然程序被杀死了,但是当缓冲区溢出发生时它不会立即被杀死——在缓冲区溢出之后再运行几行代码,程序才会被杀死。 好奇怪!

这些就是关于缓存区溢出的所有内容。

现在我们来看一下 heap_string

我们仍然将 bananas 输入到 heap_string 变量中。让我们来看一下内存中的样子。

这是在我们读取了字符串以后,heap_string 在栈空间上的样子:

需要注意的是,这里的值是一个地址。并且这个地址并没有改变,但是我们来看一下指向的内存上的内容。

(gdb) x/10x 0x5555555592a0
0x5555555592a0: 0x62    0x61    0x6e    0x61    0x6e    0x61    0x73    0x00
0x5555555592a8: 0x00    0x00

看到了吗,这就是字符串 bananas 的字节表示。这些字节并不在栈空间上。他们存在于内存中的堆上。

堆和栈到底在哪里?

我们已经讨论过栈和堆是不同的内存区域,但是你怎么知道它们在内存中的位置呢?

每个进程都有一个名为 /proc/$PID/maps 的文件,它显示了每个进程的内存映射。 在这里你可以看到其中的栈和堆。

$ cat /proc/24963/maps
... lots of stuff omitted ...
555555559000-55555557a000 rw-p 00000000 00:00 0                          [heap]
... lots of stuff omitted ...
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]

需要注意的一件事是,这里堆地址以 0x5555 开头,栈地址以 0x7fffff 开头。 所以很容易区分栈上的地址和堆上的地址之间的区别。

像这样使用 gdb 真的很有帮助

这有点像旋风之旅,虽然我没有解释所有内容,但希望看到数据在内存中的实际情况可以使你更清楚地了解堆栈的实际情况。

我真的建议像这样来把玩一下 gdb —— 即使你不理解你在内存中看到的每一件事,我发现实际上像这样看到我程序内存中的数据会使抽象的概念,比如“栈”和“堆”和“指针”更容易理解。

更多练习

一些关于思考栈的后续练习的想法(没有特定的顺序):

  • 尝试将另一个函数添加到 test.c 并在该函数的开头创建一个断点,看看是否可以从 main 中找到堆栈! 他们说当你调用一个函数时“堆栈会变小”,你能在 gdb 中看到这种情况吗?
  • 从函数返回一个指向栈上字符串的指针,看看哪里出了问题。 为什么返回指向栈上字符串的指针是不好的?
  • 尝试在 C 中引起堆栈溢出,并尝试通过在 gdb 中查看堆栈溢出来准确理解会发生什么!
  • 查看 Rust 程序中的堆栈并尝试找到变量!
  • 噩梦课程 中尝试一些缓冲区溢出挑战。每个问题的答案写在 README 文件中,因此如果你不想被宠坏,请避免先去看答案。 所有这些挑战的想法是给你一个二进制文件,你需要弄清楚如何导致缓冲区溢出以使其打印出 flag 字符串。

via: https://jvns.ca/blog/2021/05/17/how-to-look-at-the-stack-in-gdb/

作者:Julia Evans 选题:lujun9972 译者:amwps290 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Bitcoin.org 败诉,需支付“中本聪” 35,000 英镑

英国高等法院裁决Bitcoin.org 不能再在其网站上分享发布于 2008 年的《比特币白皮书》,Craig Wright 声称是该文件的原始作者“中本聪”。Bitcoin.org 的匿名创始人 Cobra 因为担心暴露身份而没有出席法院辩论,所以 Wright 以默认方式赢得了他提起的版权侵权案件。因此,Bitcoin.org 必须支付 35,000 英镑的法律费用,并在其网站上发布法院命令的通知,为期六个月。

这么说,在英国《比特币白皮书》的使用要看“版权方”的脸色了。

古老的编程语言正面临人才青黄不接

许多大型组织仍在依赖陈旧的 IT 系统和编程语言来支撑大型机的运转。但随着老一代开发者到了退休年龄,行业内正面临着人才青黄不接的尴尬局面。这些系统通常以诞生于 1959 年的 COBOL 等编程语言为基础,目前仍被许多大型组织广泛用于处理某些重要的中央系统数据,比如计费、账户、工资单和客户交易。比如,美国财政部国税局的“六号系统”,正是用汇编程序和 COBOL 语言来管理包含纳税人在内的各种数据的。

Advanced Software 调查的 400 家组织中,有 3/4 表示 COBOL 仍是其大型机应用中最主要的依赖语言,66% 的大型企业仍在使用汇编程序,其它主要语言包括 ADS/Online(40%)、CA Gen(37%)、CA Telon(24%)、以及 PL/1(15%)。

套用一句运维潜规则,“能运行的就不要去动”。越是老旧的系统和平台,越是没人敢碰。

“天河”E级验证系统获得图计算领域两项世界第一

据新华网报道,由国防科技大学研制,部署在国家超级计算天津中心的“天河”E级(百亿亿次)计算机关键技术验证系统,在 7 月 1 日发布的国际 Graph500 排名中,获得单源最短路径榜单世界第一和大数据图计算能效榜单世界第一的佳绩。

国家超级计算天津中心也是我国首个千万亿次超算“天河一号”部署所在地。

可喜可贺,榜单排名是一方面,希望可以在实际研究中取得重要应用。

下面是我如何在我的 FreeDOS 虚拟机和 Linux 桌面系统之间传输文件。

 title=

我运行 Linux 作为我的主要操作系统,我在一个虚拟机中启动 FreeDOS。大多数时候,我使用 QEMU 作为我的 PC 模拟器,但有时我会用 GNOME Boxes(它使用 QEMU 作为后端虚拟机)或用 VirtualBox 运行其他实验。

我喜欢玩经典的 DOS 游戏,有时我也会调出一个最喜欢的 DOS 应用。我在管理信息系统(MIS)课上讲计算机的历史,有时我会用 FreeDOS 和一个传统的 DOS 应用录制一个演示,比如 As-Easy-As(我最喜欢的 DOS 电子表格,曾经作为“共享软件”发布,但现在可以 从 TRIUS 公司免费获得)。

但是以这种方式使用 FreeDOS 意味着我需要在我的 FreeDOS 虚拟机和我的 Linux桌 面系统之间传输文件。让我来展示是如何做到这一点的。

用 guestmount 访问镜像

我曾经通过计算第一个 DOS 分区的偏移量来访问我的虚拟磁盘镜像,然后用正确的选项组合来调用 Linux 的 mount 命令来匹配这个偏移量。这总是很容易出错,而且不是很灵活。幸运的是,有一个更简单的方法可以做到这一点。来自 libguestfs-tools 包的 guestmount 程序可以让你从 Linux 中访问或 挂载 虚拟磁盘镜像。你可以在 Fedora 上用这个命令安装 libguestfs-tools

$ yum install libguestfs-tools libguestfs

使用 guestmount 并不像从 GNOME 文件管理器中双击文件那么简单,但命令行的使用并不难。guestmount 的基本用法是:

$ guestmount -a image -m device mountpoint

在这个用法中,image 是要使用的虚拟磁盘镜像。在我的系统中,我用 qemu-img 命令创建了 QEMU 虚拟磁盘镜像。guestmount 程序可以读取这种磁盘镜像格式,以及 GNOME Boxes 使用的 QCOW2 镜像格式,或者 VirtualBox 使用的 VDI 镜像格式。

device 选项表示虚拟磁盘上的分区。想象一下,把这个虚拟磁盘当作一个真正的硬盘使用。你可以用 /dev/sda1 访问第一个分区,用 /dev/sda2 访问第二个分区,以此类推。这就是 guestmount 的语法。默认情况下,FreeDOS 1.3 RC4 在一个空的驱动器上创建了一个分区,所以访问这个分区的时候要用 /dev/sda1

mountpoint 是在你的本地 Linux 系统上“挂载” DOS 文件系统的位置。我通常会创建一个临时目录来工作。你只在访问虚拟磁盘时需要挂载点。

综上所述,我使用这组命令从 Linux 访问我的 FreeDOS 虚拟磁盘镜像:

$ mkdir /tmp/freedos
$ guestmount -a freedos.img -m /dev/sda1 /tmp/freedos

之后,我可以通过 /tmp/freedos 目录访问我的 FreeDOS 文件,使用 Linux 上的普通工具。我可以在命令行中使用 ls /tmp/freedos,或者使用桌面文件管理器打开 /tmp/freedos 挂载点。

$ ls -l /tmp/freedos
total 216
drwxr-xr-x. 5 root root 8192 May 10 15:53 APPS
-rwxr-xr-x. 1 root root 85048 Apr 30 07:54 COMMAND.COM
-rwxr-xr-x. 1 root root  103 May 13 15:48 CONFIG.SYS
drwxr-xr-x. 5 root root 8192 May 15 16:52 DEVEL
drwxr-xr-x. 2 root root 8192 May 15 13:36 EDLIN
-rwxr-xr-x. 1 root root 1821 May 10 15:57 FDAUTO.BAT
-rwxr-xr-x. 1 root root  740 May 13 15:47 FDCONFIG.SYS
drwxr-xr-x. 10 root root 8192 May 10 15:49 FDOS
-rwxr-xr-x. 1 root root 46685 Apr 30 07:54 KERNEL.SYS
drwxr-xr-x. 2 root root 8192 May 10 15:57 SRC
-rwxr-xr-x. 1 root root 3190 May 16 08:34 SRC.ZIP
drwxr-xr-x. 3 root root 8192 May 11 18:33 TEMP

 title=

使用 GNOME 文件管理器来访问虚拟磁盘

例如,要从我的 Linux projects 目录中复制几个 C 源文件到虚拟磁盘镜像上的 C:\SRC,以便我以后能在 FreeDOS 下使用这些文件,我可以使用 Linux cp 命令:

$ cp /home/jhall/projects/*.c /tmp/freedos/SRC

虚拟驱动器上的文件和目录在技术上是不分大小写的,所以你可以用大写或小写字母来引用它们。然而,我发现使用所有大写字母来输入 DOS 文件和目录更为自然。

$ ls /tmp/freedos
APPS     CONFIG.SYS EDLIN    FDCONFIG.SYS KERNEL.SYS SRC.ZIP
COMMAND.COM DEVEL    FDAUTO.BAT FDOS     SRC     TEMP

$ ls /tmp/freedos/EDLIN
EDLIN.EXE MAKEFILE.OW

$ ls /tmp/freedos/edlin
EDLIN.EXE MAKEFILE.OW

用 guestmount 卸载

在你再次在虚拟机中使用虚拟磁盘镜像之前,你应该总是先 卸载。如果你在运行 QEMU 或 VirtualBox 时让镜像挂载,你有可能弄乱你的文件。

guestmount 配套的命令是 guestunmount,用来卸载磁盘镜像。只要给出你想卸载的挂载点就可以了:

$ guestunmount /tmp/freedos

请注意命令拼写与 Linux 的 umount 稍有不同。


via: https://opensource.com/article/21/6/copy-files-linux-freedos

作者:Jim Hall 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

与 “MAGFest 先生” Brendan Becker 的对话。

 title=

1999 年,我在一家计算机商店工作时遇到了 Brendan Becker。我们都喜欢构建定制计算机并在其上安装 Linux。Brendan 一直在同时参与着从游戏编程到音乐创作的多个技术项目。从那之后快进几年,他继续编写 pyDance,这是一个多舞种游戏的开源实现,然后成为了音乐和游戏项目 MAGFest 的 CEO。他有时被称为 “MAGFest 先生”,因为他是该项目的负责人,Brendan 现在使用的音乐笔名是 “Inverse Phase”,是一位 电子合音 chiptune (主要在 8 位计算机和游戏机上创作的音乐)作曲家。

我认为采访并询问他在整个职业生涯中如何从 Linux 和开源软件中受益的一些细节会很有趣。

 title=

你是如何开始接触计算机和软件的?

Brendan Becker:从我记事起,我家就有一台电脑。我父亲热衷于技术;在康柏便携式电脑刚刚上市时,他就带了一台回家,当他不在上面工作时,我就可以使用它。由于我两岁时就开始阅读,使用电脑就成了我的第二天性——只要阅读磁盘上的内容,按照说明进行操作,我就可以玩游戏了!有时我会玩一些学习和教育软件,我们有几张装满游戏的磁盘,我可以在其他时间玩。我记得有一张磁盘,里面有一些流行游戏的免费副本。后来,我父亲向我展示了我们可以呼叫其他计算机(我 5 岁时就上了 BBS!),我看到了一些游戏来自那儿。我喜欢玩的一款游戏是用 BASIC 编写的,当我意识到我可以简单地修改游戏,只需阅读一些内容并重新输入它们游戏就会更轻松,玩游戏就没意思了。

这是上世纪 80 年代?

Becker:康柏便携式电脑于 1983 年推出,这可以给你一些参考。我爸爸有一个那个型号的初代产品。

你是如何进入 Linux 和开源软件的?

Becker:在上世纪 90 年代初,我酷爱 MOD 和 演示场景 demoscene 之类的东西,我注意到 Walnut Creek(即 cdrom.com;现已解散)在 FreeBSD 上开设了商店。总的来说,我对 Unix 和其他操作系统非常好奇,但没有太多的第一手资料,我认为是时候尝试一些东西了。当时 DOOM 刚刚发布,有人告诉我,我可以试着在计算机上运行它。在这与能够运行很酷的互联网服务器之间,我开始陷入两难取舍。有人看到我在阅读有关 FreeBSD 的文章,并建议我了解一下 Linux,这是一个为 x86 重新编写的新操作系统,与 BSD 不同,(他们说)后者存在一些兼容性问题。因此,我加入了 undernet IRC 上的 #linuxhelp 频道,询问如何开始使用 Linux,并表明我已经做了一些研究(我已经能问出 “Red Hat 和 Slackware 之间有什么区别?”这样的问题),想知道什么是最容易使用的。频道里唯一说话的人说他已经 13 岁了,他都能弄明白 Slackware,所以我应该不会有问题。学校的一个数学老师给了我一个硬盘,我下载了 “A” 盘组和一个启动盘,写入到软盘,安装了它,回头看也并没有花太多时间。

你是如何被称为 “MAGFest 先生”的?

Becker:嗯,这个很简单。在第一个活动后,我几乎立即成为了 MAGFest 的代理负责人。前任主席都各奔东西,我向负责人要求不要取消活动。解决方案就是自己运营它,当我慢慢地将项目塑造成我自己的时,这个昵称就成了我的。

我记得我在早期参加过,MAGFest 最终变得有多大?

Becker:第一届 MAGFest 是 265 人。现在它超大,有两万多名不同的参与者。

太棒了!你能简要描述一下 MAGFest 大会吗?

Becker:我的一个朋友 Hex 描述得非常好。他说:“就像是和你所有的朋友一起举办这个以电子游戏为主题的生日派对,那里恰好有几千人,如果你愿意,他们都可以成为你的朋友,然后还有摇滚音乐会。” 这很快被采用并缩短为 “这是一个为期四天的电子游戏派对,有多场电子游戏摇滚音乐会”。通常 “音乐和游戏节” 这句话就能让人们明白这个意思。

你是如何利用开源软件来运行 MAGFest 的?

Becker:当我成为 MAGFest 的负责人时,我已经用 Python 编写了一个游戏,所以我觉得用 Python 编写我们的注册系统最舒服。这是一个非常轻松的决定,因为不涉及任何费用,而且我已经有了经验。后来,我们的在线注册系统和拼车界面都是用 PHP/MySQL 编写的,我们的论坛使用了 Kboard。最终,这发展到我们用 Python 从头开始编写了自己的注册系统,我们也在活动中使用它,并在主网站上运行 Drupal。有一次,我还用 Python 编写了一个系统来管理视频室和邀请比赛站。哦,我们有一些游戏音乐收听站,你可以翻阅标志性的游戏 OST(原始音轨)的曲目和简介,和演奏 MAGFest 的乐队。

我知道几年前你减少了你在 MAGFest 的职责,去追求新的项目。你接下来的努力是什么?

Becker:我一直非常投入游戏音乐领域,并试图将尽可能多的音乐带到 MAGFest 中。随着我越来越多地成为这些社区的一部分,我想参与其中。我使用以前用过的自由开源版本的 DOS 和 Windows 演示场景工具编写了一些视频游戏曲调的混合曲、封面和编曲,我以前使用过的这种工具也是免费的,但不一定是开源的。我在运行 MAGFest 的最初几年发布了一些曲目,然后在 Jake Kaufman(也被称为 virt;在他的简历之外也叫 Shovel Knight 和 Shantae)的一些严厉的关爱和建议之后,我改变主题到我更擅长的电子和音。尽管我小时候就用我的康柏便携式电脑编写了 PC 扬声器发出的哔哔啵啵声,并在 90 年代的演示场景中写过 MOD 文件,但我在 2006 年发布了第一首 NES 规格的曲目,我真的能很自豪地称之为我自己的作品。随后还有几张流行音乐的作品和专辑。

2010 年,有很多人找我做游戏配乐工作。尽管配乐工作对它没有太大影响,但我开始更认真地缩减我在 MAGFest 的一些职责,并且在 2011 年,我决定更多地进入幕后。我会留在董事会担任顾问,帮助人们了解他们需要什么来管理他们的部门,但我不再掌舵了。与此同时,我的兼职工作,即给我支付账单的工作,解雇了他们所有的工人,我突然发现自己有了很多空闲时间。我开始写《 Pretty Eight Machine》,这是一首向《Nine Inch Nails》致敬的作品,我在这个事情和游戏配乐工作之间花了一年多,我向自己证明了我可以用音乐来(即便只是勉强)维持生计,这就是我接下来想做的。

 title=

版权所有 Inverse Phase,经许可使用。

就硬件和软件而言,你的工作空间是什么样的?

Becker:在我的 DOS/Windows 时代,我主要使用 FastTracker 2。在 Linux 中,我将其替换为 SoundTracker(不是 Karsten Obarski 的原始版本,而是 GTK 重写版本;参见 soundtracker.org)。近来,SoundTracker 处于不断变化的状态——虽然我仍然需要尝试新的 GTK3 版本——但是当我无法使用 SoundTracker 时,MilkyTracker 是一个很好的替代品。如果我真的需要原版 FastTracker 2,虽然老旧但它也可以在 DOSBox 中运行起来。然而,那是我开始使用 Linux 的时候,所以这是我在 20-25 年前发现的东西。

在过去的十年里,我已经从基于采样的音乐转向了电子和音,这是由来自 8 位和 16 位游戏系统和计算机的旧声音芯片合成的音乐。有一个非常好的跨平台工具叫 Deflemask,可以为许多这些系统编写音乐。不过,我想为其创作音乐的一些系统不受支持,而且 Deflemask 是闭源的,因此我已经开始使用 Python 和 Pygame 从头开始构建自己的音乐创作环境。我使用 Git 维护我的代码树,并将使用开源的 KiCad 控制硬件合成器板。

你目前专注于哪些项目?

Becker:我断断续续地从事于游戏配乐和音乐委托工作。在此期间,我还一直致力于创办一个名为 Bloop 的电子娱乐博物馆。我们在档案和库存方面做了很多很酷的事情,但也许最令人兴奋的是我们一直在用树莓派构建展览。它们的用途非常广泛,而且我觉得很奇怪,如果我在十年前尝试这样做,我就不会有可以驱动我的展品的小型单板计算机;我可能会用把一个平板固定在笔记本电脑的背面!

现在有更多游戏平台进入 Linux,例如 Steam、Lutris 和 Play-on-Linux。你认为这种趋势会持续下去吗?这些会一直存在吗?

Becker:作为一个在 Linux 上玩了 25 年游戏的人——事实上,我 是因为 游戏才接触 Linux 的——我想我认为这个问题比大多数人认为的更艰难。我已经玩了 Linux 原生游戏几十年了,我甚至不得不对收回我当年说的“要么存在 Linux 解决方案,要么编写出来”这样的话,但最终,我做到了,我编写了一个 Linux 游戏。

说实话:Android 问世于 2008 年。如果你在 Android 上玩过游戏,那么你就在 Linux 上玩过游戏。Steam 在 Linux 已经八年了。Steambox/SteamOS 发布在 Steam 发布一年后。我没有听到太多 Lutris 或 Play-on-Linux 的消息,但我知道它们并希望它们成功。我确实看到 GOG 的追随者非常多,我认为这非常好。我看到很多来自 Ryan Gordon(icculus)和 Ethan Lee(flibitijibibo)等人的高质量游戏移植,甚至有些公司在内部移植。Unity 和 Unreal 等游戏引擎已经支持 Linux。Valve 已经将 Proton 纳入 Linux 版本的 Steam 已有两年左右的时间了,所以现在 Linux 用户甚至不必搜索他们游戏的 Linux 原生版本。

我可以说,我认为大多数游戏玩家期待并将继续期待他们已经从零售游戏市场获得的支持水平。就我个人而言,我希望这个水平是增长而不是下降!

详细了解 Brendan 的 Inverse Phase 工作。


via: https://opensource.com/article/20/2/linux-open-source-music

作者:Alan Formy-Duval 选题:lujun9972 译者:stevenzdg988 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

谷歌要用新的安卓软件包格式取代 APK

自 2008 年安卓发布以来,其软件包一直是 APK 格式。但谷歌想要更好的控制安卓应用的发布,宣布从 8 月开始上传到 Play 商店的应用必须使用安卓应用打包格式 AAB。谷歌是在 2018 年推出 AAB 的,其背后动机是安卓支持的语言、CPU 架构和屏幕分辨率越来越多,单一的版本太占空间,因此通过提供多个 APK 文件集合,由 Play 商店根据相应的设备提供相应的特定 APK。但从 APK 切换到 AAB,谷歌对安卓生态系统有了更大的控制,因为 AAB 需要 Play 商店的云计算进行处理,增加了第三方应用商店的工作和困难。

假借技术之名的垄断之举,是谷歌对安卓的开放生态的收割。

暂缓废除第三方 cookie 后,谷歌提出第二种替代方案

在谷歌提出的 FLoC 方案遭到业界的联合反对之后,上周,谷歌提出暂缓废除第三方 cookie,允许它们存活到 2023 年底。现在,谷歌提案了一种新的“分区 cookies” 方案 CHIPS。该提案要求第三方服务器可以设置 Cookie,但只能在最初设置 Cookie 的第一方网站范围内读取,而不能在其它也设置该 Cookie 的网站中读取。

这个方案似乎不错,而且 FireFox 和 Safari 也实现了类似的方案。

多个托管服务提供商遭遇 REvil 供应链攻击

REvil 勒索软件团伙又盯上了拥有数千名客户的多个大型托管服务提供商,大约有 200 家企业被加密。所有受影响的托管服务提供商都在使用 Kaseya VSA,且有证据表明他们的客户也受到了影响。Kaseya VSA 是一个基于云的 MSP 平台,允许提供商为客户执行补丁管理和客户端监控任务。Kaseya 在网站上发布了安全公告,警告所有 VSA 客户立即关闭他们的服务器,以防止事态的进一步蔓延。

利用供应链攻击进行的勒索攻击其影响广泛,目前看起来还没有特别好的方法。