分类 技术 下的文章

用这个方便的 Linux 命令合并 PDF、删除页面、分割 PDF 和填写表格。

 title=

技术白皮书、手稿和 RPG 手册,我每天都要处理大量的 PDF 文件。PDF 格式之所以受欢迎,是因为它包含经过处理的 PostScript 代码。PostScript 是现代打印机的原生语言,所以出版商经常将一本书的数字版本发布为 PDF,因为他们已经投入了时间和精力来制作印刷用的文件。但是,PDF 并不是一种可编辑的格式,虽然可以进行一些逆向处理,但它是数字数据发送到打印机之前的最后一站。即便如此,有时你还是需要对 PDF 进行调整,而我最喜欢的工具之一就是 pdftk-java 命令。

在 Linux 上安装 pdftk-java

顾名思义,pdftk-java 是用 Java 编写的,所以只要你安装了 Java,它就能在所有主流的操作系统上工作。

Linux 和 macOS 用户可以从 AdoptOpenJDK.net 安装 Java。Windows 用户可以安装 Red Hat 的 OpenJDK 的 Windows版本

要安装 pdftk-java

1、从 Gitlab 仓库下载 pdftk-all.jar 程序,并将其保存到 ~/.local/bin/你 path 变量中的其他位置

2、在你喜欢的文本编辑器中打开 ~/.bashrc 并添加这一行:

alias pdftk='java -jar $HOME/.local/bin/pdftk-all.jar'

3、加载你的新 Bash 设置:

$ source ~/.bashrc

命令语法

一个有效的 pdftk-java 命令的结构遵循一个模式,但在模式中的内容有很大的灵活性。语法有点不寻常,因为它没有使用传统风格的 终端选项,但经过实践,它并不难记。

  • pdftk:调用该命令的别名
  • 输入文件:你想修改的 PDF 文件
  • 动作:你想对输入文件做什么
  • 输出:你想在哪里保存你修改过的 PDF 文件

最复杂的是动作部分,所以我将从简单的任务开始。

将两个 PDF 文件合并成一个

一本书的封面通常在一个单独的应用中创建,如 Inkscape 或 GIMP,而书的其他部分通常在 Scribus 等排版程序或 LibreOffice 等办公套件中完成,这种情况并不罕见。你可以在你的排版应用中把这两者结合起来。像 Scribus 这样的出版软件可以很容易地引用一张图片,这样当封面改变时,它就会在版面中自动更新。然而,也可以用 pdftk-java 将封面预置到 PDF 中:

$ pdftk cover.pdf body.pdf \
  cat \
  output book.pdf

在这个例子中,动作是 cat 连接 concatenate 的缩写,和 Linux 的 cat 命令 一样,它将一个或多个 PDF 文件串联成一个数据流,数据流被引导到“ 输出 output ”参数指定的任何文件中。

从一个 PDF 中删除页面

你不能确切地从一个 PDF 中删除一页,但你可以创建一个新的 PDF,只包含你想保留的页面。

$ pdftk book.pdf \
  cat 1 3-end \
  output shorter-book.pdf

在这个例子中,我的书的文件的第 1 页,以及从 3 到结尾的所有页面,都被保存到一个新文件中。因此,我删除的那一页是第 2 页。

将一个 PDF 分割成不同的文件

将一个 PDF 文件分割成许多不同的文件也使用 cat 动作,它的原理与删除页面相似。你可以通过将你想要的页面发送到一个新文件来分割一个 PDF:

$ pdftk book.pdf \
  cat 1-15 \
  output part-1.pdf
$ pdftk book.pdf \
  cat 16-42 \
  output part-2.pdf

如果你需要将一个 PDF 分割成单页文件,有一个特殊的动作,叫做 burst

$ pdftk book.pdf burst
$ ls
book.pdf pg_0001.pdf pg_0002.pdf
pg_0003.pdf pg_0004.pdf pg_0005.pdf
[...]

填写表格

很少有人能否认多年来 PDF 格式变得越来越臃肿,而你有时在 PDF 文件中发现的一个功能是可填写的表格。你会在美国税务文件、RPG 角色表、线上学校作业本和其他旨在互动的 PDF 文件中看到这种情况。虽然大多数现代的 PDF 浏览器,比如 GNOME 的 Evince 和 KDE 的 Okular,都可以填写 PDF 表格,但你也可以在 pdftk-java 的帮助下填写 PDF 表格。

首先,你必须使用 generate_fdf 动作提取表单数据。这将提取表单元素的 ID,并将它们放入一个文本文件。

$ pdftk character-sheet.pdf \
  generate_fdf \
  output chsheet-form.txt

你的目标文件(在这个例子中是 chsheet-form.txt)包含 PDF 中的表格数据,但只是文本部分。你可以在任何标准的文本编辑器中编辑它,如 AtomGedit

在对生成 PDF 的组织的工作流程的有时令人钦佩和有时尴尬的一瞥中,你会发现一些表格有明确的标签,而其他表格有默认的名字,如 “Checkbox\_001” 和 “Textfield-021”,所以你可能要把你的文本文件和你的 PDF 对照一下,但如果你要写一个脚本来自动填写表格,这可能是值得的。每个标签都被标记为 /T 项,在接下来的一行中,有空间(标记为 /V)提供给文本输入。下面是一个片段,它的标签有上下文,并填入了一些数据:

