分类 技术 下的文章

从 Pop OS 21.10 升级到 Pop OS 22.04 LTS 的简单步骤。

System76 跟着 Ubuntu 22.04 LTS 发布 了 Pop OS 22.04 LTS ,它带来了一些令人兴奋的功能。Pop OS 22.04 LTS 是来自 System76 发布的长期支持版本,它带来了自动计划更新、自定义的 GNOME 42、底层性能改进和 许多其它的功能

你肯定很想体验一下,计划更新到 Pop OS 22.04 。这里我给出你升级 Pop OS 22.04 LTS 的步骤。

注意: 你不能直接从 Pop OS 20.04 升级到 Pop OS 22.04 。首先,你需要先升级到 Pop OS 21.10,然后按照此处概述的步骤升级到这个版本。

从 Pop OS 21.10 升级到 Pop OS 22.04

升级之前的准备

Pop OS 升级过程是相对稳定的。因为根据我们 上一篇关于升级的文章,许多用户面临升级方面的问题。但是如果你正在使用英伟达硬件运行 Pop OS ,我建议你做个备份。

  • 确保你的系统是最新的。你可以使用 Pop 商店应用检查更新。或者,你可以打开终端提示符并运行以下命令更新:
sudo apt update && sudo apt upgrade
  • 按照以上步骤升级完成之后,重启系统。
  • 备份你的文档、照片、视频和其它文件到独立的磁盘分区或者 USB 驱动器。
  • 升级之前,禁用所有 GNOME 扩展。许多扩展会阻挡迁移到 GNOME 42 的过程,最好在你升级之前禁用所有扩展,之后再启用它们。
  • 记下所有额外的软件源或你已经添加的 PPA 仓库,因为它们可能与 “jammy” 分支不兼容。升级之后你可能需要验证它们。
  • 关闭所有运行的程序。
  • 最后,确保你有时间和稳定的网络连接来完成升级。

Pop OS 22.04 LTS 的升级步骤

图形界面升级方法

如果你正在运行的是 Pop OS 21.10 ,你应该看到如下提示是否你的系统需要升级。

Pop OS 22.04 升级提示

或者,你可以打开 “ 设置 Settings ” 然后访问 “ 系统升级和恢复 OS Upgrade and Recovery ” 标签。这里你应该看到有系统更新信息。

Pop OS 22.04 在设置标签的提示

点击 “ Download 下载 ” 开始升级过程。

升级到 Pop OS 22.04 LTS 的终端方法

  • 打开终端运行以下命令:
sudo apt update
sudo apt full-upgrade
  • 这能确保在升级过程开始前系统保持最新。如果你已经在上述升级前步骤中完成了这个步骤,那么你可以忽略它。
  • 使用以下命令更新恢复分区并等待它完成。这只适用于 UEFI 安装模式。
pop-upgrade recovery upgrade from-release
  • 现在使用以下命令开始升级过程:
pop-upgrade release upgrade

开始升级过程

  • 首先,升级过程将会下载软件包。按照我们的测试,需要下载大约 1600 多个软件包。因此,你应该等到它结束。
  • 其次,一旦下载完成,更新管理器将会提示你重启。 准备升级
  • 重启之后,Pop OS 将开始安装最新的软件包到你的系统中。
  • 最后,这个下载过程要花将近一个小时,所以等待它完成。我不建议中途停止更新,这将会导致系统不稳定。 Pop OS 22.04 LTS 桌面
  • 升级完成之后,享受全新的 Pop OS 22.04 LTS 吧。

via: https://www.debugpoint.com/2022/04/upgrade-pop-os-22-04-from-21-10/

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

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

实现一个 WiFi 扫描器玩玩~

去年夏天,我和妻子变卖了家产,带着我们的两只狗移居了夏威夷。这里有美丽的阳光、温暖的沙滩、凉爽的冲浪等你能想到的一切。我们同样遇到了一些意料之外的事:WiFi 问题。

不过,这不是夏威夷的问题,而是我们租住公寓的问题。我们住在一个单身公寓里,与房东的公寓仅一墙之隔。我们的租房协议中包含了免费的网络连接!好耶!只不过,它是由房东的公寓里的 WiFi 提供的,哇哦……

说实话,它的效果还不错……吧?好吧,我承认它不尽如人意,并且不知道是哪里的问题。路由器明明就在墙的另一边,但我们的信号就是很不稳定,经常会自动断开连接。在家的时候,我们的 WiFi 路由器的信号能够穿过层层墙壁和地板。事实上,它所覆盖的区域比我们居住的 600 平方英尺(大约 55 平方米)的公寓还要大。

在这种情况下,一个优秀的技术人员会怎么做呢?既然想知道为什么,当然是开始排查咯!

