分类 技术 下的文章

D 语言以系统编程语言而闻名,但它也是编写脚本的一个很好的选择。

 title=

D 语言由于其静态类型和元编程能力,经常被宣传为系统编程语言。然而,它也是一种非常高效的脚本语言。

由于 Python 在自动化任务和快速实现原型想法方面的灵活性,它通常被选为脚本语言。这使得 Python 对系统管理员、管理者和一般的开发人员非常有吸引力,因为它可以自动完成他们可能需要手动完成的重复性任务。

我们自然也可以期待任何其他的脚本编写语言具有 Python 的这些特性和能力。以下是我认为 D 是一个不错的选择的两个原因。

1、D 很容易读和写

作为一种类似于 C 的语言,D 应该是大多数程序员所熟悉的。任何使用 JavaScript、Java、PHP 或 Python 的人对 D 语言都很容易上手。

如果你还没有安装 D,请安装 D 编译器,这样你就可以运行本文中的 D 代码。你也可以使用在线 D 编辑器

下面是一个 D 代码的例子,它从一个名为 words.txt 的文件中读取单词,并在命令行中打印出来:

open
source
is
cool

用 D 语言写脚本:

#!/usr/bin/env rdmd
// file print_words.d

// import the D standard library
import std;

void main(){
    // open the file
     File("./words.txt")

         //iterate by line
        .byLine

        // print each number
        .each!writeln;
}

这段代码以 释伴) 开头,它将使用 rdmd 来运行这段代码,rdmd 是 D 编译器自带的编译和运行代码的工具。假设你运行的是 Unix 或 Linux,在运行这个脚本之前,你必须使用chmod 命令使其可执行:

chmod u+x print_words.d

现在脚本是可执行的,你可以运行它:

./print_words.d

这将在你的命令行中打印以下内容:

open
source
is
cool

恭喜你,你写了第一个 D 语言脚本。你可以看到 D 是如何让你按顺序链式调用函数,这让阅读代码的感觉很自然,类似于你在头脑中思考问题的方式。这个功能让 D 成为我最喜欢的编程语言

试着再写一个脚本:一个非营利组织的管理员有一个捐款的文本文件,每笔金额都是单独的一行。管理员想把前 10 笔捐款相加,然后打印出金额:

#!/usr/bin/env rdmd
// file sum_donations.d

import std;

void main()
{
    double total = 0;

    // open the file
    File("monies.txt")

         // iterate by line
        .byLine

         // pick first 10 lines
        .take(10)

        // remove new line characters (\n)
        .map!(strip)

         // convert each to double
        .map!(to!double)

        // add element to total
        .tee!((x) { total += x; })

        // print each number
        .each!writeln;

    // print total
    writeln("total: ", total);
}

each 一起使用的 ! 操作符是模板参数的语法。

2、D 是快速原型设计的好帮手

D 是灵活的,它可以快速地将代码敲打在一起,并使其发挥作用。它的标准库中包含了丰富的实用函数,用于执行常见的任务,如操作数据(JSON、CSV、文本等)。它还带有一套丰富的通用算法,用于迭代、搜索、比较和 mutate 数据。这些巧妙的算法通过定义通用的 基于范围的接口 而按照序列进行处理。

上面的脚本显示了 D 中的链式调用函数如何提供顺序处理和操作数据的要领。D 的另一个吸引人的地方是它不断增长的用于执行普通任务的第三方包的生态系统。一个例子是,使用 Vibe.d web 框架构建一个简单的 web 服务器很容易。下面是一个例子:

#!/usr/bin/env dub
/+ dub.sdl:
dependency "vibe-d" version="~>0.8.0"
+/
void main()
{
    import vibe.d;
    listenHTTP(":8080", (req, res) {
        res.writeBody("Hello, World: " ~ req.path);
    });
    runApplication();
}

它使用官方的 D 软件包管理器 Dub,从 D 软件包仓库中获取 vibe.d Web 框架。Dub 负责下载 Vibe.d 包,然后在本地主机 8080 端口上编译并启动一个 web 服务器。

尝试一下 D 语言

这些只是你可能想用 D 来写脚本的几个原因。

D 是一种非常适合开发的语言。你可以很容易从 D 下载页面安装,因此下载编译器,看看例子,并亲自体验 D 语言。


via: https://opensource.com/article/21/1/d-scripting

作者:Lawrence Aberba 选题:lujun9972 译者:geekpi 校对:wxy

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

这本初学者指南向你展示了在 Linux 中可以使用 pacman 命令做什么,如何使用它们来查找新的软件包,安装和升级新的软件包,以及清理你的系统。

pacman 包管理器是 Arch Linux 和其他主要发行版如 Red Hat 和 Ubuntu/Debian 之间的主要区别之一。它结合了简单的二进制包格式和易于使用的 构建系统pacman 的目标是方便地管理软件包,无论它是来自 官方库 还是用户自己构建的软件库。

如果你曾经使用过 Ubuntu 或基于 debian 的发行版,那么你可能使用过 apt-getapt 命令。pacman 在 Arch Linux 中是同样的命令。如果你 刚刚安装了 Arch Linux,在安装 Arch Linux 后,首先要做的 几件事 之一就是学习使用 pacman 命令。

在这个初学者指南中,我将解释一些基本的 pacman 命令的用法,你应该知道如何用这些命令来管理你的基于 Archlinux 的系统。

