分类 技术 下的文章

使用 ncurses 在 Linux 屏幕上的特定位置放置文本,可以带来更友好的用户界面体验。

 title=

大多数的 Linux 实用程序仅仅只在屏幕的底部滚动文本。如果你想在屏幕中放置你的文本,例如一个游戏或者一个数据展示,你可以试试 ncurses。

curses 是一个旧的 Unix 库,它可以在文本终端界面控制光标。curses 的名称就来自于术语 “ 光标控制 cursor control ”。多年以后,其他人编写了新的 curses 版本用来添加新的功能,新版本被叫做 “new curses” 或者 “ncurses”。你可以在每个流行的 Linux 发行版中找到 ncurses。尽管默认情况下可能未安装开发库、头文件和文档。例如,在 Fedora 上,你需要使用以下命令安装 ncurses-devel 包:

$ sudo dnf install ncurses-devel

在程序中使用 ncurses

要在屏幕上直接寻址,你首先需要初始化 ncurses 库。大部分程序会通过以下三行来做到这一点:

  • initscr():初始化窗口对象和 ncurses 代码,返回代表整个屏幕的窗口对象
  • cbreak():禁用缓冲并使键入的输入立即可用
  • noecho():关闭回显,因此用户输入不会显示在屏幕上

这些函数定义在 curses.h 头文件中,你需要在你的程序中通过以下方式将其包含进来:

#include <curses.h>

初始化终端后,你可以自由使用任何 ncurses 函数,我们将在示例程序中探讨其中的一些函数。

当你使用完 ncurses 并想返回到常规终端模式下时,使用 endwin() 重置一切。此命令可以重置任何屏幕颜色,将光标移动到屏幕的左下角,并使光标可见。通常在退出程序之前执行此操作。

在屏幕上寻址

关于 ncurses 首先需要知道的是屏幕的坐标分为行和列,左上角的是 0,0 点。ncurses 定义了两个全局变量来帮助你识别屏幕:LINES 是屏幕的行数,COLS 是屏幕的列数。屏幕右下角的位置是 LINES-1,COLS-1

例如,如果你想要移动光标到第 10 行和第 30 列,你可以使用 move() 函数,移动到此坐标:

move(10, 30);

之后显示的任何文本都将从屏幕的该位置开始。要显示单个字符,请对单个字符使用 addch(c) 函数。要显示字符串,将对字符串使用 addstr(s) 函数。对于类似于 printf 的格式化输出,请使用带有常用选项的 printw(fmt, ...)

移动到屏幕指定位置和显示文本是一件很常见的事情,ncurses 提供了同时执行这两项操作的快捷方式。mvaddch(row, col, c) 函数将在屏幕第 row 行,第 col 列的位置显示一个字符。而 mvaddstr(row, col, s) 函数将在屏幕第 row 行,第 col 列的位置显示一个字符串。举个更直接的例子,在程序中使用 mvaddstr(10, 30, "Welcome to ncurses"); 函数将从屏幕的第 10 行和第 30 列开始显示文本 Welcome to ncurses。使用 mvaddch(0, 0, '+') 函数将在屏幕的左上角第 0 行和第 0 列处显示一个加号(+)。

在终端屏幕上绘制文本会对某些系统产生性能影响,尤其是在较旧的硬件终端上。因此 ncurses 允许你“堆叠”一堆文本以显示在屏幕上,然后使用 refresh() 函数使所有这些更改对用户可见。

让我们来看一个将以上所有内容整合在一起的简单示例:

#include <curses.h>

int
main()
{
  initscr();
  cbreak();
  noecho();

  mvaddch(0, 0, '+');
  mvaddch(LINES - 1, 0, '-');
  mvaddstr(10, 30, "press any key to quit");
  refresh();

  getch();

  endwin();
}

程序的开始初始化了一个终端窗口,然后在屏幕的左上角打印了一个加号,在左下角打印了一个减号,在第 10 行和第 30 列打印了 press any key to quit 文本。程序通过使用 getch() 函数接收了键盘输入的单个字符,接着,使用 endwin() 函数在程序完全退出前重置了终端。

getch() 是一个很有用的函数,你可以使用它来做很多事情。我经常使用它在我退出程序前用来暂停。与大多数 ncurses 函数一样,还有一个名为 mvgetch(row, col)getch() 版本,用于在等待字符输入之前移动到屏幕位置的第 row 行,第 col 列。

使用 ncurses 编译

如果你尝试以通常的方式编译该示例程序,例如 gcc pause.c,你可能会从链接器中获得大量错误列表。那是因为 GNU C 编译器不会自动链接 ncurses 库。相反,你需要使用 -l ncurses 命令行选项加载它以进行链接。

$ gcc -o pause pause.c -lncurses

运行新程序将打印一条简单的 press any key to quit消息,该消息差不多位于屏幕中央:

centered message in a program window

图 1:程序中居中的 “press any key to quit” 消息。

使用 ncurses 构建更好的程序