幸运的是,我们在搬家之前并没有变卖掉树莓派 Zero W。它是如此小巧便携! 我当然就把它一起带来了。我有一个机智的想法:通过树莓派和它内置的 WiFi 适配器,使用 Go 语言编写一个小程序来测量并显示从路由器收到的 WiFi 信号。我打算先简单快速地把它实现出来,以后再去考虑优化。真是麻烦!我现在只想知道这个 WiFi 是怎么回事!

谷歌搜索了一番后,我发现了一个比较有用的 Go 软件包 mdlayher/wifi,它专门用于 WiFi 相关操作,听起来很有希望!

获取 WiFi 接口的信息

我的计划是查询 WiFi 接口的统计数据并返回信号强度,所以我需要先找到设备上的接口。幸运的是,mdlayher/wifi 包有一个查询它们的方法,所以我可以创建一个 main.go 来实现它,具体代码如下:

package main

import (
    "fmt"
    "github.com/mdlayher/wifi"
)

func main() {
    c, err := wifi.New()
    defer c.Close()

    if err != nil {
        panic(err)
    }

    interfaces, err := c.Interfaces()

    for _, x := range interfaces {
        fmt.Printf("%+v\n", x)
    }
}

让我们来看看上面的代码都做了什么吧!首先是导入依赖包,导入后,我就可以使用 mdlayher/wifi 模块就在 main 函数中创建一个新的客户端(类型为 *Client)。接下来,只需要调用这个新的客户端(变量名为 c)的 c.Interfaces() 方法就可以获得系统中的接口列表。接着,我就可以遍历包含接口指针的切片(变长数组),然后打印出它们的具体信息。

注意到 %+v 中有一个 + 了吗?它意味着程序会详细输出 *Interface 结构体中的属性名,这将有助于我标识出我看到的东西,而不用去查阅文档。

运行上面的代码后,我得到了机器上的 WiFi 接口列表:

&{Index:0 Name: HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:3 Type:P2P device Frequency:0}
&{Index:3 Name:wlp2s0 HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:1 Type:station Frequency:2412}

注意,两行输出中的 MAC 地址(HardwareAddr)是相同的,这意味着它们是同一个物理硬件。你也可以通过 PHY: 0 来确认。查阅 Go 的 wifi 模块文档PHY 指的就是接口所属的物理设备。

第一个接口没有名字,类型是 TYPE: P2P。第二个接口名为 wpl2s0,类型是 TYPE: Stationwifi 模块的文档列出了 不同类型的接口,以及它们的用途。根据文档,P2P(点对点传输) 类型表示“该接口属于点对点客户端网络中的一个设备”。我认为这个接口的用途是 WiFi 直连 ,这是一个允许两个 WiFi 设备在没有中间接入点的情况下直接连接的标准。

Station(基站)类型表示“该接口是具有 控制接入点 controlling access point 的客户端设备管理的 基本服务集 basic service set (BSS)的一部分”。这是大众熟悉的无线设备标准功能:作为一个客户端来连接到网络接入点。这是测试 WiFi 质量的重要接口。

利用接口获取基站信息

利用该信息,我可以修改遍历接口的代码来获取所需信息:

for _, x := range interfaces {
    if x.Type == wifi.InterfaceTypeStation {
        // c.StationInfo(x) returns a slice of all
        // the staton information about the interface
        info, err := c.StationInfo(x)
        if err != nil {
            fmt.Printf("Station err: %s\n", err)
        }
        for _, x := range info {
            fmt.Printf("%+v\n", x)
        }
    }
}

首先,这段程序检查了 x.Type(接口类型)是否为 wifi.InterfaceTypeStation,它是一个基站接口(也是本练习中唯一涉及到的类型)。不幸的是名字出现了冲突,这个接口“类型”并不是 Golang 中的“类型”。事实上,我在这里使用了一个叫做 interfaceType 的 Go 类型来代表接口类型。呼,我花了一分钟才弄明白!

然后,假设接口的类型正确,我们就可以调用 c.StationInfo(x) 来检索基站信息,StationInfo() 方法可以获取到关于这个接口 x 的信息。

这将返回一个包含 *StationInfo 指针的切片。我不大确定这里为什么要用切片,或许是因为接口可能返回多个 StationInfo?不管怎么样,我都可以遍历这个切片,然后使用之前提到的 +%v 技巧格式化打印出 StationInfo 结构的属性名和属性值。

运行上面的程序后,我得到了下面的输出:

&{HardwareAddr:70:5a:9e:71:2e:d4 Connected:17m10s Inactive:1.579s ReceivedBytes:2458563 TransmittedBytes:1295562 ReceivedPackets:6355 TransmittedPackets:6135 ReceiveBitrate:2000000 TransmitBitrate:43300000 Signal:-79 TransmitRetries:2306 TransmitFailed:4 BeaconLoss:2}

我感兴趣的是 Signal(信号)部分,可能还有 TransmitFailed(传输失败)和 BeaconLoss(信标丢失)部分。信号强度是以 dBm( 分贝-毫瓦 decibel-milliwatts )为单位来报告的。

简短科普:如何读懂 WiFi dBm

