分类 技术 下的文章

介绍

OpenSSL 是一个多功能的命令行工具,可以用于与 公钥基础设施 ( Public Key Infrastructure ) (PKI)和 HTTPS(HTTP over TLS)相关的大量任务。这本小抄风格的指南提供了 OpenSSL 命令的快速参考,这些命令在常见的日常场景中非常有用。这包括生成私钥、 证书签署请求 ( certificate signing request ) (CSR)和证书格式转换的 OpenSSL 示例,但它并没有涵盖 OpenSSL 的所有用途。

如何使用本指南

  • 如果你不熟悉证书签署请求(CSR),请阅读第一部分。
  • 除了第一部分,本指南采用了简单的小抄格式:自带了命令行代码片段。
  • 跳到与你准备完成的任务相关的任何部分。
  • 大多数命令都是单行的,为了清晰起见,已经扩展到多行(使用 \ 符号)。

关于证书签署请求(CSR)

如果你想从 证书颁发机构 ( certificate authority ) (CA)那里获得 SSL 证书,你必须生成一个 证书签署请求 ( certificate signing request ) (CSR)。一个 CSR 主要是由一个密钥对的公钥和一些附加信息组成。当证书被签署时,这两部分都会被插入到证书中。

每当你生成一个 CSR 时,你会被提示提供有关证书的信息。这些信息被称为 区分名称 ( Distinguised Name ) (DN)。DN 中的一个重要字段是 通用名称 ( Common Name ) (CN),它应该是你打算使用证书的主机的 完全合格域名 ( Fully Qualified Domain Name ) (FQDN)。当创建 CSR 时,也可以通过命令行或文件传递信息来跳过交互式提示。

DN 中的其他项目提供了有关你的业务或组织的附加信息。如果你是从证书机构购买 SSL 证书,通常要求这些附加字段(如“ 组织 ( Organization ) ”)准确地反映你的组织的详细信息。

下面是一个 CSR 信息提示的例子:

---
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:Brooklyn
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Brooklyn Company
Organizational Unit Name (eg, section) []:Technology Division
Common Name (e.g. server FQDN or YOUR name) []:examplebrooklyn.com
Email Address []:

如果你想非交互式地回答 CSR 信息提示,你可以通过在任何请求 CSR 信息的 OpenSSL 命令中添加 -subj 选项来实现。这里是该选项的一个例子,使用上面代码块中显示的相同信息:

-subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=examplebrooklyn.com"

现在你已经了解了 CSR,可以自由跳转到本指南中涵盖你的 OpenSSL 需求的任何一节。

生成 CSR

本节介绍了与生成 CSR(以及私钥,如果它们还不存在的话)有关的 OpenSSL 命令。CSR 可以用来向证书颁发机构请求 SSL 证书。

请记住,你可以通过上一节中提到的 -subj 选项非交互式地添加 CSR 信息。

生成一个私钥和一个 CSR

如果你想使用 HTTPS(HTTP over TLS)来保护你的 Apache HTTP 或 Nginx Web 服务器的安全,并且你想使用一个证书颁发机构(CA)来颁发 SSL 证书,那么就使用这个方法。生成的 CSR 可以发送给 CA,请求签发由 CA 签名的 SSL 证书。如果你的 CA 支持 SHA-2,请添加 -sha256 选项,用 SHA-2 签署 CSR。

这条命令从头开始创建一个 2048 位的私钥(domain.key)和一个 CSR(domain.csr):

openssl req \
       -newkey rsa:2048 -nodes -keyout domain.key \
       -out domain.csr

回答 CSR 信息提问,完成该过程。

选项 -newkey rsa:2048 指定密钥应该是 2048 位,使用 RSA 算法生成。选项 -nodes 指定私钥没有用密码加密。这里没有包含 -new 选项,而是隐含在其中,表示正在生成一个 CSR。

从现有的私钥中生成一个 CSR

如果你已经有了私钥,并想用它向 CA 申请证书,请使用这个方法。

该命令基于现有的私钥(domain.key)创建一个新的 CSR(domain.csr):

openssl req \
       -key domain.key \
       -new -out domain.csr

回答 CSR 信息提问,完成该过程。

选项 -key 指定一个现有的私钥(domain.key),它将被用来生成一个新的 CSR。选项 -new 表示正在生成一个 CSR。

从现有的证书和私钥生成 CSR

如果你想更新现有的证书,但由于某些原因,你或你的 CA 没有原始的 CSR,请使用这个方法。基本上可以省去重新输入 CSR 信息的麻烦,因为它是从现有证书中提取信息的。

该命令基于现有的证书(domain.crt)和私钥(domain.key)创建一个新的 CSR(domain.csr):

openssl x509 \
       -in domain.crt \
       -signkey domain.key \
       -x509toreq -out domain.csr

选项 -x509toreq 指定你使用一个 X509 证书来制作 CSR。

生成 SSL 证书

如果你想使用 SSL 证书来确保服务的安全,但你不需要 CA 签名的证书,一个有效的(和免费的)解决方案是签署你自己的证书。

你可以自己签发的一种常见证书是 自签证书 ( self-signed certificate ) 。自签证书是用自己的私钥签署的证书。自签证书和 CA 签名证书一样可以用来加密数据,但是你的用户会显示一个警告,说这个证书不被他们的计算机或浏览器信任。因此,只有当你不需要向用户证明你的服务身份时,才可以使用自签名证书(例如非生产或非公开服务器)。