探索 ncurses 库函数以了解在屏幕上显示文本的其它方法。你可以在 ncurses 的手册页中找到所有 ncurses 函数的列表。这给出了 ncurses 的一般概述,并提供了不同 ncurses 函数的类似表格的列表,并参考了包含完整详细信息的手册页。例如,在 curs_printw(3X) 手册页中描述了 printw,可以通过以下方式查看:

$ man 3x curs_printw

更简单点:

$ man curs_printw

使用 ncurses,你可以创建更多有趣的程序。通过在屏幕上的特定位置打印文本,你可以创建在终端中运行的游戏和高级实用程序。


via: https://opensource.com/article/21/8/ncurses-linux

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

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

youtube-dl 是一个多功能的命令行工具,用于从 YouTube 和许多其他网站下载视频。我用它来做我自己的 YouTube 视频的备份。

默认情况下,你会 使用 youtube-dl 下载视频。用 youtube-dl 只提取音频怎么样? 其实很简单。让我告诉你步骤。

注意

从网站下载视频可能违反他们的政策。这取决于你是否选择下载视频或音频。

使用 youtube-dl 只下载音频

请确保你已经在你的 Linux 发行版上安装了 youtube-dl

sudo snap install youtube-dl

如果你只想从 YouTube 视频中下载音频,你可以使用 youtube-dl-x 选项。这个提取音频的选项将视频文件转换为纯音频文件。

youtube-dl -x video_URL

该文件被保存在你运行 youtube-dl 命令的同一目录下。

这是我下载 Zorin OS 16 评论视频的画外音的示例:

youtube-dl -x https://www.youtube.com/watch?v=m_PmLG7HqbQ
[youtube] m_PmLG7HqbQ: Downloading webpage
[download] Destination: Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a
[download] 100% of 4.26MiB in 00:03
[ffmpeg] Correcting container in "Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a"
[ffmpeg] Post-process file Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a exists, skipping

你注意到音频格式了吗?它是 .m4a 格式。你可以把音频格式指定为你所选择的格式。

比如你想提取 MP3 格式的音频。你可以像这样使用它:

youtube-dl -x --audio-format mp3 video_URL

下面是我之前展示的同一个例子。你可以看到它 使用 ffmpeg 转换 m4a 文件为 mp3:

youtube-dl -x --audio-format mp3 https://www.youtube.com/watch?v=m_PmLG7HqbQ
[youtube] m_PmLG7HqbQ: Downloading webpage
[download] Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a has already been downloaded
[download] 100% of 4.26MiB
[ffmpeg] Correcting container in "Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a"
[ffmpeg] Destination: Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.mp3
Deleting original file Zorin OS 16 Review - It's a Visual Masterpiece-m_PmLG7HqbQ.m4a (pass -k to keep)

以 MP3 格式下载整个 YouTube 播放列表

是的,你完全可以这样做。最主要的是要在这里得到播放列表的 URL。它通常是以下格式:

https://www.youtube.com/playlist?list=XXXXXXXXXXXXXXXXXXX

要获得一个播放列表的 URL,当播放列表显示在右边栏时,点击其名称。

Click on the playlist title

它将带你到播放列表页面,你可以在这里复制 URL。

Grab the playlist URL

现在你有了播放列表的 URL,你可以用它来下载 MP3 格式的音频文件,方法如下:

youtube-dl --extract-audio --audio-format mp3 -o "%(title)s.%(ext)s" playlist_URL

那个看起来很可怕的 -o "%(title)s.%(ext)s" 指定了输出文件(选项 -o),并指示它使用视频的标题和扩展名(本例为 mp3)来命名音频文件。

我希望你觉得这个技巧对你有帮助。享受音频文件吧。


via: https://itsfoss.com/youtube-dl-audio-only/

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

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

通过 ftrace 来了解 Linux 内核内部工作方式是一个好方法。

 title=

操作系统的内核是最难以理解的软件之一。自从你的系统启动后,它会一直在后台运行。尽管每个用户都不与内核直接交互,但他们在内核的帮助下完成自己的计算任务。与内核的交互发生在调用系统调用或者用户日常使用的各种库或应用间接调用了系统调用。

在之前的文章里我介绍了如何使用 strace 来追踪系统调用。然而,使用 strace 时你的视野是有限的。它允许你查看特定参数的系统调用。并在工作完成后,看到其返回值或状态,以表明是成功还是失败。但是你无法知道内核在这段时间内发生了什么。除了系统调用外,还有很多其他活动内核中发生,而你却视而不见。

ftrace 介绍

本文的旨在通过使用一个名为 ftrace 的机制来阐明追踪内核函数的一些情况。它使得任何 Linux 用户可以轻松地追踪内核,并且了解更多关于 Linux 内核内部如何工作。

ftrace 默认产生的输出往往是巨大的,因为内核总是忙碌的。为了节省空间,很多情况下我会通过截断来给出尽量小的输出。

我使用 Fedora 来演示下面的例子,但是它们应该在其他最新的 Linux 发行版上同样可以运行。

启用 ftrace