根据 MetaGeek 的说法:

  • -30 最佳,但它既不现实也没有必要
  • -67 非常好,它适用于需要可靠数据包传输的应用,例如流媒体
  • -70 还不错,它是实现可靠数据包传输的底线,适用于电子邮件和网页浏览
  • -80 很差,只是基本连接,数据包传输不可靠
  • -90 不可用,接近“ 背景噪声 noise floor

注意:dBm 是对数尺度,-60 比 -30 要低 1000 倍。

使它成为一个真的“扫描器”

所以,看着上面输出显示的我的信号:-79。哇哦,感觉不大好呢。不过单看这个结果并没有太大帮助,它只能提供某个时间点的参考,只对 WiFi 网络适配器在特定物理空间的某一瞬间有效。一个连续的读数会更有用,借助于它,我们观察到信号随着树莓派的移动而变化。我可以再次修改 main 函数来实现这一点。

var i *wifi.Interface

for _, x := range interfaces {
    if x.Type == wifi.InterfaceTypeStation {
        // Loop through the interfaces, and assign the station
        // to var x
        // We could hardcode the station by name, or index,
        // or hardwareaddr, but this is more portable, if less efficient
        i = x
        break
    }
}

for {
    // c.StationInfo(x) returns a slice of all
    // the staton information about the interface
    info, err := c.StationInfo(i)
    if err != nil {
        fmt.Printf("Station err: %s\n", err)
    }

    for _, x := range info {
        fmt.Printf("Signal: %d\n", x.Signal)
    }

    time.Sleep(time.Second)
}

首先,我命名了一个 wifi.Interface 类型的变量 i。因为它在循环的范围外,所以我可以用它来存储接口信息。循环内创建的任何变量在该循环的范围外都是不可访问的。

然后,我可以把这个循环一分为二。第一个遍历了 c.Interfaces() 返回的接口切片,如果元素是一个 Station 类型,它就将其存储在先前创建的变量 i 中,并跳出循环。

第二个循环是一个死循环,它将不断地运行,直到我按下 Ctrl + C 来结束程序。和之前一样,这个循环内部获取接口信息、检索基站信息,并打印出信号信息。然后它会休眠一秒钟,再次运行,反复打印信号信息,直到我退出为止。

运行上面的程序后,我得到了下面的输出:

[chris@marvin wifi-monitor]$ go run main.go
Signal: -81
Signal: -81
Signal: -79
Signal: -81

哇哦,感觉不妙。

绘制公寓信号分布图

不管怎么说,知道这些信息总比不知道要好。让树莓派连接上显示器或者电子墨水屏,并接上电源,我就可以让它在公寓里移动,并绘制出信号死角的位置。

剧透一下:由于房东的接入点在隔壁的公寓里,对我来说最大的死角是以公寓厨房的冰箱为顶点的一个圆锥体形状区域......这个冰箱与房东的公寓靠着一堵墙!

我想如果用《龙与地下城》里的黑话来说,它就是一个“ 沉默之锥 Cone of Silence ”。或者至少是一个“ 糟糕的网络连接之锥 Cone of Poor Internet ”。

总之,这段代码可以直接在树莓派上运行 go build -o wifi_scanner 来编译,得到的二进制文件 wifi_scanner 可以运行在其他同样的ARM 设备上。另外,它也可以在常规系统上用正确的 ARM 设备库进行编译。

祝你扫描愉快!希望你的 WiFi 路由器不在你的冰箱后面!你可以在 我的 GitHub 存储库 中找到这个项目所用的代码。


via: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi

作者:Chris Collins 选题:lkxed 译者:lkxed 校对:turbokernel

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

学习如何使用 apt 命令在基于 Debian 的 Linux 发行版上安装软件包,然后下载我们的速查表,让正确的命令触手可及。

 title=

包管理器 可帮助你处理 Linux 系统的计算机上软件的更新、卸载、故障排除等问题。Seth Kenlon 写了 使用 dnf 进行 Linux 包管理 一文,介绍了如何使用 dnf 这款命令行包管理工具,在 RHEL、CentOS、Fedora、Mageia、OpenMandriva 等 Linux 发行版中安装软件。

Debian 和基于 Debian 的发行版(例如 MX Linux、Deepin、Ubuntu)以及基于 Ubuntu 的发行版(例如 Linux Mint 和 Pop!\_OS)都有 apt,这是一个“相似但不同”的工具。在本文中,我将按照 Seth 的示例(但使用 apt)向你展示如何使用它。

在一开始,我想先提一下四个跟 apt 相关的软件安装工具:

  • Synaptic 是为 apt 服务的一个基于 GTK+ 的图形用户界面(GUI)的前端工具。
  • Aptitude 是为 apt 服务的一个基于 Ncurses 的全屏命令行前端工具。
  • apt 的前身有 apt-getapt-cache 等工具。
  • Dpkg 是在 apt 包管理器背后处理繁杂事务的”幕后工作者“。