/T (CharacterName 2)
/V (Abaddon)
>>
<<
/T (SlotsTotal 24)
/V ()
>>
<<
/T (Hair)
/V (Brown)
>>
<<
/T (AC)
/V (15)
>>
<<
/T (Background)
/V ()
>>
<<
/T (DEXmod )
/V ()

当你输入了表单数据,你就可以用 fill_form 动作将你的文本输入与 PDF 结构结合起来:

$ pdftk character-sheet.pdf \
  fill_form chsheet-form.txt \
  output completed.pdf

下面是一个结果示例。

 title=

PDF 修改变得简单

当你处理大量的 PDF 文件或通过 shell 脚本处理 PDF 文件时,像 pdftk-java 这样的工具是非常有价值的,因为它使你不必手动做所有的事情。当我从 Docbook 的输出建立一个 PDF 时,它是一个 Makefile,调用 pdftk-java 完成任何数量的任务,所以我没有机会忘记某个步骤或打错命令,也没有必要把时间花在这上面。在你自己的工作流程中,还有很多其他的原因你可能会使用 pdftk-java,它还可以做很多其他的事情,包括 shufflerotatedump_dataupdate_infoattach_files 等动作。如果你发现自己经常与 PDF 文件打交道,可以试试 pdftk-java


via: https://opensource.com/article/21/12/edit-pdf-linux-pdftk

作者:Seth Kenlon 选题:lujun9972 译者:geekpi 校对:wxy

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

你可能已经注意到,当你在 GNOME 菜单/活动区搜索某样东西时,它也会显示名称与搜索词相匹配的文件,以及已安装的应用。

Search in GNOME activities shows installed applications and matching files

这是个很方便的功能。如果你记得文件名,甚至是它的一部分,你可以很容易地搜索到它,只需按下 Super 键(Windows 键)并输入文件名就可以打开它。

但是,围绕这个搜索功能,有一些你可能不知道或从未关心过的小问题。

在这篇文章中,我将分享你如何控制 GNOME 搜索功能,从搜索选项中添加或隐藏文件夹,以及完全禁用它。

注意:这专门针对使用 GNOME 的发行版。请 确认你使用的是哪种桌面环境,确保是 GNOME。

文件搜索的默认位置

GNOME 的搜索功能使用了一个叫做 Tracker Miner FS 的工具。请不要被 “tracker” 和 “miner” 这样的术语吓到。它不是在监视你,也不是在你的系统上挖掘加密货币。它的基本功能是作为一个搜索引擎和数据库,为你提供即时搜索结果。

默认情况下,文件索引发生在元文件夹,如文档、音乐、图片和视频目录及其子目录。主页和下载文件夹中的文件也会被索引,但不包括其子目录中的文件。

Default locations for file search

如果你在你的主文件夹中创建了一些新的目录,这些文件将不会被索引。

然而,最近访问的文件也会被自动编入索引。如果你最近打开了一个文件,它将被添加到 “最近的文件” 中,并将出现在搜索结果中,而不管它在什么地方。

如果你还不知道的话,你可以在文件管理器中看到你最近访问的文件:

Accessing recent files in GNOME file manager

在搜索结果中添加一个文件夹的内容

假设你在你的主目录中为编码项目创建了一个文件夹。这些文件不会被索引,也不会出现在搜索结果中(除非你通过双击打开了一个文件,并且它被添加到最近的文件中)。

要在搜索结果中添加自定义文件夹中的文件,你可以将该文件夹添加到搜索位置。

通过在菜单/活动区搜索打开 “设置” 应用。

Search for settings application

从左侧边栏进入 “搜索” 选项,点击顶部的“搜索位置”选项。在弹出的窗口中,进入 “其他” 标签,点击 “+” 符号。它将打开文件浏览器,你可以添加你想要的文件夹。

Adding a custom folder content to search

如果你在刚刚添加的文件夹中搜索一个文件名进行测试,你现在应该在搜索结果中看到它。它应该是即时的,但如果不是,请尝试注销或重启系统。

从搜索结果中隐藏一个文件夹

如果你不希望某个特定文件夹的文件出现在搜索结果中,你可以隐藏它。

如果你不希望在搜索中出现图片、文档、视频等元文件夹的内容,你可以从搜索位置设置中禁用它。

Disable meta folders from the search

如果你只想让文档下的某个文件夹的内容不出现在搜索结果中,你只需要在该文件夹中创建一个名为 .nomedia 的新文件。你也可以将该文件命名为 .git.trackerignore.hg

Hide specific folder from search results by creating file named .nomedia or .hg or .git

如果你在鼠标右键中没有看到创建新文件的选项,你必须做一些调整来增加 在右键上下文菜单中创建新文件选项。还要注意的是,任何名称中以 . 开头的文件都会被隐藏起来,不能被正常查看。要 切换显示隐藏文件,按 Ctrl+H 键。

这种隐藏可能不会立即生效,因为该文件可能已经被索引了。你可能必须注销或重启才能看到效果。

如果你手动访问一个文件,它将被添加到最近的文件中,并且会出现在搜索结果中,尽管文件夹中的文件被忽略了。

你可以从 “设置 -> 隐私 -> 文件历史 & 垃圾箱” 删除最近的文件历史或完全禁用它(如果你想的话)。不过我认为没有必要,所以在这里你自己决定吧。

Clear or disable file access history in GNOME

禁用所有文件的搜索结果

如果你不希望任何文件出现在搜索结果中,你可以在搜索设置中完全禁用对文件的搜索。

Disable search results for all files