ftrace 现在已经是内核中的一部分了,你不再需要事先安装它了。也就是说,如果你在使用最近的 Linux 系统,那么 ftrace 是已经启用了的。为了验证 ftrace 是否可用,运行 mount 命令并查找 tracefs。如果你看到类似下面的输出,表示 ftrace 已经启用,你可以轻松地尝试本文中下面的例子。下面有些命令需要在 root 用户下使用(用 sudo 执行是不够的)。

# mount | grep tracefs
none on /sys/kernel/tracing type tracefs (rw,relatime,seclabel)

要想使用 ftrace,你首先需要进入上面 mount 命令中找到的特定目录中,在那个目录下运行文章中的其他命令。

# cd /sys/kernel/tracing

一般的工作流程

首先,你需要理解捕捉踪迹和获取输出的一般流程。如果你直接运行 ftrace,不会运行任何特定的 ftrace 命令。相反的,基本操作是通过标准 Linux 命令来写入或读取一些文件。

一般的步骤如下:

  1. 通过写入一些特定文件来启用/结束追踪
  2. 通过写入一些特定文件来设置/取消追踪时的过滤规则
  3. 从文件中读取基于第 1 和 2 步的追踪输出
  4. 从文件中清除早期输出或缓冲区
  5. 缩小到你的特定用例(你要追踪的内核函数),重复 1、2、3、4 步

可用的追踪器类型

有多种不同的追踪器可供使用。之前提到,在运行任何命令前,你需要进入一个特定的目录下,因为需要的文件在这些目录下。我在我的例子中使用了相对路径(而不是绝对路径)。

你可以查看 available_tracers 文件内容来查看所有可用的追踪器类型。你可以看下面列出了几个。不需要担心这些:

$ pwd
/sys/kernel/tracing

$ sudo cat available_tracers
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop

在所有输出的追踪器中,我会聚焦于下面三个特殊的:启用追踪的 functionfunction_graph,以及停止追踪的 nop

确认当前的追踪器

通常情况默认的追踪器设定为 nop。即在特殊文件中 current_tracer 中的 “无操作”,这意味着追踪目前是关闭的:

$ pwd
/sys/kernel/tracing

$ sudo cat current_tracer
nop

查看追踪输出

在启用任何追踪功能之前,请你看一下保存追踪输出的文件。你可以用 cat 命令查看名为 trace 的文件的内容:

# cat trace

# tracer: nop
#
# entries-in-buffer/entries-written: 0/0   #P:8
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |

启用 function 追踪器

你可以通过向 current_tracer 文件写入 function 来启用第一个追踪器 function(文件原本内容为 nop,意味着追踪是关闭的)。把这个操作看成是启用追踪的一种方式:

$ pwd
/sys/kernel/tracing

$ sudo cat current_tracer
nop
$ echo function > current_tracer
$
$ cat current_tracer
function

查看 function 追踪器的更新追踪输出

现在你已启用追踪,是时候查看输出了。如果你查看 trace 文件内容,你将会看到许多被连续写入的内容。我通过管道只展示了文件内容的前 20 行。根据左边输出的标题,你可以看到在某个 CPU 上运行的任务和进程 ID。根据右边输出的内容,你可以看到具体的内核函数和其父函数。中间显示了时间戳信息:

# sudo cat trace | head -20

# tracer: function
#
# entries-in-buffer/entries-written: 409936/4276216   #P:8
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |
          <idle>-0       [000] d...  2088.841739: tsc_verify_tsc_adjust <-arch_cpu_idle_enter
          <idle>-0       [000] d...  2088.841739: local_touch_nmi <-do_idle
          <idle>-0       [000] d...  2088.841740: rcu_nocb_flush_deferred_wakeup <-do_idle
          <idle>-0       [000] d...  2088.841740: tick_check_broadcast_expired <-do_idle
          <idle>-0       [000] d...  2088.841740: cpuidle_get_cpu_driver <-do_idle
          <idle>-0       [000] d...  2088.841740: cpuidle_not_available <-do_idle
          <idle>-0       [000] d...  2088.841741: cpuidle_select <-do_idle
          <idle>-0       [000] d...  2088.841741: menu_select <-do_idle
          <idle>-0       [000] d...  2088.841741: cpuidle_governor_latency_req <-menu_select

请记住当追踪打开后,这意味着追踪结果会被一直连续写入直至你关闭追踪。

关闭追踪

关闭追踪是简单的。你只需要在 current_tracer 文件中用 nop 替换 function 追踪器即可:

$ sudo cat current_tracer
function

$ sudo echo nop > current_tracer

$ sudo cat current_tracer
nop

启用 function\_graph 追踪器

现在尝试第二个名为 function_graph 的追踪器。你可以使用和上面相同的步骤:在 current_tracer 文件中写入 function_graph

$ sudo echo function_graph > current_tracer

$ sudo cat current_tracer
function_graph

function\_tracer 追踪器的追踪输出

注意到目前 trace 文件的输出格式已经发生变化。现在,你可以看到 CPU ID 和内核函数的执行时长。接下来,一个花括号表示一个函数的开始,以及它内部调用了哪些其他函数:

# cat trace | head -20

# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 6)               |              n_tty_write() {
 6)               |                down_read() {
 6)               |                  __cond_resched() {
 6)   0.341 us    |                    rcu_all_qs();
 6)   1.057 us    |                  }
 6)   1.807 us    |                }
 6)   0.402 us    |                process_echoes();
 6)               |                add_wait_queue() {
 6)   0.391 us    |                  _raw_spin_lock_irqsave();
 6)   0.359 us    |                  _raw_spin_unlock_irqrestore();
 6)   1.757 us    |                }
 6)   0.350 us    |                tty_hung_up_p();
 6)               |                mutex_lock() {
 6)               |                  __cond_resched() {
 6)   0.404 us    |                    rcu_all_qs();
 6)   1.067 us    |                  }

启用追踪的设置来增加追踪的深度

你可以使用下面的步骤来调整追踪器以看到更深层次的函数调用。完成之后,你可以查看 trace 文件的内容并发现输出变得更加详细了。为了文章的可读性,这个例子的输出被省略了:

# cat max_graph_depth
0

# echo 1 > max_graph_depth ## or:
# echo 2 > max_graph_depth

# sudo cat trace

查找要追踪的函数

上面的步骤足以让你开始追踪。但是它产生的输出内容是巨大的,当你想试图找到自己感兴趣的内容时,往往会很困难。通常你更希望能够只追踪特定的函数,而忽略其他函数。但如果你不知道它们确切的名称,你怎么知道要追踪哪些进程?有一个文件可以帮助你解决这个问题 —— available_filter_functions 文件提供了一个可供追踪的函数列表:

$ sudo wc -l available_filter_functions  
63165 available_filter_functions

查找一般的内核函数

现在试着搜索一个你所知道的简单内核函数。用户空间由 malloc 函数用来分配内存,而内核由 kmalloc 函数,它提供类似的功能。下面是所有与 kmalloc 相关的函数:

$ sudo grep kmalloc available_filter_functions
debug_kmalloc
mempool_kmalloc
kmalloc_slab
kmalloc_order
kmalloc_order_trace
kmalloc_fix_flags
kmalloc_large_node
__kmalloc
__kmalloc_track_caller
__kmalloc_node
__kmalloc_node_track_caller
[...]

查找内核模块或者驱动相关函数

available_filter_functions 文件的输出中,你可以看到一些以括号内文字结尾的行,例如下面的例子中的 [kvm_intel]。这些函数与当前加载的内核模块 kvm_intel 有关。你可以运行 lsmod 命令来验证:

$ sudo grep kvm available_filter_functions | tail
__pi_post_block [kvm_intel]
vmx_vcpu_pi_load [kvm_intel]
vmx_vcpu_pi_put [kvm_intel]
pi_pre_block [kvm_intel]
pi_post_block [kvm_intel]
pi_wakeup_handler [kvm_intel]
pi_has_pending_interrupt [kvm_intel]
pi_update_irte [kvm_intel]
vmx_dump_dtsel [kvm_intel]
vmx_dump_sel [kvm_intel]

$ lsmod  | grep -i kvm
kvm_intel             335872  0
kvm                   987136  1 kvm_intel
irqbypass              16384  1 kvm

仅追踪特定的函数

为了实现对特定函数或模式的追踪,你可以利用 set_ftrace_filter 文件来指定你要追踪上述输出中的哪些函数。这个文件也接受 * 模式,它可以扩展到包括具有给定模式的其他函数。作为一个例子,我在我的机器上使用 ext4 文件系统。我可以用下面的命令指定 ext4 的特定内核函数来追踪:

# mount | grep home
/dev/mapper/fedora-home on /home type ext4 (rw,relatime,seclabel)

# pwd
/sys/kernel/tracing

# cat set_ftrace_filter

#### all functions enabled ####
$
$ echo ext4_* > set_ftrace_filter
$
$ cat set_ftrace_filter
ext4_has_free_clusters
ext4_validate_block_bitmap
ext4_get_group_number
ext4_get_group_no_and_offset
ext4_get_group_desc
[...]

现在当你可以看到追踪输出时,你只能看到与内核函数有关的 ext4 函数,而你之前已经为其设置了一个过滤器。所有其他的输出都被忽略了:

# cat trace |head -20

## tracer: function
#
# entries-in-buffer/entries-written: 3871/3871   #P:8
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |
           cupsd-1066    [004] ....  3308.989545: ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....  3308.989547: ext4_getattr <-ext4_file_getattr
           cupsd-1066    [004] ....  3308.989552: ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....  3308.989553: ext4_getattr <-ext4_file_getattr
           cupsd-1066    [004] ....  3308.990097: ext4_file_open <-do_dentry_open
           cupsd-1066    [004] ....  3308.990111: ext4_file_getattr <-vfs_fstat
           cupsd-1066    [004] ....  3308.990111: ext4_getattr <-ext4_file_getattr
           cupsd-1066    [004] ....  3308.990122: ext4_llseek <-ksys_lseek
           cupsd-1066    [004] ....  3308.990130: ext4_file_read_iter <-new_sync_read