还有其他的包管理系统,例如 FlatpakSnap,你可能会在 Debian 和基于 Debian 的系统上遇到它们,但我不打算在这里讨论。还有一些应用程序“商店”,例如 GNOME “软件”,与 apt 和其他打包技术重叠;我也不打算在这里讨论它们。最后,还有其他 Linux 发行版,例如 ArchGentoo 既不使用 dnf 也不使用 apt,我也不打算在这里讨论它们!

上面我讲了这么多我不想提及的内容,你可能怀疑 apt 到底还能处理多少软件。这么说吧,在我的 Ubuntu 20.04 上,apt 可以让我使用 69,371 个软件包,从 0ad(一款古代战争题材的即时战略游戏)到 zzuf(一个透明的应用程序模糊测试工具),一点也不差。

使用 apt 搜索软件

使用 apt 软件包管理器的第一步是找到感兴趣的软件包。Seth 的 dnf 文章以 Cockpit 服务器管理应用程序为例。用 apt 我会输入如下命令:

$ apt search cockpit
Sorting... Done
Full Text Search... Done
389-ds/hirsute,hirsute 1.4.4.11-1 all
  389 Directory Server suite - metapackage

cockpit/hirsute,hirsute 238-1 all
  Web Console for Linux servers

...
$

上面的第二个包就是你要的那个(以 cockpit/hirsute 开头的那一行)。如果你决定要安装它,输入:

$ sudo apt install cockpit

apt 将负责安装 Cockpit 以及使其工作所需的所有部件或 依赖。有时我们不太确定这是我们所需要的。了解更多的信息可能有助于你决定是否真的要安装此应用程序。

包元数据

要了解有关软件包的更多信息,使用 apt show 命令:

$ apt show cockpit
Package: cockpit
Version: 238-1
Priority: optional
Section: universe/admin
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Utopia Maintenance Team <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 88.1 kB
Depends: cockpit-bridge (>= 238-1), cockpit-ws (>= 238-1), cockpit-system (>= 238-1)
Recommends: cockpit-storaged (>= 238-1), cockpit-networkmanager (>= 238-1), cockpit-packagekit (>= 238-1)
Suggests: cockpit-doc (>= 238-1), cockpit-pcp (>= 238-1), cockpit-machines (>= 238-1), xdg-utils
Homepage: https://cockpit-project.org/
Download-Size: 21.3 kB
APT-Sources: http://ca.archive.ubuntu.com/ubuntu hirsute/universe amd64 Packages
Description: Web Console for Linux servers
 The Cockpit Web Console enables users to administer GNU/Linux servers using a
 web browser.
 .
 It offers network configuration, log inspection, diagnostic reports, SELinux
 troubleshooting, interactive command-line sessions, and more.

$

特别要注意的是 Description 字段,它会告诉你更多关于应用程序的信息。Depends 字段说明还必须安装什么,而 Recommends 则显示建议安装的其他(如果有的话)合作组件。Homepage 字段会提供一个网址,通过它你可以了解更多。

哪个包提供的这个文件?

有时你并不知道包名,但你知道包里一定包含着的某个文件。Seth 以 qmake-qt5 程序作为示例。使用 apt search 找不到它:

$ apt search qmake-qt5
Sorting... Done
Full Text Search... Done
$

但是,另一个有关联的命令 apt-file 可以用来探索包内部:

$ apt-file search qmake-qt5
qt5-qmake-bin: /usr/share/man/man1/qmake-qt5.1.gz
$

这时会显示一个 qmake-qt5 的手册页。它是一个名为 qt5-qmake-bin 的包的一部分。注意,此包名称颠倒了字符串 qmakeqt5 的顺序。

包里包含哪些文件?

方便的 apt-file 命令会列出给定的包中包含哪些文件。例如:

$ apt-file list cockpit
cockpit: /usr/share/doc/cockpit/TODO.Debian
cockpit: /usr/share/doc/cockpit/changelog.Debian.gz
cockpit: /usr/share/doc/cockpit/copyright
cockpit: /usr/share/man/man1/cockpit.1.gz
cockpit: /usr/share/metainfo/cockpit.appdata.xml
cockpit: /usr/share/pixmaps/cockpit.png
$

注意,这与 apt show 命令提供的信息不同,后者列出了包的依赖(其他必须安装的包)。

移除一个应用程序

你还可以使用 apt 移除软件包。例如,要移除apt-file 应用程序:

$ sudo apt purge apt-file

注意必须由超级用户运行 apt 才能安装或移除应用程序。

移除一个包并不会自动移除 apt 在此过程中安装的所有依赖项。不过,一点点的工作就很容易去除这些残留:

$ sudo apt autoremove

认识一下 apt

正如 Seth 所写的,“你对包管理器的工作方式了解得越多,在需要安装和查询应用程序时就会越容易。”