本节介绍与生成自签名证书相关的 OpenSSL 命令。

生成自签证书

如果你想使用 HTTPS(HTTP over TLS)来保护你的 Apache HTTP 或 Nginx Web 服务器,并且你不需要你的证书由 CA 签名,那么就使用这个方法。

这个命令可以从头开始创建一个 2048 位的私钥(domain.key)和一个自签证书(domain.crt):

openssl req \
       -newkey rsa:2048 -nodes -keyout domain.key \
       -x509 -days 365 -out domain.crt

回答 CSR 信息提问,完成该过程。

选项 -x509 告诉 req 子命令创建一个自签名的证书。-days 365 选项指定证书的有效期为 365 天。它会生成一个临时的 CSR,以收集与证书相关的信息。

从现有私钥生成自签名证书

如果你已经有了一个私钥,并且你想用它来生成一个自签证书,请使用这个方法。

这条命令可以从现有的私钥(domain.key)中创建一个自签证书(domain.crt):

openssl req \
       -key domain.key \
       -new \
       -x509 -days 365 -out domain.crt

回答 CSR 信息提问,完成该过程。

选项 -x509 告诉 req 子命令创建一个自签证书。-days 365 选项指定证书的有效期为 365 天。选项 -new 启用 CSR 信息提问。

从现有的私钥和 CSR 生成自签证书

如果你已经有了私钥和 CSR,并且你想用它们生成一个自签证书,请使用这个方法。

这条命令将从现有的私钥(domain.key)和(domain.csr)中创建一个自签证书(domain.crt)。

openssl x509 \
       -signkey domain.key \
       -in domain.csr \
       -req -days 365 -out domain.crt

选项 -days 365 指定证书的有效期为 365 天。

查看证书

证书和 CSR 文件是以 PEM 格式编码的,不适合被人读取。

本节介绍的 OpenSSL 命令将输出 PEM 编码文件的实际条目。

查看 CSR 条目

该命令允许你查看和验证纯文本的 CSR(domain.csr)的内容:

openssl req \  
       -text -noout -verify \  
       -in domain.csr

查看证书条目

该命令允许你查看纯文本证书(domain.crt)的内容:

openssl x509 \  
       -text -noout \  
       -in domain.crt

验证证书由 CA 签署

使用此命令验证证书(domain.crt)是否由特定的 CA 证书(ca.crt)签署:

openssl verify \  
       -verbose -CAFile ca.crt \  
       domain.crt

私钥

本节介绍了用于创建和验证私钥的 OpenSSL 命令。

创建私钥

使用该命令创建一个受密码保护的 2048 位私钥(domain.key):

openssl genrsa \  
       -des3 -out domain.key 2048

在提示时输入密码以完成该过程。

验证私钥

使用此命令检查私钥(domain.key)是否为有效密钥:

openssl rsa \  
       -check -in domain.key

如果你的私钥已经加密,系统会提示你输入它的密码,成功后,未加密的密钥会在终端上输出。

验证私钥是否与证书和 CSR 匹配

使用这些命令来验证私钥(domain.key)是否匹配证书(domain.crt)和 CSR(domain.csr):

openssl rsa  -noout -modulus -in domain.key | openssl md5
openssl x509 -noout -modulus -in domain.crt | openssl md5
openssl req  -noout -modulus -in domain.csr | openssl md5

如果每条命令的输出都是相同的,那么私钥、证书和 CSR 就极有可能是相关的。

加密私钥

这需要一个未加密的私钥(unencrypted.key),并输出它的加密版本(encrypted.key):

openssl rsa -des3 \
       -in unencrypted.key \
       -out encrypted.key

输入你所需的密码,以加密私钥。

解密私钥

这需要一个加密的私钥(encrypted.key),并输出一个解密的版本(decrypted.key):

openssl rsa \
       -in encrypted.key \
       -out decrypted.key

在提示时,输入加密密钥的密码。

转换证书格式

我们一直在使用的所有证书都是 ASCII 码 PEM 编码的 X.509 证书。还有很多其他的证书编码和容器类型;一些应用程序喜欢某些格式而不是其他格式。此外,这些格式中的许多格式可以在一个文件中包含多个项目,如私钥、证书和 CA 证书。

OpenSSL 可以用来将证书在则西格式间转换。本节将介绍一些可能的转换。

将 PEM 转换为 DER

如果要将 PEM 编码的证书(domain.crt)转换为 DER 编码的证书(domain.der),即二进制格式,请使用此命令:

openssl x509 \
       -in domain.crt \
       -outform der -out domain.der

DER 格式通常与 Java 一起使用。

将 DER 转换为 PEM

如果要将 DER 编码的证书(domain.der)转换为 PEM 编码的证书(domain.crt),请使用此命令:

openssl x509 \
       -inform der -in domain.der \
       -out domain.crt

将 PEM 转换为 PKCS7

如果你想把 PEM 证书(domain.crt 和 ca-chain.crt)添加到 PKCS7 文件(domain.p7b)中,请使用该命令:

openssl crl2pkcs7 -nocrl \
       -certfile domain.crt \
       -certfile ca-chain.crt \
       -out domain.p7b