排除要被追踪的函数

你并不总是知道你想追踪什么,但是,你肯定知道你不想追踪什么。因此,有一个 set_ftrace_notrace —— 请注意其中的 “no”。你可以在这个文件中写下你想要的模式,并启用追踪。这样除了所提到的模式外,任何其他东西都会被追踪到。这通常有助于删除那些使我们的输出变得混乱的普通功能:

$ sudo cat set_ftrace_notrace
#### no functions disabled ####

具有目标性的追踪

到目前为止,你一直在追踪内核中发生的一切。但是,它无法帮助你追踪与某个特定命令有关的事件。为了达到这个目的,你可以按需打开和关闭跟踪,并且在它们之间,运行我们选择的命令,这样你就不会在跟踪输出中得到额外的输出。你可以通过向 tracing_on 写入 1 来启用跟踪,写 0 来关闭跟踪。

# cat tracing_on
0

# echo 1 > tracing_on

# cat tracing_on
1

### Run some specific command that we wish to trace here ###

# echo 0 > tracing_on

# cat tracing_on
0

追踪特定的 PID

如果你想追踪与正在运行的特定进程有关的活动,你可以将该 PID 写入一个名为 set_ftrace_pid 的文件,然后启用追踪。这样一来,追踪就只限于这个 PID,这在某些情况下是非常有帮助的。

$ sudo echo $PID > set_ftrace_pid

总结

ftrace 是一个了解 Linux 内核内部工作的很好方式。通过一些练习,你可以学会对 ftrace 进行调整以缩小搜索范围。要想更详细地了解 ftrace 和它的高级用法,请看 ftrace 的核心作者 Steven Rostedt 写的这些优秀文章。


via: https://opensource.com/article/21/7/linux-kernel-ftrace

作者:Gaurav Kamathe 选题:lujun9972 译者:萌新阿岩 校对:wxy

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

一个精心准备的在安装 elementary OS 6 “Odin” 后要做的事情的列表。

在经过两年多的开发后 elementary OS 6 “Odin” 于不久前发布,此次版本更新在核心模块、 Pantheon 桌面、原生应用方面带来了一大批新特性。elementary OS 6 “Odin” 是基于 Ubuntu 20.04 LTS 的。

如果你完成了安装,你可能想要尝试通过一些特定的设置来使你的系统更加的个性化。这里描述的选项是通用的,在某些情况下可能对你没有用,但是我们觉得有必要列出一些基本的东西,让你有合适的方式来探索这个漂亮的 elementary OS。

安装完 elementary OS 6 “Odin” 后要做的事情

准备步骤:

首先确保你已经连上了互联网,你可以在顶部的通知区域查看可用的网络列表

1、更改主机名

这可能不是你想做的第一件事。但是我不知道为什么在安装过程中没有给出更改主机名的选项。例如,见下图的终端提示, 这个主机名是 elementary OS 的默认硬件配置。在我看来这一点都不好。

主机名修改之前

打开终端并运行下列命令以更改主机名:

hostnamectl set-hostname your-new-hostname

示例:

修改主机名

主机名修改之后

2、升级你的系统

在安装任何 Linux 发行版后,你应该做的第一件事就是确保系统处于最新的软件包和安全更新状态。

你可以通过打开应用中心来检查或者安装更新。

或者打开终端运行下列命令:

sudo apt update
sudo apt upgrade

3、安装 Pantheon Tweaks

Pantheon Tweaks 是 elementary OS 的必备应用。它提供了一些无法通过系统原生设置程序修改的额外的设置和配置选项,请打开终端并运行以下命令以安装 Pantheon Tweaks。注意:先前版本的 Tweak 工具叫做 elementary Tweaks,从 Odin 版本开始更名为 Pantheon Tweaks。

sudo apt install software-properties-common
sudo add-apt-repository -y ppa:philip.scott/pantheon-tweaks
sudo apt install -y pantheon-tweaks

安装后打开系统设置,你可以在那里找到 “ 调整 Tweaks ” 选项。

这里 提供了更详细的安装指南(如果你需要了解更多信息)。

4、配置 Dock

Dock 是整个桌面的中心。老实说,Dock 中默认包含的应用并不常用,因此你可以通过以下步骤配置 Dock 中的项目。

  • 移除:右键单击并取消 “ 在 Dock 中驻留 Keep in Dock ” 选项。
  • 添加新的项目:单击顶部的应用程序。然后右键单击你想要放在 Dock 的应用图标。选择 “ 添加到 Dock Add to Dock ”。

在我看来,你应该至少把文件管理、截图工具、Firefox 、计算器,以及其他的一些应用添加到 Dock。然后移除 Dock 上那些你不需要的应用。

5、更改外观

elementary OS 6 Odin 改进了桌面的整体外观,为整个桌面和应用程序提供了自带的强调色和原生的夜间模式,同时,系统自带了许多漂亮的壁纸。你可以通过 “应用 > 系统设置 > 桌面” 来定制壁纸、外观、面板和多任务视图。