Arch Linux 用户应该知道的几个重要的 pacman 命令

与其他包管理器一样,pacman 可以将包列表与软件库同步,它能够自动解决所有所需的依赖项,以使得用户可以通过一个简单的命令下载和安装软件。

通过 pacman 安装软件

你可以用以下形式的代码来安装一个或者多个软件包:

pacman -S 软件包名1 软件包名2 ...

安装一个包

-S 选项的意思是 同步 synchronization ,它的意思是 pacman 在安装之前先与软件库进行同步。

pacman 数据库根据安装的原因将安装的包分为两组:

  • 显式安装:由 pacman -S-U 命令直接安装的包
  • 依赖安装:由于被其他显式安装的包所 依赖,而被自动安装的包。

卸载已安装的软件包

卸载一个包,并且删除它的所有依赖。

pacman -R 软件包名

移除一个包

删除一个包,以及其不被其他包所需要的依赖项:

pacman -Rs 软件包名

如果需要这个依赖的包已经被删除了,这条命令可以删除所有不再需要的依赖项:

pacman -Qdtq | pacman -Rs -

升级软件包

pacman 提供了一个简单的办法来 升级 Arch Linux。你只需要一条命令就可以升级所有已安装的软件包。这可能需要一段时间,这取决于系统的新旧程度。

以下命令可以同步存储库数据库,并且 更新系统的所有软件包,但不包括不在软件库中的“本地安装的”包:

pacman -Syu
  • S 代表同步
  • y 代表更新本地存储库
  • u 代表系统更新

也就是说,同步到中央软件库(主程序包数据库),刷新主程序包数据库的本地副本,然后执行系统更新(通过更新所有有更新版本可用的程序包)。

系统更新

注意!

对于 Arch Linux 用户,在系统升级前,建议你访问 Arch-Linux 主页 查看最新消息,以了解异常更新的情况。如果系统更新需要人工干预,主页上将发布相关的新闻。你也可以订阅 RSS 源Arch 的声明邮件

在升级基础软件(如 kernel、xorg、systemd 或 glibc) 之前,请注意查看相应的 论坛,以了解大家报告的各种问题。

在 Arch 和 Manjaro 等滚动发行版中不支持部分升级。这意味着,当新的库版本被推送到软件库时,软件库中的所有包都需要根据库版本进行升级。例如,如果两个包依赖于同一个库,则仅升级一个包可能会破坏依赖于该库的旧版本的另一个包。

用 Pacman 查找包

pacman 使用 -Q 选项查询本地包数据库,使用 -S 选项查询同步数据库,使用 -F 选项查询文件数据库。

pacman 可以在数据库中搜索包,包括包的名称和描述:

pacman -Ss 字符串1 字符串2 ...

查找一个包

查找已经被安装的包:

pacman -Qs 字符串1 字符串2 ...

根据文件名在远程软包中查找它所属的包:

pacman -F 字符串1 字符串2 ...

查看一个包的依赖树:

pactree 软件包名

清除包缓存

pacman 将其下载的包存储在 /var/cache/Pacman/pkg/ 中,并且不会自动删除旧版本或卸载的版本。这有一些优点:

  1. 它允许 降级 一个包,而不需要通过其他来源检索以前的版本。
  2. 已卸载的软件包可以轻松地直接从缓存文件夹重新安装。

但是,有必要定期清理缓存以防止文件夹增大。

pacman contrib 包中提供的 paccache(8) 脚本默认情况下会删除已安装和未安装包的所有缓存版本,但最近 3 个版本除外:

paccache -r

清除缓存

要删除当前未安装的所有缓存包和未使用的同步数据库,请执行:

pacman -Sc

要从缓存中删除所有文件,请使用清除选项两次,这是最激进的方法,不会在缓存文件夹中留下任何内容:

pacman -Scc

安装本地或者第三方的包

安装不是来自远程存储库的“本地”包:

pacman -U 本地软件包路径.pkg.tar.xz

安装官方存储库中未包含的“远程”软件包:

pacman -U http://www.example.com/repo/example.pkg.tar.xz

额外内容:用 pacman 排除常见错误

下面是使用 pacman 管理包时可能遇到的一些常见错误。

提交事务失败(文件冲突)

如果你看到以下报错:

error: could not prepare transaction
error: failed to commit transaction (conflicting files)
package: /path/to/file exists in filesystem
Errors occurred, no packages were upgraded.

这是因为 pacman 检测到文件冲突,不会为你覆盖文件。

解决这个问题的一个安全方法是首先检查另一个包是否拥有这个文件(pacman-Qo 文件路径)。如果该文件属于另一个包,请提交错误报告。如果文件不属于另一个包,请重命名“存在于文件系统中”的文件,然后重新发出更新命令。如果一切顺利,文件可能会被删除。