请注意,你可以使用一个或多个 -certfile 选项来指定要添加到 PKCS7 文件中的证书。

PKCS7 文件,也被称为 P7B,通常用于 Java Keystores 和 Microsoft IIS(Windows)。它们是 ASCII 文件,可以包含证书和 CA 证书。

将 PKCS7 转换为 PEM

如果你想将 PKCS7 文件(domain.p7b)转换为 PEM 文件,请使用该命令:

openssl pkcs7 \
       -in domain.p7b \
       -print_certs -out domain.crt

请注意,如果你的 PKCS7 文件中有多个项目(如证书和 CA 中间证书),创建的 PEM 文件将包含其中的所有项目。

将 PEM 转换为 PKCS12

如果你想使用私钥(domain.key)和证书(domain.crt),并将它们组合成一个 PKCS12 文件(domain.pfx),请使用这个命令:

openssl pkcs12 \
       -inkey domain.key \
       -in domain.crt \
       -export -out domain.pfx

系统会提示你输入导出密码,你可以留空。请注意,在这种情况下,你可以通过将多个证书连接到一个 PEM 文件(domain.crt)中来添加一个证书链到 PKCS12 文件中。

PKCS12 文件,也被称为 PFX 文件,通常用于在 Micrsoft IIS(Windows)中导入和导出证书链。

将 PKCS12 转换为 PEM

如果你想转换 PKCS12 文件(domain.pfx)并将其转换为 PEM 格式(domain.combined.crt),请使用此命令:

openssl pkcs12 \
       -in domain.pfx \
       -nodes -out domain.combined.crt

请注意,如果你的 PKCS12 文件中有多个项目(如证书和私钥),创建的 PEM 文件将包含其中的所有项目。

OpenSSL 版本

openssl version 命令可以用来检查你正在运行的版本。你正在运行的 OpenSSL 版本,以及编译时使用的选项会影响到你可以使用的功能(有时也会影响到命令行选项)。

下面的命令显示了你正在运行的 OpenSSL 版本,以及它被编译时的所有选项:

openssl version -a

本指南是使用具有如下细节的 OpenSSL 二进制文件编写的(参见前面命令的输出):

OpenSSL 1.0.1f 6 Jan 2014
built on: Mon Apr  7 21:22:23 UTC 2014
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"

总结

这应该涵盖了大多数人如何使用 OpenSSL 来处理 SSL 证书的情况!它还有很多其他的用途,在这里没有介绍,所以请在评论中随时询问或建议其他用途。

如果你在使用这些命令时遇到了问题,请一定要评论(并附上你的 OpenSSL 版本输出)。


via: https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs

作者:Mitchell Anicas 选题:wxy 译者:wxy 校对:wxy

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

ethtool 用于查看和修改网络设备(尤其是有线以太网设备)的驱动参数和硬件设置。你可以根据需要更改以太网卡的参数,包括自动协商、速度、双工和局域网唤醒等参数。通过对以太网卡的配置,你的计算机可以通过网络有效地进行通信。该工具提供了许多关于接驳到你的 Linux 系统的以太网设备的信息。

在这篇文章中,我们将告诉你如何更改以下的参数以及如何查看这些参数。这篇文章将帮助你在 Linux 系统中排除与以太网卡相关的问题。

下面的信息将帮助你了解以太网卡的工作原理。

  • 半双工:半双工模式允许设备一次只能发送或接收数据包。
  • 全双工:全双工模式允许设备可以同时发送和接收数据包。
  • 自动协商:自动协商是一种机制,允许设备自动选择最佳网速和工作模式(全双工或半双工模式)。
  • 速度:默认情况下,它会使用最大速度,你可以根据自己的需要改变它。
  • 链接检测:链接检测可以显示网卡的状态。如果显示为 no,请尝试重启网卡。如果链路检测仍显示 no,则检查交换机与系统之间连接的线缆是否有问题。

如何在 Linux 上安装 ethtool

默认情况下,大多数系统上应该已经安装了 ethtool。如果没有,你可以从发行版的官方版本库中安装。

对于 RHEL/CentOS 6/7 系统,请使用 yum 命令 安装 ethtool:

$ sudo yum install -y ethtool

对于 RHEL/CentOS 8 和 Fedora 系统,请使用 dnf 命令 安装 ethtool:

$ sudo dnf install -y ethtool

对于基于 Debian 的系统,请使用 apt 命令 或 apt-get 命令 安装 ethtool:

$ sudo apt-get install ethtool

对于 openSUSE 系统,使用 zypper 命令 安装 ethtool:

$ sudo zypper install -y ethtool

对于 Arch Linux 系统,使用 pacman 命令 安装 ethtool:

$ sudo pacman -S ethtool

如何检查 Linux 上的可用网络接口

你可以使用 ip 命令或 ifconfig 命令(在现代发行版中已被淘汰)来验证可用的、活动的网卡的名称和其他细节:

# ip a
或
# ifconfig

1: lo: 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
2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:10:22:35:23:sf brd ff:ff:ff:ff:ff:ff
    inet 192.164.23.100/24 brd 192.164.23.255 scope global eth0
       valid_lft forever preferred_lft forever

如何检查 Linux 上的网卡(NIC)信息

掌握了以太网卡名称后,就可以使用 ethtool 命令轻松查看其详细信息,如下所示。