elementary OS 6 Odin 桌面设置界面

按照你希望的样子来配置你系统的外观。

你也可以基于日出和日落的时间来设置夜间模式。

6、安装其他的应用

自带的应用中心非常适合这个系统,我发现它是 Linux 桌面最好的应用商店之一。然而,有时候需要安装没有预装的必要应用(大多数是知名的应用)。下面是个新系统推荐安装的软件列表。(说真的,为什么 LibreOffice 没有预装?)

  • firefox
  • gimp
  • gedit
  • inkscape
  • obs-studio
  • libreoffice

7、一些针对笔记本电脑的省电贴士

有许多方法可以配置你的 elementary OS(或者一般的 Linux 桌面),以达到延长电池寿命的目的。记住,电池寿命取决于你的笔记本硬件,以及电池和笔记本的使用年限。所以,遵循下面的一些建议,最大限度的利用你的笔记本电池。

  • 安装 tlptlp 是一个简单易用的命令行程序,用来帮你在 Linux 上延长电池寿命。你只需要安装它,默认情况下,它会处理好其他的设置。安装命令:
sudo add-apt-repository ppa:linrunner/tlp
sudo apt update
sudo apt-get install tlp
sudo tlp start
  • 关闭蓝牙,默认情况下,蓝牙是开启状态。在需要的时候再启动它。
  • 通过下面的命令安装 thermald。这个实用程序(实际是个守护进程)控制着你的 CPU 的 P-States 和 T-States 的温度以及 CPU 发热。
sudo apt install thermald
  • 根据你的需要将亮度调到最小。

8、安装磁盘实用程序

在很多情况下,你发现你需要格式化 USB 或者向 USB 中写入一些东西。默认情况下,系统没有安装任何相关的应用。你可以安装以下这些易用的应用。

  • gnome-disk-utility
  • gparted

9、启用最大化和最小化选项

许多用户喜欢在窗口标题栏左边或者右边使用最大化、最小化的按钮,elementary OS 默认只提供关闭和恢复两个选项。这没什么问题,因为这就是它的设计理念。然而你可以通过使用 Pantheon Tweaks 来开启最大化和最小化按钮,具体的方式是:“调整 > 外观 > 窗口控制”。

在 elementary OS 中启动最大化和最小化设置

10、在 Odin 中学习新的多点触控手势

如果你是笔记本用户,并且使用 elementary OS “Odin”,那么你一定要看看这些超酷的新触控手势。三根手指向上滑动,就会平滑的打开多任务视图,展示打开的应用程序和工作空间。用三根手指向左或向右滑动,就能在动态工作空间之间流畅的切换,使任务之间的切换更快。

用两根手指也可以在原生应用中实现类似的功能。

结束语

我希望这篇安装 elementary OS 6 “Odin” 后要做的 10 件事能帮助到你,让你可以上手使用 elementary OS 6 “Odin”,尽管这些事情完全是用户的偏好,因此这些事情有可能适合你也有可能不适用于你,但总的来说,这些都是一般用户喜欢的预期调整。

如果你觉得有更多的东西应该添加到列表中,请在下面的评论中告诉我。


via: https://www.debugpoint.com/2021/08/10-things-to-do-after-install-elementary-os-6/

作者:Arindam 选题:lujun9972 译者:anine09 校对:wxy

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

开源爱好者们对他们所喜爱的 Linux 内核模块进行了评价。

 title=

Linux 内核今年就要满 30 岁了! 如果你像我们一样对此特别重视,那么让我们本周用几个特别的文章来庆祝 Linux。

今天,我们先来看看来自社区对“你不能没有哪个 Linux 内核模块?为什么?”的回答,让我们听听这 10 位爱好者是怎么说的。

1

我猜一些内核开发者听到我的回答后会尖叫着跑开。不过,我还是在这里列出了两个最具争议性的模块:

  • 第一个是 NVIDIA,因为我的工作笔记本和个人台式机上都有 NVIDIA 显卡。
  • 另一个可能产生的仇恨较少。VMware 的 VMNET 和 VMMON 模块,以便能够运行 VMware Workstation。

Peter Czanik

2

我最喜欢的是 zram 模块。它在内存中创建了一个压缩块设备,然后它可以作为交换分区使用。在内存有限的情况下(例如,在虚拟机上),还有如果你担心频繁的 I/O 操作会磨损你的 SSD 或者甚至更糟糕的基于闪存的存储,那么使用基于 zram 的交换分区是非常理想的。

Stephan Avenwedde

3

最有用的内核模块无疑是 snd-hda-intel,因为它支持大多数集成声卡。我可以一边听音乐,一边在 Linux 桌面上编码一个音频编曲器。

Joël Krähemann

4

如果没有我用 Broadcom 文件生成的 kmod-wl,我的笔记本就没有价值了。我有时会收到关于内核污染的信息,但没有无线网络的笔记本电脑有什么用呢?