即便你不是 apt 的重度使用者,当你需要在命令行中安装或删除软件包时(例如,在一台远程服务器上或遵循某些热心肠发布的操作指南时),掌握一些 apt 的知识也会很有用。在某些软件创作者仅提供了一个裸 .pkg 文件的情况下,可能还需要了解一些关于 dpkg 的知识(如上所述)。

我发现 Synaptic 包管理器在我的桌面上是一个非常有用的工具,但出于各种目的,我也在少数维护的服务器上使用着 apt

下载我们的 apt 速查表 习惯该命令并尝试一些新技巧。一旦你这样做了,你可能会发现很难再使用其他任何东西。

apt 速查表

via: https://opensource.com/article/21/6/apt-linux

作者:Chris Hermansen 选题:lujun9972 译者:hanszhao80 校对:wxy

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

watch 和 tail 命令可以帮助监视 Linux 系统上的活动。本文介绍了这两个命令的一些有用的使用方法。

watchtail 命令为持续监视 Linux 系统上的活动提供了一些有趣的选项。

也就是说,你可以通过 watch 来显示谁已登录,并随着用户登录和注销不断更新,而不是仅仅提出问题并获得答案(例如询问 who 并获取当前登录用户的列表)。

使用 tail,你可以显示文件的底部并在添加内容时查看内容。这种监控一般非常有用,并且比定期运行命令所需的工作更少。

使用 watch 命令

使用 watch 的最简单示例之一是使用命令 watch who。你会看到一个列表,其中显示了谁登录了,以及他们登录的时间和登录位置。请注意,默认设置是每两秒更新一次显示(左上角),日期和时间(右上角)将按该间隔自行更新。用户列表将随着用户登录和注销而增长和缩小。

$ watch who

此命令将显示如下所示的登录列表:

Every 2.0s: who                              dragonfly: Thu Feb 27 10:52:00 2020

nemo     pts/0        2020-02-27 08:07 (192.168.0.11)
shs      pts/1        2020-02-27 10:58 (192.168.0.5)

你可以通过添加 -n 选项(例如 -n 10)来修改更新间的不同秒数,以修改更新间隔,从而获取较少的更新频率。

$ watch -n 10 who

上述命令将以新的间隔显示,并且显示的时间更新频率较低,从而使显示时间与所选间隔保持一致。

Every 10.0s: who                             dragonfly: Thu Feb 27 11:05:47 2020

nemo     pts/0        2020-02-27 08:07 (192.168.0.11)
shs      pts/1        2020-02-27 10:58 (192.168.0.5)

如果你希望仅查看命令的输出,而不是标题(前 2 行),则可以通过添加 -t(无标题)选项来省略这些行。

$ watch -t who

然后,你的屏幕将显示如下所示:

nemo     pts/0        2020-02-27 08:07 (192.168.0.11)
shs      pts/1        2020-02-27 10:58 (192.168.0.5)

如果每次运行监视的命令时,输出都是相同的,则只有标题行(如果未省略)会更改。其余显示的信息将保持不变。

如果你希望 watch 命令在它正在监视的命令的输出发生更新后立即退出,则可以使用 -g(将其视为“ 离开 go away ”)选项。例如,如果你只是在等待其他人开始登录系统,则可以选择执行此操作。

你还可以使用 -d 差异 differences )选项突出显示显示输出中的更改。突出显示只会持续一个间隔(默认为 2 秒),但有助于引起你对更新的注意。

下面是一个更复杂的示例,该示例使用 watch 命令显示正在侦听连接的服务及其使用的端口。虽然输出不太可能更改,但它会提醒你任何新服务正在启动或关闭。

$ watch 'sudo lsof -i -P -n | grep LISTEN'

值得注意的是,正在运行的命令需要用引号扩起来,以确保不会将 watch 命令的输出发送到 grep 命令。

使用 watch -h 命令将为你提供命令选项的列表。

$ watch -h

Usage:
 watch [options] command

Options:
  -b, --beep             beep if command has a non-zero exit
  -c, --color            interpret ANSI color and style sequences
  -d, --differences[=<permanent>]
                         highlight changes between updates
  -e, --errexit          exit if command has a non-zero exit
  -g, --chgexit          exit when output from command changes
  -n, --interval <secs>  seconds to wait between updates
  -p, --precise          attempt run command in precise intervals
  -t, --no-title         turn off header
  -x, --exec             pass command to exec instead of "sh -c"

 -h, --help     display this help and exit
 -v, --version  output version information and exit

使用 tail -f

tail -f 命令与 watch 有一些相同之处。它也会在添加文件时显示文件的底部和其他内容。你不必一次又一次地运行 tail 命令,而是运行一个命令并获得可重复更新显示视图的结果。例如,你可以使用如下命令查看系统日志:

$ tail -f /var/log/syslog

某些文件(如 /var/log/wtmp)不适合这种类型的处理,因为它们的格式不是普通文本文件,但是通过组合 watchtail,你可以获得类似的结果,如下所示:

watch 'who /var/log/wtmp | tail -20'

无论有多少用户仍处于登录状态,此命令都将只显示最近的 5 次登录。如果发生其他登录,显示结果将添加一行记录并删除顶行记录。

Every 60.0s: who /var/log/wtmp | tail -5    dragonfly: Thu Feb 27 12:46:07 2020

shs      pts/0        2020-02-27 08:07 (192.168.0.5)
nemo     pts/1        2020-02-27 08:26 (192.168.0.5)
shs      pts/1        2020-02-27 10:58 (192.168.0.5)
nemo     pts/1        2020-02-27 11:34 (192.168.0.5)
dory     pts/1        2020-02-27 12:14 (192.168.0.5)

对你有时可能想要监视的信息,无论监视进程、登录名还是系统资源,watchtail -f 命令都可以提供自动更新视图,从而使监视任务变得更加容易。


via: https://www.networkworld.com/article/3529891/watching-activity-on-linux-with-watch-and-tail-commands.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:Starryi 校对:wxy

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

通过理解和使用 JVM 以及 JVM 参数,开发人员和最终用户都可以诊断故障并且提高 Java 应用程序的性能。

当你在编写源代码时,你是在编写人类可以阅读的代码。在将代码编译成机器语言之前,计算机无法执行它。机器语言是一个通用术语,指的是特定机器所需的任意数量的语言。通常,如果你在 Linux 上编译代码,它只能 Linux 上运行;如果你在 Windows 上编译代码,它就只在 Windows 上运行。但是,Java 是不同的,它并不以真实的机器为目标,而是面向 Java 虚拟机 Java Virtual Machine (JVM)。因此,它可以在任何机器上运行。

Java 源代码被编译成 字节码 bytecode ,然后由安装在计算机上的 JVM 运行。JVM 是一个执行引擎,但我们通常不会直接与它交互。它在后台静默运行,替我们处理 Java 字节码。大多数人不需要考虑,甚至也不需要知道 JVM。但是,了解它的工作原理是对我们来说是非常有用的,因为这会有助于我们调试和优化 Java 代码。例如:

  • 在生产环境中,你发现已经部署的应用程序可能需要提升性能。
  • 如果你写的应用程序出错了,开发人员和最终用户都可以选择对问题进行调试。
  • 如果你想了解关于 JDK(即 Java 开发工具包 Java Development Kit ,用于开发/运行 Java 应用程序)的详细信息,你可以通过查询 JVM 来获取。

本文介绍了一些基础的 JVM 参数,希望在这些场景中可以提供帮助。

JVM 参数

(图源:Jayashree Huttanagoudar,CC BY-SA 4.0)

JVM、JDK 和 JRE 有什么不同?

Java 有许多 J 开头的缩略词,包括 JVM、JDK 和 JRE。

  • Java 开发工具包 Java Development Kit (JDK)可供需要在代码中使用开发库的程序员使用。
  • Java 运行时环境 Java Runtime Environment (JRE)可供想运行 Java 应用程序的人使用。
  • Java 虚拟机 Java Virtual Machine (JVM)是运行 Java 字节码的组件。

JDK 同时包含 JRE 和 JVM,但有些 Java 发行版提供了包含 JRE(包括 JVM)的替代下载。

JDK

(图源:Jayashree Huttanagoudar,CC BY-SA 4.0)

Java 是开源的,因此,许多不同的公司都会构建和发行他们自己的 JDK 发行版。你可以在系统上安装多个 JDK,这会对你参与或者运行不同的 Java 项目时很有帮助,因为其中一些项目可能使用旧版本的 JDK。

你可以使用 alternatives 命令,来查看 Linux 系统上的 JDK 列表:

$ alternatives --config java
There are 2 programs that provide java.
Selection Command
-----------------------------------------------
*+ 1 java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-2.fc35.x86_64/bin/java)
2 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/jre/bin/java)

Enter to keep the current selection[+], or type selection number:

如果想要在可用的 JDK 之间进行切换,请再次执行该命令:

$ sudo alternatives --config java

或者可以使用 SDKMan,它可以下载、更新和管理系统中的所有 JDK。

什么是 JVM 调优?

JVM 调优指的是,通过调整 JVM 参数,来提高 Java 应用程序性能的过程,它还有助于诊断应用程序的故障。

通常情况下,在调试之前需要考虑以下几点:

  • 成本:有时改进运行代码的硬件可以提高应用程序的性能。这可能看起来像是在“作弊”,但请考虑你愿意花多少时间调整 JVM 参数。有时应用程序需要更多的内存来执行所需的功能,而这点是任何软件技术都无法改变的。
  • 期望结果:长期来看,稳定性比性能更重要。如果你的调优对稳定性产生了影响,那么谨慎地选择你的调优参数可能会更好。
  • 底层问题:有时,问题可能是主机操作系统的底层问题。那么,在调整 JVM 之前,请确保 JVM 平台按预期工作。
  • 内存泄漏:如果你在使用垃圾回收(GC)调优参数,那么,应用程序代码中很可能会存在需要修复的内存泄漏。