在 Linux 系统中,每个网卡(NIC)都被分配了唯一的名称,如 ethX、enpXXX 等。

  • 旧的 Linux 发行版使用的是 eth[X] 格式。例如,RHEL 6 和它们的旧版本。
  • 现代的 Linux 发行版使用 enp[XXX] 或 ens[XXX] 格式。例如,大多数现代 Linux 发行版都使用这种格式,包括 RHEL 7、Debian 10、Ubuntu 16.04 LTS。
# ethtool eth0

Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes: 1000baseT/Full
                              10000baseT/Full
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes: Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 10000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        MDI-X: Unknown
        Supports Wake-on: uag
        Wake-on: d
        Link detected: yes

如何检查以太网卡的驱动程序和固件版本

你可以使用 ethtool 命令的 -i 选项检查驱动程序版本、固件版本和总线的详细信息,如下所示:

# ethtool -i eth0

driver: vmxnet3
version: 1.4.16.0-k-NAPI
firmware-version:
expansion-rom-version:
bus-info: 0000:0b:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no

如何检查网络使用情况统计

你可以使用 ethtool 命令中的 -S 选项来查看网络使用情况统计。它可以显示传输的字节数、接收的字节数、错误数等。

# ethtool -S eth0

NIC statistics:
     Tx Queue#: 0
       TSO pkts tx: 2053
       TSO bytes tx: 7167572
       ucast pkts tx: 4028081
       ucast bytes tx: 399093197
       mcast pkts tx: 0
       mcast bytes tx: 0
       bcast pkts tx: 0
       bcast bytes tx: 0
       pkts tx err: 0
       pkts tx discard: 0
       drv dropped tx total: 0
          too many frags: 0
          giant hdr: 0
          hdr err: 0
          tso: 0
       ring full: 0
       pkts linearized: 0
       hdr cloned: 0
       giant hdr: 0
     Tx Queue#: 1
       TSO pkts tx: 1955
       TSO bytes tx: 6536945
       ucast pkts tx: 3711838
       ucast bytes tx: 346309662
       mcast pkts tx: 0
       mcast bytes tx: 0
       bcast pkts tx: 1186
       bcast bytes tx: 49812
       pkts tx err: 0
       pkts tx discard: 0
       drv dropped tx total: 0
          too many frags: 0
          giant hdr: 0
          hdr err: 0
          tso: 0
       ring full: 0
       pkts linearized: 0
       hdr cloned: 0
       giant hdr: 0
     Rx Queue#: 0
       LRO pkts rx: 0
       LRO byte rx: 0
       ucast pkts rx: 5084776
       ucast bytes rx: 4673133395
       mcast pkts rx: 0
       mcast bytes rx: 0
       bcast pkts rx: 154143
       bcast bytes rx: 45415676
       pkts rx OOB: 0
       pkts rx err: 0
       drv dropped rx total: 0
          err: 0
          fcs: 0
       rx buf alloc fail: 0
     Rx Queue#: 1
       LRO pkts rx: 0
       LRO byte rx: 0
       ucast pkts rx: 6346769
       ucast bytes rx: 4835534292
       mcast pkts rx: 0
       mcast bytes rx: 0
       bcast pkts rx: 3464
       bcast bytes rx: 714646
       pkts rx OOB: 0
       pkts rx err: 0
       drv dropped rx total: 0
          err: 0
          fcs: 0
       rx buf alloc fail: 0
     tx timeout count: 0

如何改变以太网设备的速度

你可以根据需要改变以太网的速度。当你进行此更改时,网卡将自动掉线,你需要使用 ifup 命令 或 ip 命令或 nmcli 命令将其重新上。

# ethtool -s eth0 speed 100
# ip link set eth0 up

如何在 Linux 上启用/禁用以太网卡的自动协商?

你可以使用 ethtool 命令中的 autoneg 选项启用或禁用自动协商,如下图所示:

# ethtool -s eth0 autoneg off
# ethtool -s eth0 autoneg on

如何同时更改多个参数

如果你想使用 ethtool 命令同时更改以太网卡的多个参数,请使用下面的格式:

Syntax:
ethtool –s [device_name] speed [10/100/1000] duplex [half/full] autoneg [on/off]
# ethtool –s eth0 speed 1000 duplex full autoneg off

如何检查特定网卡的自动协商、RX 和 TX

要查看关于特定以太网设备的自动协商等详细信息,请使用以下格式:

# ethtool -a eth0

如何从多个设备中识别出特定的网卡(闪烁网卡上的 LED)

如果你想识别一个特定的物理接口,这个选项非常有用。下面的 ethtool 命令会使 eth0 端口的 LED 灯闪烁:

# ethtool -p eth0

如何在 Linux 中永久设置这些参数

在系统重启后,你使用 ethtool 所做的更改将被默认恢复。

要使自定义设置永久化,你需要更新网络配置文件中的值。根据你的 Linux 发行版,你可能需要将此值更新到正确的文件中。

对于基于 RHEL 的系统。你必须使用 ETHTOOL_OPTS 变量:

# vi /etc/sysconfig/network-scripts/ifcfg-eth0

ETHTOOL_OPTS="speed 1000 duplex full autoneg off"

对于基于 Debian 的系统:

# vi /etc/network/interfaces

post-up ethtool -s eth0 speed 1000 duplex full autoneg off