Gregory Pittman

5

我不能没有蓝牙。没有它,我的鼠标、键盘、扬声器和耳机除了用来挡住门板还有啥用?

Gary Smith

6

我要冒昧地说 都是。 说真的,我们已经到了随机拿一块硬件,插入它,它就可以工作的地步。

  • USB 串行适配器能正常工作
  • 显卡可以使用(尽管可能不是最好的)
  • 网卡正常工作
  • 声卡正常工作

所有这些模块整体带来大量可以工作的驱动程序,令人印象深刻。我记得在过去那些糟糕的日子里,我们曾经大喊 xrandr 魔法字符串才能来使投影仪工作。而现在,是的,当设备基本不能正常工作时,才真的罕见。

如果我不得不把它归结为一个,那就是 raid6。

John 'Warthog9' Hawley

7

对于这个问题,我想回到 20 世纪 90 年代末。我是一家小公司的 Unix 系统管理员(兼任 IS 经理)。我们的磁带备份系统死了,由于“小公司”预算有限,我们没有急于更换或现场维修。所以我们必须得把它送去维修。

在那两个星期里,我们没有办法进行磁带备份。没有一个系统管理员愿意处于这种境地。

但后来我想起了读过的 如何使用软盘磁带机,我们刚好有一台刚换下来的塔式电脑,它有一个软盘磁带机。

于是我用 Linux 重新安装了它,设置了 ftape 内核驱动模块,进行了一些备份/恢复测试,然后将我们最重要的备份运行到 QIC 磁带上。在这两个星期里,我们依靠 ftape 备份重要数据。

所以,对于那些让软盘磁带机在 1990 年代的 Linux 上工作的无名英雄,你真是太厉害了!

Jim Hall

8

嗯,这很简单。是 kvm 内核模块。就个人而言,我无法想象在没有虚拟机的情况下完成日常工作。我愿意相信我们大多数人都是这样。kvm 模块在使 Linux 成为云战略的核心方面也发挥了很大作用。

Gaurav Kamathe

9

对我来说,是 dm-crypt,它是用于 LUKS 的。参见:

知道别人无法看到你的磁盘上的内容是非常棒的,例如,如果你的笔记本丢失或被盗时。

Maximilian Kolb

10

对于密码学基础,很难超越 crypto 模块和它的 C API,它是如此简洁明了。

在日常生活中,还有什么比蓝牙提供的即插即用更有价值的吗?

Marty Kalin

在评论中与我们分享。你的生活中不能没有什么 Linux 内核模块?


via: https://opensource.com/article/21/8/linux-kernel-module

作者:Jen Wike Huger 选题:lujun9972 译者:geekpi 校对:wxy

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

了解如何使用 Kubermatic Kubernetes 平台来部署、扩展与管理图像识别预测的深度学习模型。

 title=

随着企业增加了对人工智能(AI)、机器学习(ML)与深度学习(DL)的使用,出现了一个关键问题:如何将机器学习的开发进行规模化与产业化?这些讨论经常聚焦于机器学习模型本身;然而,模型仅仅只是完整解决方案的其中一环。为了达到生产环境的应用和规模,模型的开发过程必须还包括一个可以说明开发前后关键活动以及可公用部署的可重复过程。

本文演示了如何使用 Kubermatic Kubernetes 平台 对图像识别预测的深度学习模型进行部署、扩展与管理。

Kubermatic Kubernetes 平台是一个生产级的开源 Kubernetes 集群管理工具,提供灵活性和自动化,与机器学习/深度学习工作流程整合,具有完整的集群生命周期管理。

开始

这个例子部署了一个用于图像识别的深度学习模型。它使用了 CIFAR-10 数据集,包含了 60,000 张分属 10 个类别的 32x32 彩色图,同时使用了 Apache MXNetGluon 与 NVIDIA GPU 进行加速计算。如果你希望使用 CIFAR-10 数据集的预训练模型,可以查阅其 入门指南

使用训练集中的样本对模型训练 200 次,只要训练误差保持缓慢减少,就可以保证模型不会过拟合。下方图展示了训练的过程:

 title=

训练结束后,必须保存模型训练所得到的参数,以便稍后可以加载它们:

file_name = "net.params"
net.save_parameters(file_name)

一旦你的模型训练好了,就可以用 Flask 服务器来封装它。下方的程序演示了如何接收请求中的一张图片作为参数,并在响应中返回模型的预测结果:

from gluoncv.model_zoo import get_model
import matplotlib.pyplot as plt
from mxnet import gluon, nd, image
from mxnet.gluon.data.vision import transforms
from gluoncv import utils
from PIL import Image
import io
import flask
app = flask.Flask(__name__)