参数类型

JVM 参数可以分为以下三类:标准参数、非标准参数和高级选项。

标准参数

所有的 JVM 实现都支持标准参数,在终端执行 java 命令来查看标准参数列表:

$ java
Usage: java [options] <mainclass> [args...]
        (to execute a class)
   or  java [options] -jar <jarfile> [args...]
        (to execute a jar file)

 where options include:

        -cp <class search path of directories and zip/jar files>
        -classpath <class search path of directories and zip/jar files>
        --class-path <class search path of directories and zip/jar files>
                A : separated list of directories, JAR archives,
                and ZIP archives to search for class files.
        --enable-preview
                allow classes to depend on preview features of this release

To specify an argument for a long option, you can use --<name>=<value> or
--<name> <value>.

这些是所有 JVM 都会包含的标准参数,你可以像使用任何 命令行选项 一样安全地使用它们。例如,要验证配置的命令选项,创建 VM 并加载主类而不执行主类,请使用:

$ java --dry-run <classfile>

非标准参数

非标准选项以 -X 开头。这些是通用的,并且特定于 JVM 的特定实现。要列出这些参数,请输入:

$ java -X
-Xbatch disable background compilation
-Xbootclasspath/a:<directories and zip/jar files separated by :>
append to end of bootstrap class path
-Xinternalversion
displays more detailed JVM version information than the
-version option
-Xloggc:<file> log GC status to a file with time stamps
[...]

在这些参数可能会不经通知就发生变化。而且,并非所有 JVM 实现都支持这些参数。

微软构建的 JVM 可能与 RedHat 构建的 JVM 有不同的参数,诸如此类。

要获取详细的 JVM 版本信息,请使用如下命令:

$ java -Xinternalversion --version
OpenJDK 64-Bit Server VM (11.0.13+8) for linux-amd64 JRE (11.0.13+8), built on Nov 8 2021 00:00:00 by "mockbuild" with gcc 11.2.1 20210728 (Red Hat 11.2.1-1)

要获取这些属性设置,请使用:

$ java -XshowSettings:properties --version

高级选项

这些参数不是随意使用的,而是用于调整 Hotspot VM 的特定区域。这些参数可能会发生变化,并且不能保证得到所有 JVM 实现的支持。

这些参数以 -XX 开头。如需列出参数列表,使用如下命令:

$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version

例如,需要跟踪类的加载,那么使用下面的命令:

$ java -XX:+TraceClassLoading Hello

Hello.java 中:

public class Hello {
  public static void main(String[] args) {
    System.out.println("Inside Hello World!");
  }
}

另一个可能会面临的问题是 OOM( 内存超出 Out Of Memory )错误,它发生的时候可能没有太多的调试信息。为了解决这个问题,使用调试参数 -XX:+HeapDumpOnOutOfMemoryError,它可以创建一个带有调试信息的 .hprof 文件。

// TestClass.java
import java.util.ArrayList;
import java.util.List;

public class TestClass {
  public static void main(String[] args) {
    List<Object> list = new ArrayList<Object>();
    for (int i = 0; i < 1000; i++) {
      list.add(new char[1000000]);
    }
  }
}
$ Javac TestClass.java
$ java -XX:+HeapDumpOnOutOfMemoryError -Xms10m -Xmx1g TestClass
java.lang.OutOfMemoryError: java heap space
Dumping heap to java_pid444496.hprof ...
Heap dump file created [1018925828 bytes in 1.442 secs]
Exception in thread "main" java.lang.OutOfMemoryError: java heap space
at TestClass.main(TestClass.Java:8)

有一些工具 可以查看这个 .hprof 文件以了解问题所在。

总结

通过了解和使用 JVM 以及 JVM 参数,开发人员和终端用户都可以诊断故障并提高 Java 应用程序的性能。下次使用 Java 时,请花点时间看看有哪些参数可以用吧!

(题图由 Seksak KerdkannoPixabay 上发布 )


via: https://opensource.com/article/22/4/jvm-parameters-java-developers

作者:Jayashree Huttanagoudar 选题:lkxed 译者:Veryzzj 校对:wxy

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

RT-Thread Smart 致力于物联网和边缘计算领域的开源。

 title=

目前对 嵌入式操作系统 有巨大的需求,你建立的操作系统最好是开源的。RT-Thread 项目的研发团队花了两年时间,研发出了该项目的最新成果:RT-Thread Smart。这是一款微内核的操作系统,主要针对中高端的处理器,如具有内存管理单元(MMU)的 RISC-V 或 Arm Cortex-A,为嵌入式领域的所有行业提供了一个具有竞争力的、基于 POSIX 的软件平台。

谁需要 RT-Thread Smart?