via: https://www.2daygeek.com/linux-ethtool-command-view-change-ethernet-adapter-settings-nic-card/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:wxy 校对:wxy

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

制作一个 GIF 可能是一件很有趣的事,很多用户可能都想如何制作一个 GIF。你可以使用功能强大的开源图像编辑软件 GIMP 创建一个非常简单的 GIF。

在这篇 GIMP 教程中,我将向你展示如何在 GIMP 中创建一个简单的 GIF。

在 GIMP 中制作一个 GIF

使用 GIMP 作为一个动画制作工具需要你把每个图层都看作动画的一帧。在这篇教程中,我将创建一个简单的基于我们的徽标的网页横幅。我将使用 2 个图像作为我的图层,但当你制作自己的 GIF 时,你可以随意添加更多的图像。

我在这里使用的方法叫做“组合法”,在这个方法中,新的帧被添加到先前的帧中。我的想法是制作一个“频闪”的网页横幅,来在对一些重要的事情引起注意。

我假设你已经 在 Ubuntu 或其它使用的操作系统中安装了 GIMP。让我们开始制作 GIF 吧。

步骤 1

从“文件”菜单中,单击“作为图层打开”,并选择你想包含在 GIF 中的所有图像。然后单击“打开”。

你可以排序图层标签页中的图像。GIF 的帧序列将从最下面的图层开始,从下到上运行每一层图层。

从主菜单中选择“滤镜”,接着选择“动画”,最后单击“优化(用于 GIF)”。

“优化”做了什么?

优化会检查每一个图层,如果来自前一帧的信息在下一帧中没有改变,则重复使用这些信息。它只存储新更改的像素值,并清除任何重复的部分。

如果一帧与前一帧完全相同,那么它将完全删除这一幅帧,并且前一帧将恰当地在屏幕上停留更长时间。

要查看该 GIF,从主菜单中单击“滤镜”,接着单击“动画”和“回放”。

按下“回放”按钮来启动 GIF。要保存该 GIF,在文件菜单上选择“文件”,单击“导出为”。

命名你的 GIF,并选择你想将其保存到的文件夹。在“选择文件类型”时,选择 “GIF 图像”。

当提示时,选择“作为动画”、“反复循环”,设置期望的延迟值,并单击“上面输入的延迟用于所有帧”来生效。

最重要的选项是设置帧处理动作为“累积各图层(组合)”,以便为我们的横幅获取“频闪”效果。单击“导出”作为最后一个步骤。

你的 GIF 已经准备好了!

这是一个浅显易懂的示例,不过 GIMP 在动画创作方面有很多能力,需要大量的学习和实践才能掌握它。


via: https://itsfoss.com/make-gif-in-gimp/

作者:Dimitrios Savvopoulos 选题:lujun9972 译者:robsean 校对:wxy

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

借鉴 C 语言的历史,学习如何用 Python 编写有用的 CLI 程序。

本文的目标很简单:帮助新的 Python 开发者了解一些关于命令行接口(CLI)的历史和术语,并探讨如何在 Python 中编写这些有用的程序。

最初……

首先,从 Unix 的角度谈谈命令行界面设计。

Unix 是一种计算机操作系统,也是 Linux 和 macOS(以及许多其他操作系统)的祖先。在图形用户界面之前,用户通过命令行提示符与计算机进行交互(想想如今的 Bash 环境)。在 Unix 下开发这些程序的主要语言是 C),它的功能非常强大。

因此,我们至少应该了解 C 程序的基础知识。

假设你没有读过上面那个链接的内容,C 程序的基本架构是一个叫做 main 的函数,它的签名是这样的。

   int main(int argc, char **argv)
   {
   ...
   }

对于 Python 程序员来说,这应该不会显得太奇怪。C 函数首先有一个返回类型、一个函数名,然后是括号内的类型化参数。最后,函数的主体位于大括号之间。函数名 main 是运行时链接器(构造和运行程序的程序)如何决定从哪里开始执行你的程序。如果你写了一个 C 程序,而它没有包含一个名为 main 的函数,它将什么也做不了。伤心。

函数参数变量 argc 和 argv 共同描述了程序被调用时用户在命令行输入的字符串列表。在典型的 Unix 命名传统中,argc 的意思是“ 参数计数 argument count ”,argv 的意思是“ 参数向量 argument vector ”。向量听起来比列表更酷,而 argl 听起来就像一个要勒死的求救声。我们是 Unix 系统的程序员,我们不求救。我们让其他人哭着求救。

再进一步

$ ./myprog foo bar -x baz

如果 myprog 是用 C 语言实现的,则 argc 的值是 5,而 argv 是一个有五个条目的字符指针数组。(不要担心,如果这听起来过于技术,那换句话说,这是一个由五个字符串组成的列表。)向量中的第一个条目 argv[0] 是程序的名称。argv 的其余部分包含参数。

   argv[0] == "./myprog"
   argv[1] == "foo"
   argv[2] == "bar"
   argv[3] == "-x"
   argv[4] == "baz"
   
   /* 注:不是有效的 C 代码 */

在 C 语言中,你有很多方法来处理 argv 中的字符串。你可以手动地循环处理数组 argv,并根据程序的需要解释每个字符串。这相对来说比较简单,但会导致程序的接口大相径庭,因为不同的程序员对什么是“好”有不同的想法。