你应该通过点击顶部的搜索切换按钮完全禁用搜索功能,它可能会干扰 GNOME 桌面环境的正常功能。

关于它的更多细节可以在 [项目主页] 中找到。

总结

这里的 讨论的是文件搜索。GNOME 桌面也可以在日历、字符映射和其他一些程序中进行搜索。你可以禁用或启用可用的搜索选项,但我们这篇不针对这些。

我希望你觉得这个快速提示对 定制你的 GNOME 体验 有帮助。如果你知道其他一些你想让别人知道的技巧,请在评论中与我们分享。


via: https://itsfoss.com/control-gnome-file-search/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

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

林林总总的 Linux 发行版可以根据它们的特点、功能、预期用户群等分为不同的类别。在这篇文章中,我将列出一些最好的滚动发布的 Linux 发行版。

你知道什么是 滚动发布的发行版 吗?这些发行版不会等待 6 个月或更长时间才发布一个新的版本,提供给你更新的 Linux 内核、桌面环境和其他主要软件组件。它们会在这些组件发布后很快就进行更新。你不必将你的发行版从一个主要版本升级到下一个版本,因为你的发行版会定期得到升级。

现在你已经知道了,让我们来看看一些最好的滚动发布的 Linux 发行版。

你可以在桌面上使用的最佳滚动发行版

是的,这个列表主要是针对桌面用户。这里列出的一些发行版可能有服务器版本,但这不是这里的重点。

请注意,这并不是一个排名表。

1、openSUSE Tumbleweed

OpenSUSE Tumbleweed

老派的 openSUSE 多年来一直按部就班地顺着版本号发布他们的系统。但在几年前,他们决定改变他们的产品,创建了 openSUSE Leap 和 Tumbleweed

openSUSE Leap 采用的是版本式发布,每隔几年就会有一个新的版本,而 Tumbleweed 则是滚动式发布,新的软件在发布后不久就会出现在这个系统中。

openSUSE Tumbleweed 对于那些想留在红帽 RPM 阵营的人来说是一个很好的选择。openSUSE 有多样化的生态系统,它有一个巨大的软件库,Zypper 和 YaST 为你的软件包管理提供了很多选择。

2、Arch Linux

Arch Linux

毋庸置疑,Arch Linux 是最流行的滚动发布版本。它几乎就是滚动发布的同义词。

Arch Linux 在 Linux 用户中具有崇高地位的原因有很多。我认为这更多是与 安装 Arch Linux 后的成就感有关,因为即使是安装程序,它都很别人不一样。

Arch 在其软件库中正式提供了一大批软件。而 AUR 则通过社区的努力,几乎使所有其他的 Linux 软件都可以使用

如果你对 Linux 有一定的经验,想挑战自己的水平,这是一个不错的选择。

3、Manjaro Linux

Manjaro Linux

Manjaro 基本上是免除了所有麻烦的 Arch Linux。

它是基于 Arch Linux 的,所以它具有 Arch Linux 的大部分优点。你可以得到 Pacman 和 AUR 的滚动发布模式。同时,Manjaro 有图形化的安装程序、基于 GUI 的软件包管理器和其他图形化工具来改善你的桌面体验。

Manjaro 更容易安装,也更容易使用。对于那些想舒适地呆在 Arch 领域的人来说是个不错的选择。

注意: 还有 许多其他基于 Arch Linux 的优秀发行版,但我无法将其列入此列表中。如果你愿意,你可以试试 Garuda Linux、EndeavourOS 和其他许多基于 Arch 的发行版。

4、Solus Linux

Solus Linux

和 Manjaro 一样,Solus 也是一个 “谨慎” 的滚动发行版。与 Manjaro 不同的是,它不是基于 Arch 的。它是从头开始创建的,使用的是 eopkg 软件包管理器。Solus 因创造了现代而直观的 Budgie 桌面环境备受赞誉。

像其他滚动发布的发行版一样,一旦你安装了 Solus,你就不需要升级到下一个版本的发行版(也可以像 ISO 刷新一样进行全新安装,带有更新的软件包)。

万一有欠缺的软件包也可以用 Snap 应用程序来补足。

如果你想要一些不同的东西,但又不至于复杂到让你感到不舒服,那么 Solus 是一个不错的选择。

5、Debian Testing

Debian

你没有想到吧?Debian 以其对稳定性的关注而闻名,以至于其稳定的有时就像是陈旧,因为它提供的软件版本已经相当老旧。

但那是针对稳定分支的。Debian 有几个分支,其中一个叫做 Testing 分支。

看起来 Testing 是某种测试版、不稳定的版本,但这并不完全正确。Debian Testing 其实是下一个 Debian 稳定版本。实际的开发分支是 Debian Unstable(即 Sid)。Debian Testing 介于不稳定版和稳定版分支之间,它会在稳定版之前添加新的功能。

有些人在配置 Debian 时,在源列表中加入 testing。这使得他们的 Debian 系统永远停留在测试阶段。这是一种滚动发布的模式,Debian 用户可以不必离开舒适的 APT 和 deb 软件包管理系统。

6、Void Linux

Void Linux

这是一个不寻常的、不太出名的发行版。Void 也是从头开始创建的,也就是说,它不是基于 Arch、Red Hat 或 Debian。

它是滚动发布的,但不像 Arch 那样激进。它优先考虑的是稳定性。这意味着当新的版本发布时,你不需要升级版本,但你也不会在最新的桌面环境版本一发布就得到它。