RT-Thread Smart 是一款专业的、高性能的微内核操作系统,用于实时应用。它为所有市场的嵌入式设备提供了开源基础,如安全(IP 摄像头)、工业控制、车载设备、消费电子及其他嵌入式科技应用,可谓一切场景。它的意义在于:不像传统的物联网操作系统,一个微内核的操作系统可以填补传统实时操作系统 RTOS 和相对大型的操作系统如 Linux 之间的空白,实现实时性能、成本、安全、启动速度等等各方面之间的最佳平衡。

RT-Thread Smart 的架构

RT-Thread Smart 通过 MMU 和系统调用将系统分割为内核模式和用户模式,并为每种模式区分了地址空间(一个 32 位系统可以提供 4G 地址空间)。

 title=

(RT-Thread, CC BY-SA 4.0

RT-Thread Smart 内核包括平台的基础功能,并支持定制化。RT-Thread Smart 的用户应用环境使用 musl libc 来提供 POSIX 接口调用和 C 语言的运行时支持。它也继承了原始的 RT-Thread 生态系统,使用 SCons 或者其他编译工具如 Autotools、Makefile、CMake 等等来支持开发,以及 RT-Thread 开箱即用的在线软件包(撰写本文时超过 342 个)。你甚至可以将 Linux 应用程序(如 wget/cURL、BusyBox、OpenSSL 和 Simple DirectMedia Layer)移植到你的平台。

压缩的 RT-Thread Smart 内核仅 217 KB,搭配一个 127 KB 的根文件系统。大约 2 MB的存储占用。包括了对文件系统、网络协议栈、多媒体的完整支持。RT-Thread 只需要 3 到 5 秒完成启动,而在不运行其他功能组件时,RT-Thread Smart 需要的启动及准备时间不到 500ms。

通过其集成的 Persimmon 用户界面(UI)组件,RT-Thread Smart 从上电到运行 UI 需要大约 1 秒。换句话说,这是一个非常轻巧快速的系统。当然,“实时”不是指启动,而是指系统随着时间推进而表现出的一致性。对于 RT-Thread ,实时性能需要优先考虑,中断时延小于 1μs,满足大部分实时性要求严格的场景需求。

RT-Thread Smart 和 RT-Thread

你可能想知道 RT-Thread Smart 和 RT-Thread 之间的不同。简单来说, RT-Thread Smart 是一个基于 RT-Thread RTOS 的操作系统,但它整合了用户态的处理过程。RT-Smart 的内核部分本质上是 RT-Thread RTOS,它在虚拟地址上运行,增加了进程管理,使用进程间通信机制(IPC)、虚拟内存/地址空间管理、ELF 加载器等等,以上特性全部在 RT-Thread RTOS 内实现,当这些组件被禁用时,RT-Smart 会回归 RT-Thread RTOS。

以下是对比:

RT-ThreadRT-Thread Smart
支持芯片Cortex-M/R、RISC-V RV32IMAC(以及类似)、Cortex-A MPUCortex-A 等具有 MMU 的 MPU
编译内核和应用都编译到一个镜像内核和应用可以被分开编译和运行
存储使用线性地址空间(即使有 MMU),使用物理地址的虚拟寻址运行在内核占用超过 1GB 的 32 位操作系统,拥有完整 4G 地址空间的用户态进程彼此隔离,外设驱动程序必须通过虚拟地址访问外设
运行错误当一个应用程序失败时,整个系统就会崩溃当应用程序失败时,它不会影响内核和其他进程的执行
运行模式多线程模型多进程模型(进程内支持多线程,内核线程由内核支持)
用户模型单用户模型单用户模型
APIRT-Thread API、POSIX PSE52RT-Thread API(内核态和用户态),以及完整的 POSIX API
实时性抢占式硬实时系统抢占式硬实时系统
资源使用非常小相对小
调试通常需要模拟器调试支持 GDB 调试,不需要模拟器

RT-Thread RTOS 非常紧凑,它的所有应用和子系统都编译到镜像中,多线程应用运行并分享相同的地址空间。

RT-Thread Smart 是独立的。系统和应用是分别编译和运行的。应用拥有完整且互相隔离的地址空间。它也继承了 RT-Thread 优秀的实时性,同时也具有 POSIX 环境的特性。

类似地,它们都与 RT-Thread API 兼容。RT-Thread RTOS 的应用可以被平滑移植到 RT-Thread Smart。

嵌入式开源

RT-Thread Smart 是一个开源项目,项目地址:GitHub。你可以下载代码和文档,尝试一下,并提交评论和反馈,将该项目传播给更多开源倡导者。嵌入式系统属于它们的用户,有太多的嵌入式开发人员没有找到太多可用的嵌入式系统。

如果你是开发人员,请帮助改进 RT-Thread Smart。随着 RT-Thread 项目的不断推进,我们希望创建物联网和边缘计算的令人激动的开源世界。


via: https://opensource.com/article/21/7/rt-thread-smart

作者:Zhu Tianlong 选题:lujun9972 译者:tendertime 校对:wxy

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