include <stdio.h>

/* 一个打印 argv 内容的简单 C 程序。 */

int main(int argc, char **argv) {
    int i;
   
    for(i=0; i<argc; i++)
      printf("%s\n", argv[i]);
}

早期对命令行标准化的尝试

命令行武器库中的下一个武器是一个叫做 getopt 的 C 标准库函数。这个函数允许程序员解析开关,即前面带破折号的参数(比如 -x),并且可以选择将后续参数与它们的开关配对。想想 /bin/ls -alSh 这样的命令调用,getopt 就是最初用来解析该参数串的函数。使用 getopt 使命令行的解析变得相当简单,并改善了用户体验(UX)。

include <stdio.h>
#include <getopt.h>

#define OPTSTR "b:f:"

extern char *optarg;

int main(int argc, char **argv) {
    int opt;
    char *bar = NULL;
    char *foo = NULL;
   
    while((opt=getopt(argc, argv, OPTSTR)) != EOF)
       switch(opt) {
          case 'b':
              bar = optarg;
              break;
          case 'f':
              foo = optarg;
              break;
          case 'h':
          default':
              fprintf(stderr, "Huh? try again.");
              exit(-1);
              /* NOTREACHED */
       }
    printf("%s\n", foo ? foo : "Empty foo");
    printf("%s\n", bar ? bar : "Empty bar");
}

就个人而言,我希望 Python 有开关,但这永远、永远不会发生。

GNU 时代

GNU 项目出现了,并为他们实现的传统 Unix 命令行工具引入了更长的格式参数,比如--file-format foo。当然,我们这些 Unix 程序员很讨厌这样,因为打字太麻烦了,但是就像我们这些旧时代的恐龙一样,我们输了,因为用户喜欢更长的选项。我从来没有写过任何使用 GNU 风格选项解析的代码,所以这里没有代码示例。

GNU 风格的参数也接受像 -f foo 这样的短名,也必须支持。所有这些选择都给程序员带来了更多的工作量,因为他们只想知道用户要求的是什么,然后继续进行下去。但用户得到了更一致的用户体验:长格式选项、短格式选项和自动生成的帮助,使用户不必再试图阅读臭名昭著的难以解析的手册页面(参见 ps 这个特别糟糕的例子)。

但我们正在讨论 Python?

你现在已经接触了足够多(太多?)的命令行的历史,对如何用我们最喜欢的语言来编写 CLI 有了一些背景知识。Python 在命令行解析方面给出了类似的几个选择:自己解析, 自给自足 batteries-included 的方式,以及大量的第三方方式。你选择哪一种取决于你的特定情况和需求。

首先,自己解析

你可以从 sys 模块中获取程序的参数。

import sys

if __name__ == '__main__':
   for value in sys.argv:
       print(value)

自给自足

在 Python 标准库中已经有几个参数解析模块的实现:getopt、optparse,以及最近的 argparse。argparse 允许程序员为用户提供一致的、有帮助的用户体验,但就像它的 GNU 前辈一样,它需要程序员做大量的工作和“模板代码”才能使它“奏效”。

from argparse import ArgumentParser

if __name__ == "__main__":

   argparser = ArgumentParser(description='My Cool Program')
   argparser.add_argument("--foo", "-f", help="A user supplied foo")
   argparser.add_argument("--bar", "-b", help="A user supplied bar")
   
   results = argparser.parse_args()
   print(results.foo, results.bar)

好处是当用户调用 --help 时,有自动生成的帮助。但是 自给自足 batteries included 的优势呢?有时,你的项目情况决定了你对第三方库的访问是有限的,或者说是没有,你不得不用 Python 标准库来“凑合”。

CLI 的现代方法

然后是 Click。Click 框架使用装饰器的方式来构建命令行解析。突然间,写一个丰富的命令行界面变得有趣而简单。在装饰器的酷炫和未来感的使用下,很多复杂的东西都消失了,用户惊叹于自动支持关键字补完以及上下文帮助。所有这些都比以前的解决方案写的代码更少。任何时候,只要你能写更少的代码,还能把事情做好,就是一种胜利。而我们都想要胜利。

import click

@click.command()
@click.option("-f", "--foo", default="foo", help="User supplied foo.")
@click.option("-b", "--bar", default="bar", help="User supplied bar.")
def echo(foo, bar):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    echo()

你可以在 @click.option 装饰器中看到一些与 argparse 相同的模板代码。但是创建和管理参数分析器的“工作”已经被抽象化了。现在,命令行参数被解析,而值被赋给函数参数,从而函数 echo 被魔法般地调用。

在 Click 接口中添加参数就像在堆栈中添加另一个装饰符并将新的参数添加到函数定义中一样简单。

但是,等等,还有更多!

Typer 建立在 Click 之上,是一个更新的 CLI 框架,它结合了 Click 的功能和现代 Python 类型提示。使用 Click 的缺点之一是必须在函数中添加一堆装饰符。CLI 参数必须在两个地方指定:装饰符和函数参数列表。Typer 免去你造轮子 去写 CLI 规范,让代码更容易阅读和维护。

import typer

cli = typer.Typer()

@cli.command()
def echo(foo: str = "foo", bar: str = "bar"):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    cli()

是时候开始写一些代码了