与其他发行版不同的另一点是,它使用 runit 作为初始化系统。

总的来说,如果你是一个有经验的 Linux 用户,Void 是一个不错的选择。

7、Gentoo Linux

Gentoo Linux

另一个是你的同行们警告过的 专家级 Linux 发行版 之一。

Gentoo 不是每个人都能享用的茶或咖啡(无论你喜欢哪一种)。从安装到配置再到软件包管理都需要一定的专业知识和时间。

但是它有一个小众的专家用户群,他们会在编译一切需要的组件时废寝忘食。

如果你觉得其他发行版都不够有挑战性,Gentoo 可能是你的选择。

你对滚动发布的发行版有什么建议?

正如我之前提到的,我在这里特意将其他基于 Arch 的发行版排除在外,否则列表中就只有 Arch 的衍生产品了。

但你可以自由地投出你的推荐,即使它是基于 Arch 的。评论区都是你的。


via: https://itsfoss.com/best-rolling-release-distros/

作者:Abhishek Prakash 选题:lujun9972 译者:wxy 校对:wxy

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

编写你自己的简单程序来自动执行通常需要大量输入的任务的批处理文件,是一种极好的方法。

 title=

在 Linux 上,创建 shell 脚本 来自动执行重复的任务是很常见的。类似地,在开源版的旧式 DOS 操作系统 FreeDOS 上,你可以创建一个包含数个 FreeDOS 命令的 批处理文件 。然后,你就可以运行你的批处理文件来按顺序执行每个命令。

你可以使用一个 ASCII 文本编辑器来创建批处理文件,诸如 FeeDOS 的 Edit 应用程序。在你创建一个批处理文件后,你可以使用一个文件名称加上扩展名 .bat 来保存它。文件名称应该是唯一的。如果你使用 FreeDOS 的一个命令的名称作为你自己的文件名称,那么可能将会执行 FreeDOS 的命令,而不会是你的批处理文件。

实际上,所有的内部的和外部的 FreeDOS 命令都可以在一个批处理文件中使用。在你创建一个批处理文件时,你其实就是在编写一个程序。FreeDOS 批处理文件可能没有结构化编程语言的功能,但是对于耗时短暂却重复乏味的任务来说,它是非常方便的。

注释你的代码

对于任何程序员来说,学习的第一个好习惯都应该是:在一个程序中放置注释来解释该代码正在做什么。这是一件非常容易完成的事情,但是你需要仔细,不要傻傻地让操作系统来执行你的注释。避免出现这种情况的方法是在一个注释行的开头处放置 REM(“remark” 的缩写) 。

FreeDOS 忽略以 REM 开头的代码行。但是任何查看源文件代码(即你在你的批处理文件中所编写的文本)的人都可以读取你的注释并理解它在做什么。这也是一种临时性禁用一个命令而不需要删除它的一种方法。只需要打开你的批处理文件来进行编辑,在你想要禁用行的开头处放置 REM ,并保存它。在你想要重新启用这个命令时,只需要打开文件来进行编辑和移除 REM 。这种技巧有时被称为 “注释掉” 一个命令。

开始设置

在你开始编写你自己的批处理文件前,我建议在 FreeDOS 中创建一个临时目录。这将会为你提供一个处理批处理文件的安全空间,不会意外地删除、移动,或重命名重要的系统文件或目录。在 FreeDOS 上,你可以使用 MD 命令来 创建一个目录

C:\>MD TEMP
C:\>CD TEMP
C:\TEMP>

FreeDOS 的 ECHO 命令会控制当你运行一个批处理文件时在屏幕上显示的东西。例如,这里是一个简单是单行批处理文件:

ECHO Hello world

如果你创建这个文件并运行它,你将看到在屏幕上显示的句子。从命令行中完成这项操作的最快的方法是:使用 COPY 命令来从你的键盘中(CON)获取输入,并将其放置到文件 TEST1.BAT 之中。接下来,按下组合键 Ctrl+Z 来停止复制过程,按下你键盘上的 ReturnEnter 按键来返回一个提示。

在你的临时目录中尝试创建这个文件为 TEST1.BAT ,接下来运行它:

C:\TEMP>COPY CON TEST1.BAT
CON => TEST1.BAT
ECHO Hello world
^Z

C:\TEMP>TEST1
Hello world

当你想要显示一段文本时,这可能很有用。例如,在一个程序完成它的任务时,你可能会在你的屏幕上看到一条告诉你需要等待的消息,或者在一个网络环境中时,你可能会看到一条登录消息。

如果你想要显示一个空行怎么办?你可能会认为 ECHO 命令本身就可以达到目的,但是单独一个 ECHO 命令只会询问 FreeDOS 来响应 ECHO 是打开还是关闭:

C:\TEMP>ECHO
ECHO is on

获取一个空白行的方法是在 ECHO后紧接着使用一个 +符号:

C:\TEMP>ECHO+

C:\TEMP>

批处理文件变量

变量是一个存储你需要你的批处理文件临时记住的信息的位置。这是编程的一个重要的功能,因为你不能总是知道你的批处理文件需要使用什么样的数据。这里有一个用于演示的简单示例。

创建 TEST3.BAT

@MD BACKUPS
COPY %1 BACKUPS\%1

变量是使用百分比符号和随后的数字表示的,因此,这个批处理文件将在你的当前目录中创建一个 BACKUPS 子目录,然后将复制变量 %1BACKUPS 文件夹之中。这个变量是什么?当你运行批处理文件时,变量由你决定:

C:\TEMP>TEST3 TEMP1.BAT
TEST1.BAT => BACKUPS\TEST1.BAT

你的批处理文件已经复制 TEST1.BAT 到一个名称为 BACKUPS 的子目录,因为在你运行批处理文件时,你标识这个文件为一个参数。你的批处理文件将把 %1 替换为 TEST1.BAT

变量是按位置的。变量 %1 是你提供给命令的第一个参数,变量 %2 是第二个参数,以此类推。假设你创建一个批处理文件来列出一个目录的内容:

DIR %1

尝试运行它:

C:\TEMP>TEST4.BAT C:\HOME
ARTICLES
BIN
CHEATSHEETS
GAMES
DND

这像预期一样的工作。但是下面这个却失败了:

C:\TEMP>TEST4.BAT C:\HOME C:\DOCS
ARTICLES
BIN
CHEATSHEETS
GAMES
DND

如果你尝试它,你将得到第一个参数(C:\HOME)的列表,而得不到第二个参数(C:\DOCS)的列表。这是因为你的批处理文件仅查找一个变量(%1),此外,DIR 命令也仅能获取一个目录。

此外,当你运行一个批处理文件时,你也不需要为其具体指定扩展名 —— 除非你运气相当不好地为批处理文件选取了一个与 FreeDOS 外部命令或类似命令相同的名称。当 FreeDOS 执行命令时,它按下面的顺序执行:

  1. 内部命令
  2. 带有 *.COM 扩展名的外部命令
  3. 带有 *.EXE 扩展名的外部命令
  4. 批处理文件

多个参数

好的,选择重新编写 TEST4.BAT 文件来使一个命令可以获取两个参数,以便你可以看到这是如何工作的。首先,使用 EDIT 应用程序来创建一个简单的名称为 FILE1.TXT 的文本文件。在其中放置一段某种类型(例如,“Hello world”)的语句,并在你的 TEMP 工作目录中保存文件。

接下来,使用 EDIT 来更改你的 TEST4.BAT 文件:

COPY %1 %2
DIR

保存它,然后执行命令:

C:\TEMP\>TEST4 FILE1.TXT FILE2.TXT

在运行你的批处理文件时,你会看一个你的 TEMP 目录的目录列表。在列出的文件之中,你有 FILE1.TXTFILE2.TXT ,它们是由你的批处理文件所创建的。

嵌套批处理文件

批处理文件的另一个功能是能够 “嵌套” ,这意味着一个批处理文件可以在另外一个批处理文件中被调用和运行。为查看这是如何工作的,从一对简单的批处理文件开始:

第一个文件被称为 NBATCH1.BAT

@ECHO OFF
ECHO Hello
CALL NBATCH2.BAT 
ECHO world

第一行 (@ECHO OFF) 轻轻地告诉批处理文件在你运行它时仅显示命令 (而不是命令本身) 的输出。你可能会在前面的示例中注意到这里有很多关于批处理文件正在做什么的反馈;在这种情况下,你正在允许你的批处理文件仅显示结果。

第二个批处理被称为 NBATCH2.BAT :

echo from FreeDOS

使用 EDIT 来创建这两个文件,并在你的 TEMP 子目录中保存它们。运行 NBATCH1.BAT 来查看会发生什么:

C:\TEMP\>NBATCH1.BAT 
Hello
from FreeDOS
world

你的第二个批处理文件将在第一个批处理文件之中通过 CALL 命令来执行,它将提供在你 “Hello world” 信息中间的字符串 “from FreeDOS” 。

FreeDOS 脚本

编写你自己的简单程序来自动执行通常需要大量输入的任务的批处理文件,是一种极好的方法。你使用的 FreeDOS 越多, 你将越熟悉它的命令,在你熟知命令后,在一个批处理文件中列出它们仅是一件使你的 FreeDOS 系统让你生活轻松的事情。尝试一下!


via: https://opensource.com/article/21/3/batch-files-freedos

作者:Kevin O'Brien 选题:lujun9972 译者:[robsean]](https://github.com/robsean) 校对:wxy

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

大家好!不久前我学会了如何使用着色器制作有趣的闪亮旋转八面体:

我的着色器能力仍然非常基础,但事实证明制作这个有趣的旋转八面体比我想象中要容易得多(从其他人那里复制了很多代码片段!)。

我在做这件事时, 从一个非常有趣的叫做 符号距离函数教程:盒子和气球 的教程中学到了“符号距离函数”的重要思路。

在本文中,我将介绍我用来学习编写简单着色器的步骤,并努力让你们相信着色器并不难入门!

更高级着色器的示例

如果你还没有看过用着色器做的真正有趣的事情,这里有几个例子:

  1. 这个非常复杂的着色器就像一条河流的真实视频:https://www.shadertoy.com/view/Xl2XRW
  2. 一个更抽象(更短!)有趣的着色器,它有很多发光的圆圈:https://www.shadertoy.com/view/lstSzj

步骤一:我的第一个着色器

我知道你可以在 shadertoy 上制作着色器,所以我去了 https://www.shadertoy.com/new。它们提供了一个默认着色器,如下图所示:

代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // 规范像素坐标 (从 0 到 1)
    vec2 uv = fragCoord / iResolution.xy;

    // 随时间改变像素颜色
    vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));

    // 输出到屏幕
    fragColor = vec4(col, 1.0);
}

虽然还没有做什么令人兴奋的事情,但它已经教会了我着色器程序的基本结构!