你可以显式地运行 pacman -S –overwrite 要覆盖的文件模式**,强制pacman` 覆盖与 给模式匹配的文件,而不是手动重命名并在以后删除属于该包的所有文件。

提交事务失败(包无效或损坏)

/var/cache/pacman/pkg/ 中查找 .part 文件(部分下载的包),并将其删除。这通常是由在 pacman.conf 文件中使用自定义 XferCommand 引起的。

初始化事务失败(无法锁定数据库)

pacman 要修改包数据库时,例如安装包时,它会在 /var/lib/pacman/db.lck 处创建一个锁文件。这可以防止 pacman 的另一个实例同时尝试更改包数据库。

如果 pacman 在更改数据库时被中断,这个过时的锁文件可能仍然保留。如果你确定没有 pacman 实例正在运行,那么请删除锁文件。

检查进程是否持有锁定文件:

lsof /var/lib/pacman/db.lck

如果上述命令未返回任何内容,则可以删除锁文件:

rm /var/lib/pacman/db.lck

如果你发现 lsof 命令输出了使用锁文件的进程的 PID,请先杀死这个进程,然后删除锁文件。

我希望你喜欢我对 pacman 基础命令的介绍。


via: https://itsfoss.com/pacman-command/

作者:Dimitrios Savvopoulos 选题:lujun9972 译者:Chao-zhi 校对:wxy

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

我相信我们的大多数读者都知道 Antergos 项目的终结。在这一消息宣布之后,Antergos 社区的成员创建了几个发行版来继承 Antergos。今天,我们将着眼于 Antergos 的“精神继承人”之一:EndeavourOS

EndeavourOS 不是 Antergos 的分支

在我们开始之前,我想非常明确地指出,EndeavourOS 并不是一个 Antergos 的复刻版本。开发者们以 Antergos 为灵感,创建了一个基于 Arch 的轻量级发行版。

Endeavouros First Boot

根据 这个项目网站 的说法,EndeavourOS 的诞生是因为 Antergos 社区的人们想要保持 Antergos 的精神。他们的目标很简单:“让 Arch 拥有一个易于使用的安装程序和一个友好、有帮助的社区,在掌握系统的过程中能够有一个社区可以依靠。”

与许多基于 Arch 的发行版不同,EndeavourOS 打算像 原生 Arch 那样使用,“所以没有一键式安装你喜欢的应用程序的解决方案,也没有一堆你最终不需要的预装应用程序。”对于大多数人来说,尤其是那些刚接触 Linux 和 Arch 的人,会有一个学习曲线,但 EndeavourOS 的目标是建立一个大型友好的社区,鼓励人们提出问题并了解他们的系统。

Endeavouros Installing

正在进行的工作

EndeavourOS 在 2019 年 5 月 23 日首次宣布成立 随后 在 7 月 15 日发布第一个版本。不幸的是,这意味着开发人员无法将他们计划的所有功能全部整合进来。(LCTT 译注:本文原文发表于 2019 年,而现在,EndeavourOS 还在持续活跃着。)

例如,他们想要一个类似于 Antergos 的在线安装,但却遇到了当前选项的问题。“Cnchi 运行在 Antergos 生态系统之外会造成严重的问题,需要彻底重写才能发挥作用。RebornOS 的 Fenix 安装程序还没有完全成型,需要更多时间才能正常运行。”于是现在,EndeavourOS 将会和 Calamares 安装程序 一起发布。

EndeavourOS 会提供 比 Antergos 少的东西:它的存储库比 Antergos 小,尽管他们会附带一些 AUR 包。他们的目标是提供一个接近 Arch 却不是原生 Arch 的系统。

Endeavouros Updating With Kalu

开发者进一步声明 :

“Linux,特别是 Arch,核心精神是自由选择,我们提供了一个基本的安装,让你在一个精细的层面上方便地探索各项选择。我们永远不会强行为你作决定,比如为你安装 GUI 应用程序,如 Pamac,甚至采用沙盒解决方案,如 Flatpak 或 Snaps。想安装成什么样子完全取决于你,这是我们与 Antergos 或 Manjaro 的主要区别,但与 Antergos 一样,如果你安装的软件包遇到问题,我们会尽力帮助你。”

体验 EndeavourOS

我在 VirtualBox 中安装了 EndeavourOS,并且研究了一番。当我第一次启动时,我看到一个窗口,里面有关于安装的 EndeavourOS 网站的链接。它还有一个安装按钮和一个手动分区工具。Calamares 安装程序的安装过程非常顺利。

在我重新启动到新安装的 EndeavourOS 之后,迎接我的是一个彩色主题的 XFCE 桌面。我还收到了一堆通知消息。我使用过的大多数基于 Arch 的发行版都带有一个 GUI 包管理器,比如 pamacoctopi,以进行系统更新。EndeavourOS 配有 kalu(kalu 是 “Keeping Arch Linux Up-to-date” 的缩写)。它可以更新软件包、可以看 Archlinux 新闻、可以更新 AUR 包等等。一旦它检查到有更新,它就会显示通知消息。

我浏览了一下菜单,看看默认安装了什么。默认的安装并不多,连办公套件都没有。他们想让 EndeavourOS 成为一块空白画布,让任何人都可以创建他们想要的系统。他们正朝着正确的方向前进。

Endeavouros Desktop

总结思考

EndeavourOS 还很年轻。第一个稳定版本都没有发布多久。它缺少一些东西,最重要的是一个在线安装程序。这就是说,我们无法估计他能够走到哪一步。(LCTT 译注:本文发表于 2019 年)

虽然它不是 Antergos 的精确复刻,但 EndeavourOS 希望复制 Antergos 最重要的部分——热情友好的社区。很多时候,Linux 社区对初学者似乎是不受欢迎甚至是完全敌对的。我看到越来越多的人试图与这种消极情绪作斗争,并将更多的人引入 Linux。随着 EndeavourOS 团队把焦点放在社区建设上,我相信一个伟大的发行版将会诞生。

如果你当前正在使用 Antergos,有一种方法可以让你不用重装系统就切换到 EndeavourOS

如果你想要一个 Antergos 的精确复刻,我建议你去看看 RebornOS。他们目前正在开发一个名为 Fenix 的 Cnchi 安装程序的替代品。

你试过 EndeavourOS 了吗?你的感受如何?


via: https://itsfoss.com/endeavouros/

作者:John Paul 选题:lujun9972 译者:Chao-zhi 校对:wxy

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

通过向一批图像添加效果来学习 GIMP 的脚本语言 Script-Fu。

 title=

前一段时间,我想给方程图片加一个黑板式的外观。我开始是使用 GIMP 来处理的,我对结果很满意。问题是我必须对图像执行几个操作,当我想再次使用此样式,不想对所有图像重复这些步骤。此外,我确信我会很快忘记这些步骤。

 title=

傅立叶变换方程式(Cristiano Fontana,[CC BY-SA 4.0] 4

GIMP 是一个很棒的开源图像编辑器。尽管我已经使用了多年,但从未研究过其批处理功能或 Script-Fu 菜单。这是探索它们的绝好机会。

什么是 Script-Fu?

Script-Fu 是 GIMP 内置的脚本语言。是一种基于 Scheme) 的编程语言。如果你从未使用过 Scheme,请尝试一下,因为它可能非常有用。我认为 Script-Fu 是一个很好的入门方法,因为它对图像处理具有立竿见影的效果,所以你可以很快感觉到自己的工作效率的提高。你也可以使用 Python 编写脚本,但是 Script-Fu 是默认选项。

为了帮助你熟悉 Scheme,GIMP 的文档提供了深入的 教程。Scheme 是一种类似于 Lisp 的语言,因此它的主要特征是使用 前缀 表示法和 许多括号。函数和运算符通过前缀应用到操作数列表中:

(函数名 操作数 操作数 ...)

(+ 2 3)
↳ 返回 5

(list 1 2 3 5)
↳ 返回一个列表,包含 1、 2、 3 和 5

我花了一些时间才找到完整的 GIMP 函数列表文档,但实际上很简单。在 Help 菜单中,有一个 Procedure Browser,其中包含所有可用的函数的丰富详尽文档。

 title=

使用 GIMP 的批处理模式

你可以使用 -b 选项以批处理的方式启动 GIMP。-b 选项的参数可以是你想要运行的脚本,或者用一个 - 来让 GIMP 进入交互模式而不是命令行模式。正常情况下,当你启动 GIMP 的时候,它会启动图形界面,但是你可以使用 -i 选项来禁用它。

开始编写你的第一个脚本

创建一个名为 chalk.scm 的文件,并把它保存在 Preferences 窗口中 Folders 选项下的 Script 中指定的 script 文件夹下。就我而言,是在 $HOME/.config/GIMP/2.10/scripts

chalk.scm 文件中,写入下面的内容:

(define (chalk filename grow-pixels spread-amount percentage)
   (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
          (drawable (car (gimp-image-get-active-layer image)))
          (new-filename (string-append "modified_" filename)))
     (gimp-image-select-color image CHANNEL-OP-REPLACE drawable '(0 0 0))
     (gimp-selection-grow image grow-pixels)
     (gimp-context-set-foreground '(0 0 0))
     (gimp-edit-bucket-fill drawable BUCKET-FILL-FG LAYER-MODE-NORMAL 100 255 TRUE 0 0)
     (gimp-selection-none image)
     (plug-in-spread RUN-NONINTERACTIVE image drawable spread-amount spread-amount)
     (gimp-drawable-invert drawable TRUE)
     (plug-in-randomize-hurl RUN-NONINTERACTIVE image drawable percentage 1 TRUE 0)
     (gimp-file-save RUN-NONINTERACTIVE image drawable new-filename new-filename)
     (gimp-image-delete image)))

定义脚本变量

在脚本中, (define (chalk filename grow-pixels spread-amound percentage) ...) 函数定义了一个名叫 chalk 的新函数。它的函数参数是 filenamegrow-pixelsspread-amoundpercentage。在 define 中的所有内容都是 chalk 函数的主体。你可能已经注意到,那些名字比较长的变量中间都有一个破折号来分割。这是类 Lisp 语言的惯用风格。

(let* ...) 函数是一个特殊 过程 procedure ,可以让你定义一些只有在这个函数体中才有效的临时变量。临时变量有 imagedrawable 以及 new-filename。它使用 gimp-file-load 来载入图片,这会返回它所包含的图片的一个列表。并通过 car 函数来选取第一项。然后,它选择第一个活动层并将其引用存储在 drawable 变量中。最后,它定义了包含图像新文件名的字符串。

为了帮助你更好地了解该过程,我将对其进行分解。首先,启动带 GUI 的 GIMP,然后你可以通过依次点击 Filters → Script-Fu → Console 来打开 Script-Fu 控制台。 在这种情况下,不能使用 let *,因为变量必须是持久的。使用 define 函数定义 image 变量,并为其提供查找图像的正确路径:

(define image (car (gimp-file-load RUN-NONINTERACTIVE "Fourier.png" "Fourier.png")))

似乎在 GUI 中什么也没有发生,但是图像已加载。 你需要通过以下方式来让图像显示:

(gimp-display-new image)

 title=

现在,获取活动层并将其存储在 drawable 变量中:

(define drawable (car (gimp-image-get-active-layer image)))

最后,定义图像的新文件名:

(define new-filename "modified_Fourier.png")

运行命令后,你将在 Script-Fu 控制台中看到以下内容:

 title=

在对图像执行操作之前,需要定义将在脚本中作为函数参数的变量:

(define grow-pixels 2)
(define spread-amount 4)
(define percentage 3)

处理图片

现在,所有相关变量都已定义,你可以对图像进行操作了。 脚本的操作可以直接在控制台上执行。第一步是在活动层上选择黑色。颜色被写成一个由三个数字组成的列表,即 (list 0 0 0) 或者是 '(0 0 0):

(gimp-image-select-color image CHANNEL-OP-REPLACE drawable '(0 0 0))

 title=

扩大选取两个像素:

(gimp-selection-grow image grow-pixels)

 title=

将前景色设置为黑色,并用它填充选区:

(gimp-context-set-foreground '(0 0 0))
(gimp-edit-bucket-fill drawable BUCKET-FILL-FG LAYER-MODE-NORMAL 100 255 TRUE 0 0)

 title=

删除选区:

(gimp-selection-none image)

 title=

随机移动像素:

(plug-in-spread RUN-NONINTERACTIVE image drawable spread-amount spread-amount)

 title=

反转图像颜色:

(gimp-drawable-invert drawable TRUE)

 title=

随机化像素:

(plug-in-randomize-hurl RUN-NONINTERACTIVE image drawable percentage 1 TRUE 0)

 title=

将图像保存到新文件:

(gimp-file-save RUN-NONINTERACTIVE image drawable new-filename new-filename)

 title=

傅立叶变换方程 (Cristiano Fontana, CC BY-SA 4.0)

以批处理模式运行脚本

现在你知道了脚本的功能,可以在批处理模式下运行它:

gimp -i -b '(chalk "Fourier.png" 2 4 3)' -b '(gimp-quit 0)'

在运行 chalk 函数之后,它将使用 -b 选项调用第二个函数 gimp-quit 来告诉 GIMP 退出。

了解更多

本教程向你展示了如何开始使用 GIMP 的内置脚本功能,并介绍了 GIMP 的 Scheme 实现:Script-Fu。如果你想继续前进,建议你查看官方文档及其入门教程。如果你不熟悉 Scheme 或 Lisp,那么一开始的语法可能有点吓人,但我还是建议你尝试一下。这可能是一个不错的惊喜。


via: https://opensource.com/article/21/1/gimp-scripting

作者:Cristiano L. Fontana 选题:lujun9972 译者:amwps290 校对:wxy

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

开始使用现代方法配置 Linux 网络接口。

 title=

在很长一段时间内,ifconfig 命令是配置网络接口的默认方法。它为 Linux 用户提供了很好的服务,但是网络很复杂,所以配置网络的命令必须健壮。ip 命令是现代系统中新的默认网络命令,在本文中,我将向你展示如何使用它。

ip 命令工作在 OSI 网络栈 的两个层上:第二层(数据链路层)和第三层(网络 或 IP)层。它做了之前 net-tools 包的所有工作。

安装 ip

ip 命令包含在 iproute2util 包中,它可能已经在你的 Linux 发行版中安装了。如果没有,你可以从发行版的仓库中进行安装。

ifconfig 和 ip 使用对比

ipifconfig 命令都可以用来配置网络接口,但它们做事方法不同。接下来,作为对比,我将用它们来执行一些常见的任务。

查看网口和 IP 地址

如果你想查看主机的 IP 地址或网络接口信息,ifconfig (不带任何参数)命令提供了一个很好的总结。

$ ifconfig
                                                                                                
eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500                                                                 
       ether bc:ee:7b:5e:7d:d8  txqueuelen 1000  (Ethernet)                                                       
       RX packets 0  bytes 0 (0.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 0  bytes 0 (0.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
       inet 127.0.0.1  netmask 255.0.0.0
       inet6 ::1  prefixlen 128  scopeid 0x10<host>
       loop  txqueuelen 1000  (Local Loopback)
       RX packets 41  bytes 5551 (5.4 KiB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 41  bytes 5551 (5.4 KiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
       inet 10.1.1.6  netmask 255.255.255.224  broadcast 10.1.1.31
       inet6 fdb4:f58e:49f:4900:d46d:146b:b16:7212  prefixlen 64  scopeid 0x0<global>
       inet6 fe80::8eb3:4bc0:7cbb:59e8  prefixlen 64  scopeid 0x20<link>
       ether 08:71:90:81:1e:b5  txqueuelen 1000  (Ethernet)
       RX packets 569459  bytes 779147444 (743.0 MiB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 302882  bytes 38131213 (36.3 MiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

新的 ip 命令提供了类似的结果,但命令是 ip address show,或者简写为 ip a:

$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host  
      valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
   link/ether bc:ee:7b:5e:7d:d8 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
   link/ether 08:71:90:81:1e:b5 brd ff:ff:ff:ff:ff:ff
   inet 10.1.1.6/27 brd 10.1.1.31 scope global dynamic wlan0
      valid_lft 83490sec preferred_lft 83490sec
   inet6 fdb4:f58e:49f:4900:d46d:146b:b16:7212/64 scope global noprefixroute dynamic  
      valid_lft 6909sec preferred_lft 3309sec
   inet6 fe80::8eb3:4bc0:7cbb:59e8/64 scope link  
      valid_lft forever preferred_lft forever

添加 IP 地址

使用 ifconfig 命令添加 IP 地址命令为:

$ ifconfig eth0 add 192.9.203.21

ip 类似:

$ ip address add 192.9.203.21 dev eth0

ip 中的子命令可以缩短,所以下面这个命令同样有效:

$ ip addr add 192.9.203.21 dev eth0

你甚至可以更短些:

$ ip a add 192.9.203.21 dev eth0

移除一个 IP 地址

添加 IP 地址与删除 IP 地址正好相反。

使用 ifconfig,命令是:

$ ifconfig eth0 del 192.9.203.21

ip 命令的语法是:

$ ip a del 192.9.203.21 dev eth0

启用或禁用组播

使用 ifconfig 接口来启用或禁用 组播 multicast

# ifconfig eth0 multicast

对于 ip,使用 set 子命令与设备(dev)以及一个布尔值和 multicast 选项:

# ip link set dev eth0 multicast on

启用或禁用网络

每个系统管理员都熟悉“先关闭,然后打开”这个技巧来解决问题。对于网络接口来说,即打开或关闭网络。

ifconfig 命令使用 updown 关键字来实现:

# ifconfig eth0 up

或者你可以使用一个专用命令:

# ifup eth0

ip 命令使用 set 子命令将网络设置为 updown 状态:

# ip link set eth0 up

开启或关闭地址解析功能(ARP)

使用 ifconfig,你可以通过声明它来启用:

# ifconfig eth0 arp

使用 ip,你可以将 arp 属性设置为 onoff

# ip link set dev eth0 arp on

ip 和 ipconfig 的优缺点

ip 命令比 ifconfig 更通用,技术上也更有效,因为它使用的是 Netlink 套接字,而不是 ioctl 系统调用。

ip 命令可能看起来比 ifconfig 更详细、更复杂,但这是它拥有更多功能的一个原因。一旦你开始使用它,你会了解它的内部逻辑(例如,使用 set 而不是看起来随意混合的声明或设置)。

最后,ifconfig 已经过时了(例如,它缺乏对网络命名空间的支持),而 ip 是为现代网络而生的。尝试并学习它,使用它,你会由衷高兴的!


via: https://opensource.com/article/21/1/ifconfig-ip-linux

作者:Rajan Bhardwaj 选题:lujun9972 译者:MjSeven 校对:wxy

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

通过使用一个简单的游戏来练习一些基本的 JavaScript 概念,迈出创建交互性动态 Web 内容的第一步。

 title=

可以肯定地说,没有 JavaScript,大多数现代 Web 都将不存在。它是三种标准 Web 技术(以及 HTML 和 CSS )之一,它使任何人都可以创建我们在万维网体验中所期待的交互式、动态内容。从 React 这样的框架到 D3 这样的数据可视化库,很难想象没有它的 Web。

现在有很多东西要学习,开始学习这种流行语言的好方法是编写一个简单的应用程序以熟悉某些概念。 最近,一些人写了关于如何通过编写简单的猜谜游戏来学习自己喜欢的语言的文章,因此这是一个很好的起点!

现在开始吧

JavaScript 有许多种风格,但我将从最基本的开始,通常称为 “普通 JavaScript”。 JavaScript 主要是一种客户端脚本语言,因此它可以在任何标准浏览器中运行,而无需安装任何程序。你只需要一个代码编辑器(Brackets 就是一个不错的选择)和一个 Web 浏览器。

HTML 用户界面

JavaScript 在 Web 浏览器中运行,并与其他标准 Web 技术 HTML 和 CSS 交互。要创建此游戏,你首先需要使用 HTML(超文本标记语言)来创建供玩家使用的简单界面。如果你不清楚,HTML 是一种标记语言,用于为 Web 内容提供结构。

首先,先创建一个 HTML 文件。该文件应具有 .html 扩展名,以使浏览器知道它是 HTML 文档。你可以将文件命名为 guessingGame.html

在此文件中使用一些基本的 HTML 标签来显示游戏的标题、玩法说明,供玩家用来输入和提交其猜测的交互式元素以及用于向玩家提供反馈的占位符:

<!DOCTYPE>
  <html>
    <head>
      <meta charset="UTF-8" />
      <title> JavaScript Guessing Game </title>
    </head>
    <body>
      <h1>Guess the Number!</h1>
      <p>I am thinking of a number between 1 and 100. Can you guess what it is?</p>
   
      <label for="guess">My Guess</label>
      <input type="number" id="guess">
      <input type="submit" id="submitGuess" value="Check My Guess">
   
      <p id="feedback"></p>
    </body>
  </html>

<h1><p> 元素使浏览器知道在页面上显示什么类型的文本。标签对 <h1></h1> 表示标签之间的文本(Guess the Number!)是标题。后面的一组 <p> 标签表示带有说明的短文本是一个段落。此代码块末尾的空 <p> 标签用作占位符,用于根据用户的输入提供一些反馈。

<script> 标签

在网页中包含 JavaScript 的方法有很多种,但是对于像这样的简短脚本,可以使用一组 <script> 标签并将 JavaScript 直接写在 HTML 文件中。 这些 <script> 标签应位于 HTML 文件末尾附近的 </body> 标签之前。

现在,你可以开始在这两个脚本标签之间编写 JavaScript。 最终文件如下所示:

<!DOCTYPE>
<html>

<head>
  <meta charset="UTF-8" />
  <title> JavaScript Guessing Game </title>
</head>

<body>
  <h1>Guess the Number!</h1>
  <p>I am thinking of a number between 1 and 100. Can you guess what it is?</p>

  <form>
    <label for="guess">My Guess</label>
    <input type="number" id="guess">
    <input type="submit" id="submitGuess" value="Check My Guess">
  </form>

  <p id="feedback"></p>

  <script>
    const randomNumber = Math.floor(Math.random() * 100) + 1
    console.log('Random Number', randomNumber)

    function checkGuess() {
      let myGuess = guess.value
      if (myGuess === randomNumber) {
        feedback.textContent = "You got it right!"
      } else if (myGuess > randomNumber) {
        feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
      } else if (myGuess < randomNumber) {
       feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
     }
   }
   submitGuess.addEventListener('click', checkGuess)
 </script>

</body>

</html>

要在浏览器中运行此文件,请双击文件或打开你喜欢的浏览器,点击菜单,然后选择文件->打开文件。(如果使用 Brackets 软件,也可以使用角落处的闪电图标在浏览器中打开文件)。

生成伪随机数

猜谜游戏的第一步是为玩家生成一个数字供玩家猜测。JavaScript 包含几个内置的全局对象,可帮助你编写代码。要生成随机数,请使用 Math 对象。

JavaScript中的 Math 具有处理和数学相关的属性和功能。你将使用两个数学函数来生成随机数,供你的玩家猜测。

Math.random(),会将生成一个介于 0 和 1 之间的伪随机数。(Math.random 包含 0 但不包含 1。这意味着该函数可以生成 0 ,永远不会产生 1)

对于此游戏,请将随机数设置在 1 到 100 之间以缩小玩家的选择范围。取刚刚生成的小数,然后乘以 100,以产生一个介于 0 到……甚至不是 100 之间的小数。至此,你将需要其他步骤来解决这个问题。

现在,你的数字仍然是小数,但你希望它是一个整数。为此,你可以使用属于 Math 对象的另一个函数 Math.floor()Math.floor() 的目的是返回小于或等于你作为参数指定的数字的最大整数,这意味着它会四舍五入为最接近的整数:

Math.floor(Math.random() * 100)

这样你将得到 0 到 99 之间的整数,这不是你想要的范围。你可以在最后一步修复该问题,即在结果中加 1。瞧!现在,你有一个(有点)随机生成的数字,介于 1 到 100 之间:

Math.floor(Math.random() * 100) + 1

变量

现在,你需要存储随机生成的数字,以便可以将其与玩家的猜测进行比较。为此,你可以将其存储到一个 变量

JavaScript 具有不同类型的变量,你可以选择这些类型,具体取决于你要如何使用该变量。对于此游戏,请使用 constlet

  • let 用于指示变量在整个程序中可以改变。
  • const 用于指示变量不应该被修改。

constlet 还有很多要说的,但现在知道这些就足够了。

随机数在游戏中仅生成一次,因此你将使用 const 变量来保存该值。你想给变量起一个清楚地表明要存储什么值的名称,因此将其命名为 randomNumber

const randomNumber

有关命名的注意事项:JavaScript 中的变量和函数名称以驼峰形式编写。如果只有一个单词,则全部以小写形式书写。如果有多个单词,则第一个单词均为小写,其他任何单词均以大写字母开头,且单词之间没有空格。

打印到控制台

通常,你不想向任何人显示随机数,但是开发人员可能想知道生成的数字以使用它来帮助调试代码。 使用 JavaScript,你可以使用另一个内置函数 console.log() 将数字输出到浏览器的控制台。

大多数浏览器都包含开发人员工具,你可以通过按键盘上的 F12 键来打开它们。从那里,你应该看到一个 控制台 标签。打印到控制台的所有信息都将显示在此处。由于到目前为止编写的代码将在浏览器加载后立即运行,因此,如果你查看控制台,你应该会看到刚刚生成的随机数!

 title=

函数

接下来,你需要一种方法来从数字输入字段中获得玩家的猜测,将其与你刚刚生成的随机数进行比较,并向玩家提供反馈,让他们知道他们是否正确猜到了。为此,编写一个函数。 函数 是执行一定任务的代码块。函数是可以重用的,这意味着如果你需要多次运行相同的代码,则可以调用函数,而不必重写执行任务所需的所有步骤。

根据你使用的 JavaScript 版本,有许多不同的方法来编写或声明函数。由于这是该语言的基础入门,因此请使用基本函数语法声明函数。

以关键字 function 开头,然后起一个函数名。好的做法是使用一个描述该函数的功能的名称。在这个例子中,你正在检查玩家的猜测的数,因此此函数的名字可以是 checkGuess。在函数名称之后,写上一组小括号,然后写上一组花括号。 你将在以下花括号之间编写函数的主体:

function checkGuess() {}

使用 DOM

JavaScript 的目的之一是与网页上的 HTML 交互。它通过文档对象模型(DOM)进行此操作,DOM 是 JavaScript 用于访问和更改网页信息的对象。现在,你需要从 HTML 中获取数字输入字段中玩家的猜测。你可以使用分配给 HTML 元素的 id 属性(在这种情况下为 guess)来做到这一点:

<input type="number" id="guess">

JavaScript 可以通过访问玩家输入到数字输入字段中的数来获取其值。你可以通过引用元素的 ID 并在末尾添加 .value 来实现。这次,使用 let 定义的变量来保存用户的猜测值:

let myGuess = guess.value

玩家在数字输入字段中输入的任何数字都将被分配给 checkGuess 函数中的 myGuess 变量。

条件语句

下一步是将玩家的猜测与游戏产生的随机数进行比较。你还想给玩家反馈,让他们知道他们的猜测是太高,太低还是正确。

你可以使用一系列条件语句来决定玩家将收到的反馈。条件语句 在运行代码块之前检查是否满足条件。如果不满足条件,则代码停止,继续检查下一个条件,或者继续执行其余代码,而无需执行条件块中的代码:

if (myGuess === randomNumber){
  feedback.textContent = "You got it right!"
}
else if(myGuess > randomNumber) {
  feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
}
else if(myGuess < randomNumber) {
  feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
}

第一个条件块使用比较运算符 === 将玩家的猜测与游戏生成的随机数进行比较。比较运算符检查右侧的值,将其与左侧的值进行比较,如果匹配则返回布尔值 true,否则返回布尔值 false

如果数字匹配(猜对了!),为了让玩家知道。通过将文本添加到具有 id 属性 feedback<p> 标记中来操作 DOM。就像上面的 guess.value 一样,除了不是从 DOM 获取信息,而是更改其中的信息。<p> 元素没有像 <input> 元素那样的值,而是具有文本,因此请使用 .textContent 访问元素并设置要显示的文本:

feedback.textContent = "You got it right!"

当然,玩家很有可能在第一次尝试时就猜错了,因此,如果 myGuessrandomNumber 不匹配,请给玩家一个线索,以帮助他们缩小猜测范围。如果第一个条件失败,则代码将跳过该 if 语句中的代码块,并检查下一个条件是否为 true。 这使你进入 else if 块:

else if(myGuess > randomNumber) {
  feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
}

如果你将其作为句子阅读,则可能是这样的:“如果玩家的猜测等于随机数,请让他们知道他们猜对了。否则,请检查玩家的猜测是否大于 randomNumber,如果是,则显示玩家的猜测并告诉他们太高了。”

最后一种可能性是玩家的猜测低于随机数。 要检查这一点,再添加一个 else if 块:

else if(myGuess < randomNumber) {
  feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
}

用户事件和事件监听器

如果你看上面的代码,则会看到某些代码在页面加载时自动运行,但有些则不会。你想在玩游戏之前生成随机数,但是你不想在玩家将数字输入到数字输入字段并准备检查它之前检查其猜测。

生成随机数并将其打印到控制台的代码不在函数的范围内,因此它将在浏览器加载脚本时自动运行。 但是,要使函数内部的代码运行,你必须对其进行调用。

调用函数有几种方法。在此,你希望该函数在用户单击 “Check My Guess” 按钮时运行。单击按钮将创建一个用户事件,然后 JavaScript 可以 “监听” 这个事件,以便知道何时需要运行函数。

代码的最后一行将事件侦听器添加到按钮上,以在单击按钮时调用函数。当它“听到”该事件时,它将运行分配给事件侦听器的函数:

submitGuess.addEventListener('click', checkGuess)

就像访问 DOM 元素的其他实例一样,你可以使用按钮的 ID 告诉 JavaScript 与哪个元素进行交互。 然后,你可以使用内置的 addEventListener 函数来告诉 JavaScript 要监听的事件。

你已经看到了带有参数的函数,但花点时间看一下它是如何工作的。参数是函数执行其任务所需的信息。并非所有函数都需要参数,但是 addEventListener 函数需要两个参数。它采用的第一个参数是将为其监听的用户事件的名称。用户可以通过多种方式与 DOM 交互,例如键入、移动鼠标,键盘上的 TAB 键和粘贴文本。在这种情况下,你正在监听的用户事件是单击按钮,因此第一个参数将是 click

addEventListener的第二个所需的信息是用户单击按钮时要运行的函数的名称。 这里我们需要 checkGuess 函数。

现在,当玩家按下 “Check My Guess” 按钮时,checkGuess 函数将获得他们在数字输入字段中输入的值,将其与随机数进行比较,并在浏览器中显示反馈,以使玩家知道他们猜的怎么样。 太棒了!你的游戏已准备就绪。

学习 JavaScript 以获取乐趣和收益

这一点点的平凡无奇的 JavaScript 只是这个庞大的生态系统所提供功能的一小部分。这是一种值得花时间投入学习的语言,我鼓励你继续挖掘并学习更多。


via: https://opensource.com/article/21/1/learn-javascript

作者:Mandy Kendall 选题:lujun9972 译者:amwps290 校对:wxy

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