哪种方法是正确的?这取决于你的用例。你是在写一个只有你才会使用的快速而粗略的脚本吗?直接使用 sys.argv 然后继续编码。你需要更强大的命令行解析吗?也许 argparse 就够了。你是否有很多子命令和复杂的选项,你的团队是否会每天使用它?现在你一定要考虑一下 Click 或 Typer。作为一个程序员的乐趣之一就是魔改出替代实现,看看哪一个最适合你。

最后,在 Python 中有很多用于解析命令行参数的第三方软件包。我只介绍了我喜欢或使用过的那些。你喜欢和/或使用不同的包是完全可以的,也是我们所期望的。我的建议是先从这些包开始,然后看看你最终的结果。

去写一些很酷的东西吧。


via: https://opensource.com/article/20/6/c-python-cli

作者:Erik O'Shaughnessy 选题:lujun9972 译者:wxy 校对:wxy

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

你可能忘记了删除计算机上某个目录中不再需要的文件的操作。这可能是“下载”或任何其他目录。它可能已经增长了一段时间。

即便有足够的存储空间,你也应该删除它们,因为这会在列出文件时降低系统速度。同样,当一个目录中有成千上万个文件时,它可能很会很臃肿。

当你不知道要检查的文件名时,很难在特定目录中找到文件。

我们可以通过结合使用 find 命令和一些组合来做到这一点,我们过去已经写过一篇文章。

今天,我们将向你展示如何在 Linux 上使用 Tmpwatch 程序来实现这一目标。

什么是 tmpwatch

tmpwatch 会在指定目录中递归删除指定时间段内未被访问的文件。通常,它用于自动清除临时文件系统目录,例如 /tmp 和 /var/tmp。

它只会删除空目录、常规文件和符号链接。它不会切换到其他文件系统,并避开了属于根用户的 lost+found 目录。

默认情况下,tmpwatch 会根据文件的 atime(访问时间)而不是 mtime(修改时间)删除文件。

你可以在 tmpwatch 命令中添加其他参数来更改这些行为。

警告: 请不要在 / 中运行 tmpwatch 或 tmpreaper,因为该程序中没有防止这种情况的机制。

如何在 Linux 上安装 tmpwatch

可以在官方仓库中按以下方式安装 tmpwatch。

对于 RHEL/CentOS 6 系统,请使用 yum 命令安装 tmpwatch。

$ sudo yum install -y tmpwatch

对于 Debian 和 Ubuntu 系统,请使用 apt 命令 或 apt-get 命令 安装 tmpreaper。

$ sudo apt-get install tmpreaper

对于 openSUSE 系统,请使用 zypper 命令 安装 tmpwatch。

$ sudo zypper install -y tmpwatch

对于 Fedora 系统,请使用 dnf 命令 安装 tmpwatch。

$ sudo dnf install -y tmpwatch

请注意: 如果你使用的是基于 Debian 的系统,请使用 tmpreaper 而不是 tmpwatch。所有示例都可以如预期工作。

了解关键选项和参数

  • atime(文件上次访问时间):显示命令或脚本等任意进程最后一次访问文件中数据的时间。
  • mtime(文件上次修改时间):显示修改文件内容或保存文件的时间。除非是更改文件属性,否则大多数情况下 ctime 和 mtime 会相同。
  • ctime(文件上次更改时间):显示文件元数据更改时间。这意味着更改文件属性的时间(如所有权或组等)。
  • dirmtime(目录的上次修改时间):显示目录的上一次修改时间。

时间参数定义删除文件的阈值。

  • d – 天
  • h – 小时
  • m – 分钟
  • s – 秒

如何使用 tmpwatch 命令删除一段时间未访问的文件

正如我在本文开头所说,tmpwatch 默认根据文件访问时间(atime)来删除文件。另外,由于小时是默认参数,因此如果使用小时单位,那么无需在时间上添加后缀。

例如,运行以下命令以递归方式删除过去 5 个小时未访问的文件。

# tmpwatch 5 /tmp

运行以下命令删除最近 10 个小时未修改的文件。如果要使用修改时间(mtime)来删除文件,那么需要在 tmpwatch 命令中添加 -m 选项。

# tmpwatch -m 10 /home/daygeek/Downloads

如何使用 tmpwatch 命令删除超过 “X” 天未访问的文件

如果要使用天数删除文件,那么需要添加后缀 d。以下示例删除了 30 天以上的文件。

# tmpwatch 30d /home/daygeek/Downloads

如何使用 tmpwatch 命令删除一段时间内未访问的所有文件

以下命令将基于修改时间(mtime)删除所有类型的文件,而不仅仅是常规文件、符号链接和目录。

# tmpwatch -am 12 /tmp

如何在 tmpwatch 中排除目录

以下命令将删除过去 10 个小时未修改的所有文件,并排除目录。

# tmpwatch -am 10 --nodirs /home/daygeek/Downloads

如何在 tmpwatch 中排除特定路径

以下命令将删除过去 10 个小时未被修改的所有文件,除了下面排除的文件夹。

# tmpwatch -am 10 --exclude=/home/daygeek/Downloads/Movies /home/daygeek/Downloads

如何在 tmpwatch 中排除特定模式

以下命令将删除过去 10 小时未被修改的所有文件,除了满足下面列出的模式的文件。