思路:将一对坐标(和时间)映射到一个颜色

这里的思路是获得一对坐标作为输入(fragCoord),你需要输出一个 RGBA 向量作为此坐标的颜色。该函数也可以使用当前时间(iTime),图像从而可以随时间变化。

这种编程模型(将一对坐标和时间映射到其中)的巧妙之处在于,它非常容易并行化。我对 GPU 了解不多,但我的理解是,这种任务(一次执行 10000 个微不足道的可并行计算)正是 GPU 擅长的事情。

步骤二:使用 shadertoy-render 加快开发迭代

玩了一段时间的 shadertoy 之后,我厌倦了每次保存我的着色器时都必须在 shadertoy 网站上单击“重新编译”。

我找到了一个名为 shadertoy-render 命令行工具,它会在每次保存时实时查看文件并更新动画。现在我可以运行:

shadertoy-render.py circle.glsl

并更快地开发迭代!

步骤三:画一个圆圈

接下来我想 —— 我擅长数学!我可以用一些基本的三角学来画一个会弹跳的彩虹圈!

我知道圆的方程为(x^2 + y^2 = 任意正数!),所以我写了一些代码来实现它:

代码如下:(你也可以 在 shadertoy 上查看

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // 规范像素坐标 (从 0 到 1)
    vec2 uv = fragCoord / iResolution.xy;
    // 绘制一个中心位置依赖于时间的圆
    vec2 shifted = uv - vec2((sin(iGlobalTime) + 1) / 2, (1 + cos(iGlobalTime)) / 2);
    if (dot(shifted, shifted) < 0.03) {
        // 改变像素颜色
        vec3 col = 0.5 + 0.5 * cos(iGlobalTime + uv.xyx + vec3(0, 2, 4));
        fragColor = vec4(col, 1.0);
    } else {
        // 使圆之外的其他像素都是黑色
        fragColor = vec4(0,0, 0, 1.0);
    }
}