@app.route("/predict",methods=["POST"])
def predict():
    if flask.request.method == "POST":
        if flask.request.files.get("img"):
           img = Image.open(io.BytesIO(flask.request.files["img"].read()))
            transform_fn = transforms.Compose([
            transforms.Resize(32),
            transforms.CenterCrop(32),
            transforms.ToTensor(),
            transforms.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010])])
            img = transform_fn(nd.array(img))
            net = get_model('cifar_resnet20_v1', classes=10)
            net.load_parameters('net.params')
            pred = net(img.expand_dims(axis=0))
            class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
                       'dog', 'frog', 'horse', 'ship', 'truck']
            ind = nd.argmax(pred, axis=1).astype('int')
            prediction = 'The input picture is classified as [%s], with probability %.3f.'%
                         (class_names[ind.asscalar()], nd.softmax(pred)[0][ind].asscalar())
    return prediction

if __name__ == '__main__':
   app.run(host='0.0.0.0')

容器化模型

在将模型部署到 Kubernetes 前,你需要先安装 Docker 并使用你的模型创建一个镜像。

  1. 下载、安装并启动 Docker:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo <https://download.docker.com/linux/centos/docker-ce.repo>
sudo yum install docker-ce
sudo systemctl start docker
  1. 创建一个你用来管理代码与依赖的文件夹:
mkdir kubermatic-dl
cd kubermatic-dl
  1. 创建 requirements.txt 文件管理代码运行时需要的所有依赖:
flask
gluoncv
matplotlib
mxnet
requests
Pillow
  1. 创建 Dockerfile,Docker 将根据这个文件创建镜像:
FROM python:3.6
WORKDIR /app
COPY requirements.txt /app
RUN pip install -r ./requirements.txt
COPY app.py /app
CMD ["python", "app.py"]

这个 Dockerfile 主要可以分为三个部分。首先,Docker 会下载 Python 的基础镜像。然后,Docker 会使用 Python 的包管理工具 pip 安装 requirements.txt 记录的包。最后,Docker 会通过执行 python app.py 来运行你的脚本。

  1. 构建 Docker 容器:
sudo docker build -t kubermatic-dl:latest .

这条命令使用 kubermatic-dl 镜像为你当前工作目录的代码创建了一个容器。

  1. 使用
sudo docker run -d -p 5000:5000 kubermatic-dl

命令检查你的容器可以在你的主机上正常运行。

  1. 使用
sudo docker ps -a

命令查看你本地容器的运行状态:

 title=

将你的模型上传到 Docker Hub

在向 Kubernetes 上部署模型前,你的镜像首先需要是公开可用的。你可以通过将你的模型上传到 Docker Hub 来将它公开。(如果你没有 Docker Hub 的账号,你需要先创建一个)

  1. 在终端中登录 Docker Hub 账号:
sudo docker login
  1. 给你的镜像打上标签,这样你的模型上传到 Docker Hub 后也能拥有版本信息:
sudo docker tag <your-image-id> <your-docker-hub-name>/<your-app-name>

sudo docker push <your-docker-hub-name>/<your-app-name>

 title=

  1. 使用
sudo docker images

命令检查你的镜像的 ID。

部署你的模型到 Kubernetes 集群

  1. 首先在 Kubermatic Kubernetes 平台创建一个项目, 然后根据 快速开始 创建一个 Kubernetes 集群。

 title=

  1. 下载用于访问你的集群的 kubeconfig,将它放置在下载目录中,并记得设置合适的环境变量,使得你的环境能找到它:

 title=

  1. 使用 kubectl 命令检查集群信息,例如,需要检查 kube-system 是否在你的集群正常启动了就可以使用命令 kubectl cluster-info

 title=

  1. 为了在集群中运行容器,你需要创建一个部署用的配置文件(deployment.yaml),再运行 apply 命令将其应用于集群中:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubermatic-dl-deployment
spec:
  selector:
    matchLabels:
      app: kubermatic-dl
  replicas: 3
  template:
    metadata:
      labels:
        app: kubermatic-dl
    spec:
     containers:
     - name: kubermatic-dl
       image: kubermatic00/kubermatic-dl:latest
       imagePullPolicy: Always
       ports:
       - containerPort: 8080

kubectl apply -f deployment.yaml`
  1. 为了将你的部署开放到公网环境,你需要一个能够给你的容器创建外部可达 IP 地址的服务:
kubectl expose deployment kubermatic-dl-deployment  --type=LoadBalancer --port 80 --target-port 5000`
  1. 就快大功告成了!首先检查你布署的服务的状态,然后通过 IP 请求的你图像识别 API:
kubectl get service

 title=

  1. 最后根据你的外部 IP 使用以下两张图片对你的图像识别服务进行测试:

 title=

 title=

 title=

总结

在这篇教程中,你可以创建一个深度学习模型,并且使用 Flask 提供 REST API 服务。它介绍了如何将应用放在 Docker 容器中,如何将这个镜像上传到 Docker Hub 中,以及如何使用 Kubernetes 部署你的服务。只需几个简单的命令,你就可以使用 Kubermatic Kubernetes 平台部署该应用程序,并且开放服务给别人使用。


via: https://opensource.com/article/20/9/deep-learning-model-kubernetes

作者:Chaimaa Zyani 选题:lujun9972 译者:chunibyo-wly 校对:wxy

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