# tmpwatch -am 10 --exclude-pattern='*.pdf' /home/daygeek/Downloads

如何让 tmpwatch 命令空运行

如果要空运行,请运行以下命令。

# tmpwatch -t 5h /home/daygeek/Downloads

如何设置 cronjob 来使用 tmpwatch 定期删除文件

默认情况下,它在 /etc/cron.daily/tmpreaper 目录下有一个 cronjob 文件。该 cronjob 根据位于 /etc/timereaper.conf 中的配置文件工作。你可以根据需要自定义文件。

它每天运行一次,并删除 7 天之前的文件。

另外,如果你希望常规执行某项操作,那么可以根据需要手动添加一个 cronjob。

# crontab -e

0 10 * * * /usr/sbin/tmpwatch 15d /home/daygeek/Downloads

上面的 cronjob 将在每天上午 10 点删除早于 15 天的文件。


via: https://www.2daygeek.com/how-to-remove-files-older-than-n-days-using-tmpwatch-tmpreaper-on-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:geekpi 校对:wxy

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

FastAPI 是一个使用 Python 编写的 Web 框架,还应用了 Python asyncio 库中最新的优化。本文将会介绍如何搭建基于容器的开发环境,还会展示如何使用 FastAPI 实现一个小型 Web 服务。

起步

我们将使用 Fedora 作为基础镜像来搭建开发环境,并使用 Dockerfile 为镜像注入 FastAPI、Uvicorn 和 aiofiles 这几个包。

FROM fedora:32
RUN dnf install -y python-pip \
    && dnf clean all \
    && pip install fastapi uvicorn aiofiles
WORKDIR /srv
CMD ["uvicorn", "main:app", "--reload"]

在工作目录下保存 Dockerfile 之后,执行 podman 命令构建容器镜像。

$ podman build -t fastapi .
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/fastapi latest 01e974cabe8b 18 seconds ago 326 MB

下面我们可以开始创建一个简单的 FastAPI 应用程序,并通过容器镜像运行。

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello Fedora Magazine!"}

将上面的代码保存到 main.py 文件中,然后执行以下命令开始运行:

$ podman run --rm -v $PWD:/srv:z -p 8000:8000 --name fastapi -d fastapi
$ curl http://127.0.0.1:8000
{"message":"Hello Fedora Magazine!"

这样,一个基于 FastAPI 的 Web 服务就跑起来了。由于指定了 --reload 参数,一旦 main.py 文件发生了改变,整个应用都会自动重新加载。你可以尝试将返回信息 "Hello Fedora Magazine!" 修改为其它内容,然后观察效果。

可以使用以下命令停止应用程序:

$ podman stop fastapi

构建一个小型 Web 服务

接下来我们会构建一个需要 I/O 操作的应用程序,通过这个应用程序,我们可以看到 FastAPI 自身的特点,以及它在性能上有什么优势(可以在这里参考 FastAPI 和其它 Python Web 框架的对比)。为简单起见,我们直接使用 dnf history 命令的输出来作为这个应用程序使用的数据。

首先将 dnf history 命令的输出保存到文件。

$ dnf history | tail --lines=+3 > history.txt

在上面的命令中,我们使用 tail 去除了 dnf history 输出内容中无用的表头信息。剩余的每一条 dnf 事务都包括了以下信息:

  • id:事务编号(每次运行一条新事务时该编号都会递增)
  • command:事务中运行的 dnf 命令
  • date:执行事务的日期和时间

然后修改 main.py 文件将相关的数据结构添加进去。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class DnfTransaction(BaseModel):
    id: int
    command: str
    date: str

FastAPI 自带的 pydantic 库让你可以轻松定义一个数据类,其中的类型注释对数据的验证也提供了方便。

再增加一个函数,用于从 history.txt 文件中读取数据。

import aiofiles

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class DnfTransaction(BaseModel):
    id: int
    command: str
    date: str


async def read_history():
    transactions = []
    async with aiofiles.open("history.txt") as f:
        async for line in f:
            transactions.append(DnfTransaction(
                id=line.split("|")[0].strip(" "),
                command=line.split("|")[1].strip(" "),
                date=line.split("|")[2].strip(" ")))
    return transactions

这个函数中使用了 aiofiles 库,这个库提供了一个异步 API 来处理 Python 中的文件,因此打开文件或读取文件的时候不会阻塞其它对服务器的请求。

最后,修改 root 函数,让它返回事务列表中的数据。

@app.get("/")
async def read_root():
    return await read_history()

执行以下命令就可以看到应用程序的输出内容了。

$ curl http://127.0.0.1:8000 | python -m json.tool
[
{
"id": 103,
"command": "update",
"date": "2020-05-25 08:35"
},
{
"id": 102,
"command": "update",
"date": "2020-05-23 15:46"
},
{
"id": 101,
"command": "update",
"date": "2020-05-22 11:32"
},
....
]

总结

FastAPI 提供了一种使用 asyncio 构建 Web 服务的简单方法,因此它在 Python Web 框架的生态中日趋流行。要了解 FastAPI 的更多信息,欢迎查阅 FastAPI 文档。

本文中的代码可以在 GitHub 上找到。


via: https://fedoramagazine.org/use-fastapi-to-build-web-services-in-python/

作者:Clément Verna 选题:lujun9972 译者:HankChow 校对:wxy

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