代码将坐标向量 fragCoord 与自身点积,这与计算 x^2 + y^2 相同。我还在这个圆圈的中心玩了一点花活 – 圆心为 vec2((sin(iGlobalTime) + 1)/ 2,(1 + cos(faster)) / 2,这意味着圆心也随着时间沿另一个圆移动。

着色器是一种学习数学的有趣方式!

我觉得有意思的(即使我们没有做任何超级高级的事情!)是这些着色器为我们提供了一种有趣的可视化方式学习数学 - 我用 sincos 来使某些东西沿着圆移动,如果你想更直观地了解三角函数的工作方式, 也许编写着色器会是一种有趣的方法!

我喜欢的是,可以获得有关数学代码的即时视觉反馈 - 如果你把一些东西乘以 2,图像里的东西会变得更大!或更小!或更快!或更慢!或更红!

但是我们如何做一些真正有趣的事情呢?

这个会弹跳的圆圈很好,但它与我见过的其他人使用着色器所做的非常奇特的事情相去甚远。那么下一步要做什么呢?

思路:不要使用 if 语句,而是使用符号距离函数!

在我上面的圆圈代码中,我基本上是这样写的:

if (dot(uv, uv) < 0.03) {
    // 圆里的代码
} else {
    // 圆外的代码
}

但问题(也是我感到卡住的原因)是不清楚如何将它推广到更复杂的形状!编写大量的 if 语句似乎不太好用。那人们要如何渲染这些 3d 形状呢?

所以! 符号距离函数 Signed distance function 是定义形状的另一种方式。不是使用硬编码的 if 语句,而是定义一个 函数,该函数告诉你,对于世界上的任何一个点,该点与你的形状有多远。比如,下面是球体的符号距离函数。

float sdSphere( vec3 p, float center )
{
  return length(p) - center;
}

符号距离函数非常棒,因为它们:

  • 易于定义!
  • 易于组合!如果你想要一个被切去一块的球体, 你可以用一些简单的数学来计算并集/交集/差集。
  • 易于旋转/拉伸/弯曲!

制作旋转陀螺的步骤

当我开始时,我不明白需要编写什么代码来制作一个闪亮的旋转东西。结果表明如下是基本步骤:

  1. 为想要的形状创建一个符号距离函数(在我的例子里是八面体)
  2. 光线追踪符号距离函数,以便可以在 2D 图片中显示它(或沿光线行进?我使用的教程称之为光线追踪,我还不明白光线追踪和光线行进之间的区别)
  3. 编写代码处理形状的表面纹理并使其发光

我不打算在本文中详细解释符号距离函数或光线追踪,因为我发现这个 关于符号距离函数的神奇教程 非常友好,老实说,它比我做的更好,它解释了如何执行上述 3 个步骤,并且代码有大量的注释,非常棒。

步骤四:复制教程代码并开始更改内容

我在这里使用了久负盛名的编程实践,即“复制代码并以混乱的方式更改内容,直到得到我想要的结果”。

最后一堆闪亮的旋转八面体着色器在这里:https://www.shadertoy.com/view/wdlcR4

动画出来的样子是这样的:

为了做到这一点,我基本上只是复制了关于符号距离函数的教程,该函数根据符号距离函数呈现形状,并且:

  • sdfBalloon 更改为 sdfOctahedron,并使八面体旋转而不是在我的符号距离函数中静止不动
  • 修改 doBalloonColor 着色功能,使其有光泽
  • 有很多八面体而不是一个

使八面体旋转!

下面是我用来使八面体旋转的代码!事实证明这真的很简单:首先从 这个页面 复制一个八面体符号距离函数,然后添加一个 rotate 使其根据时间旋转,然后它就可以旋转了!

vec2 sdfOctahedron( vec3 currentRayPosition, vec3 offset ){
    vec3 p = rotate((currentRayPosition), offset.xy, iTime * 3.0) - offset;
    float s = 0.1; // s 是啥?
    p = abs(p);
    float distance = (p.x + p.y + p.z - s) * 0.57735027;
    float id = 1.0;
    return vec2( distance,  id );
}

用一些噪音让它发光

我想做的另一件事是让我的形状看起来闪闪发光/有光泽。我使用了在 这个 GitHub gist 中找到的噪声函数使表面看起来有纹理。

以下是我如何使用噪声函数的代码。基本上,我只是随机地将参数更改为噪声函数(乘以 2?3?1800?随你!),直到得到喜欢的效果。

float x = noise(rotate(positionOfHit, vec2(0, 0), iGlobalTime * 3.0).xy * 1800.0);
float x2 = noise(lightDirection.xy * 400.0);
float y = min(max(x, 0.0), 1.0);
float y2 = min(max(x2, 0.0), 1.0);
vec3 balloonColor = vec3(y, y + y2, y + y2);

编写着色器很有趣!

上面就是全部的步骤了!让这个八面体旋转并闪闪发光使我很开心。如果你也想用着色器制作有趣的动画,希望本文能帮助你制作出很酷的东西!

通常对于不太了解的主题,我可能在文章中说了至少一件关于着色器的错误事情,请让我知道错误是什么!

再说一遍,如下是我用到的两个资源:

  1. “符号距离函数教程:盒子和气球”:https://www.shadertoy.com/view/Xl2XWt(修改和玩起来真的很有趣)
  2. 可以将大量符号距离函数复制并粘贴到你的代码中:http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm

via: https://jvns.ca/blog/2020/03/15/writing-shaders-with-signed-distance-functions/

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

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

使用本文中的这些 Ansible 剧本可以帮你获得更优的 Mycroft AI 体验。

 title=

Mycroft AI 是一款虚拟助手应用程序,可以响应语音请求并完成相应的任务,比如在互联网上搜索你需要的某些信息,或者下载你喜欢的博客等等。这是一款优秀的开源软件,不同于那些收集个人数据业务的公司的同款软件,Mycroft AI 注重于保护隐私以及提供平台灵活性。

Mycroft AI 使用 python 开发,可以安装于不同的硬件平台上。家喻户晓的树莓派便是一个非常热门的运行语音助手的硬件方案(不过不是唯一的方案)。方便的是,Mycroft 为树莓派提供了 Picroft 镜像,虽然目前 Picroft 还有一些限制,比如不支持 64 位系统,不过不能阻止它成为一种优秀的解决方案。

树莓派 4,我选择的目标平台

树莓派在 Mycroft 社区中非常受欢迎,因为其性价比高,在教育行业中有着巨大的优势,并且由于 Mycroft 提供的便捷功能以及树莓派本身易于访问的输入/输出(GPIO)引脚等,为树莓派提供了有趣的扩展可能(比如,提供 唤醒词 LED GPIO 能力)。

树莓派 4B 具有足够的 CPU 算力以及内存来平稳运行 Mycroft。我使用的是 8G 内存的树莓派4B,运行 Raspberry Pi OS Bullseye 64-bit 系统,你可以从 RaspberryPi.org 网站下载该系统镜像文件。

自动化这件事

构建你自己的 Mycroft AI 系统,必须要注意一些细节问题。根据我(一年以来)的初步经验,以下罗列了一些重要的技术细节点:

  • 音频输出(扬声器配置)
  • 音频输入(麦克风配置)
  • 麦克风质量(以购买的实际硬件为准)
  • 唤醒词响应(比如打招呼 “嘿,Mycroft”)
  • 响应延迟(比如提问 “天气怎么样”)

这些并不是 Mycroft AI 的问题(LCTT 译注:难道软件平台就没有处理延时问题?),它们只能是你在选择硬件和配置操作时必须牢记关心的事情。树莓派本身能够运行 Mycroft AI,但有一些配置需要额外的注意下:

  • CPU 调度器
  • SD 卡性能
  • PulseAudio 配置
  • 网络延迟

我做了大量的研究和实践来解决上面列出这些令人头疼的注意点,最终我实现了我的“终极”目标 —— 最流畅的体验!

Ansible 雪中送炭

我已经摸索出了最流畅的体验配置,但是如何确保在任何树莓派 4 板子上都能不遗漏每一个设置细节,然后达到重新部署这种流畅性体验的目标呢?

Ansible 能帮助你实现。Ansible 在设计上是幂等设计,这意味着它仅在需要时响应更改的请求。如果一切配置正确,Ansible 不会改变任何事情。这便是幂等设计的优美之处。

为了达到这一目的,我使用了两种 Ansible 场景角色工具:

  • 一个用于配置和调整树莓派
  • 一个用于安装和配置 Mycroft AI

Ansible prepi 角色

Ansible prepi role 应用了一些配置,以便让树莓派 4B 发挥更佳的性能以及为安装 Mycroft 做前提准备。

  • 更新 Raspberry Pi OS 至最新版本
  • 添加 Debian backports 仓库
  • 使用 next 分支更新固件,该分支支持 5.15 版本内核以及边缘固件
  • 使用测试版本更新 EEPROM,该版本支持边缘功能
  • 设置 initial_turbo 用来加速启动过程
  • 将树莓派超频至 2GHz
  • 在 RAMDisck 上挂载 /tmp
  • 优化 / 分区挂载选项,提升 SD 卡读/写性能
  • 管理 I2C、SPI、UART 接口
  • 设置 CPU 控制器至避免在空间内核函数之间发生上下文切换的模式,以便提升性能
  • 安装和配置 PulseAduio(非系统范围)
  • 新固件或者 EEPROM 安装后重启树莓派

Ansible mycroft 角色

Ansible mycroft role 基于脚本 dev_setup.sh 从 Github 仓库获取并安装和配置 Mycroft AI,该脚本是 Mycroft 核心团队提供。

  • 需要准备 Python3 环境
  • 系统集成环境
  • 额外的安装技能
  • 安装 Boto3、py\_mplayer、pyopenssl 库
  • 支持 IPC 的 RAMDisck
  • 支持文件配置
  • PulseAudio 优化
  • 安全的 Mycroft 消息总线 websocket

我利用 Ansible 剧本 来协调上面两个角色的使用。

个人配置需求

下面列举了一些个人配置的需求:

  • 能上网的树莓派 4B 板子(或者更新的板子)
  • Raspberry Pi OS 64-bit
  • Ansible 2.9(或者更新版本)
  • 可正常工作的 SSH

推荐使用 Etcher 来烧录 Raspberry Pi OS 镜像至 SD 卡,你也可以使用你选择的镜像烧录工具。

我将树莓派超频来提升性能,不过这可能对你的硬件是一种潜在危险。在使用我的 Ansible 剧本配置之前,请先仔细阅读。你需要为你的每个配置选择负责。你将决定使用哪个固件、哪个 EEPROM。超频的话需要记得提供相应的冷却系统。

执行 Ansible 剧本

第一步,使用命令从 Github 获取 Ansible 剧本:

$ git clone https://github.com/smartgic/ansible-playbooks-mycroft.git

源码中,requirements.yml 文件中提供了该剧本的依赖角色列表,必须从 Ansible Galaxy 中检索这些依赖。

$ cd ansible-playbooks-mycroft
$ ansible-galaxy install -r requirements.yml
Starting galaxy role install process
- downloading role 'mycroft', owned by smartgic
- downloading role from https://github.com/smartgic/ansible-role-mycroft/archive/main.tar.gz
- extracting smartgic.mycroft to /home/goldyfruit/.ansible/roles/smartgic.mycroft
- smartgic.mycroft (main) was installed successfully
- downloading role 'prepi', owned by smartgic
- downloading role from https://github.com/smartgic/ansible-role-prepi/archive/main.tar.gz
- extracting smartgic.prepi to /home/goldyfruit/.ansible/roles/smartgic.prepi
- smartgic.prepi (main) was installed successfully

第二步,编辑仓库中的 Ansible 清单,设置需要管理的主机。

[rpi]
rpi4b01 ansible_host=192.168.1.97 ansible_user=pi

[rpi] 代表组,无需更改。该组有一个主机 rpi4b01,其 IP 地址为 192.168.1.97, 并创建 pi 作为 Linux(Raspberry Pi OS)上的默认用户。

现在比较棘手的部分到了:你希望每个选项怎么配置?这取决于你自己,下面是我的首选配置,供你参考:

# file: install-custom.yml
- hosts: rpi
  gather_facts: yes
  become: yes

  pre_tasks:
    - name: Install Python 3.x Ansible requirement
      raw: apt-get install -y python3
      changed_when: no
      tags:
        - always

  vars:
    # PREPI
    prepi_pi_user: pi
    prepi_hostname: mylovelypi
    prepi_firmware_update: yes
    prepi_overclock: yes
    prepi_force_turbo: yes
    prepi_cpu_freq: 2000
    prepi_pulseaudio_daemon: yes

    # MYCROFT
    mycroft_branch: dev
    mycroft_user: "{{ prepi_pi_user }}"
    mycroft_skills_update_interval: 2.0
    mycroft_recording_timeout_with_silence: 3.0
    mycroft_enclosure_name: picroft
    mycroft_extra_skills:
      - https://github.com/smartgic/mycroft-finished-booting-skill.git

  tasks:
    - import_role:
        name: smartgic.prepi

    - import_role:
        name: smartgic.mycroft

上面的配置内容需要保存在文件里(比如,install-custom.yml)。

现在关键步骤:运行你新创建的剧本。

$ ansible-playbook -i inventory install-custom.yml -k

-k 选项只有在不需要 SSH 密钥的时候才使用。在命令执行期间,树莓派可能会重启若干次。Ansible 剧本会自动处理这个问题,不必担心。

Ansible 配置完成后,你可以看到一条祝贺消息,提示你下一步需要做什么。

 title=

Ansible 让定制 Mycroft 变得更容易

这些 Ansible 剧本是我开始使用 Mycroft AI 后学到的经验教训。它们帮助我在任何一个地方都能构建、重构、定制、拷贝我的安装,并保持一致,这让我很省心!

读完此文,你有何意见、问题或疑虑?欢迎在 Twitter上 @goldyfruit上和我交流,或者访问 Mycroft 频道 搜寻答案。


via: https://opensource.com/article/21/12/mycroft-raspberry-pi-ansible

作者:Gaëtan Trellu 选题:lujun9972 译者:jrglinux 校对:wxy

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