分类 技术 下的文章

这篇文章介绍了 testdisk,这是恢复最近删除的文件(以及用其他方式修复分区)的工具之一,非常方便。

当你在 Linux 系统上删除一个文件时,它不一定会永远消失,特别是当你最近才刚刚删除了它的时候。

除非你用 shred 等工具把它擦掉,否则数据仍然会放在你的磁盘上 —— 而恢复已删除文件的最佳工具之一 testdisk 可以帮助你拯救它。虽然 testdisk 具有广泛的功能,包括恢复丢失或损坏的分区和使不能启动磁盘可以重新启动,但它也经常被用来恢复被误删的文件。

在本篇文章中,我们就来看看如何使用 testdisk 恢复已删除的文件,以及该过程中的每一步是怎样的。由于这个过程需要不少的步骤,所以当你做了几次之后,你可能会觉得操作起来会更加得心应手。

安装 testdisk

可以使用 apt install testdiskyum install testdisk 等命令安装 testdisk。有趣的是,它不仅是一个 Linux 工具,而且还适用于 MacOS、Solaris 和 Windows。

文档可在 cgsecurity.org 中找到。

恢复文件

首先,你必须以 root 身份登录,或者有 sudo 权限才能使用 testdisk。如果你没有 sudo 访问权限,你会在这个过程一开始就被踢出,而如果你选择创建了一个日志文件的话,最终会有这样的消息:

TestDisk exited normally.
jdoe is not in the sudoers file.  This incident will be reported.

当你用 testdisk 恢复被删除的文件时,你最终会将恢复的文件放在你启动该工具的目录下,而这些文件会属于 root。出于这个原因,我喜欢在 /home/recovery 这样的目录下启动。一旦文件被成功地还原和验证,就可以将它们移回它们的所属位置,并将它们的所有权也恢复。

在你可以写入的选定目录下开始:

$ cd /home/recovery
$ testdisk

testdisk 提供的第一页信息描述了该工具并显示了一些选项。至少在刚开始,创建个日志文件是个好主意,因为它提供的信息可能会被证明是有用的。下面是如何做的:

Use arrow keys to select, then press Enter key:
>[ Create ] Create a new log file
 [ Append ] Append information to log file
 [ No Log ] Don’t record anything

左边的 > 以及你看到的反转的字体和背景颜色指出了你按下回车键后将使用的选项。在这个例子中,我们选择了创建日志文件。

然后会提示你输入密码(除非你最近使用过 sudo)。

下一步是选择被删除文件所存储的磁盘分区(如果没有高亮显示的话)。根据需要使用上下箭头移动到它。然后点两次右箭头,当 “Proceed” 高亮显示时按回车键。

Select a media (use Arrow keys, then press Enter):
 Disk /dev/sda - 120 GB / 111 GiB - SSD2SC120G1CS1754D117-551
>Disk /dev/sdb - 500 GB / 465 GiB - SAMSUNG HE502HJ
 Disk /dev/loop0 - 13 MB / 13 MiB (RO)
 Disk /dev/loop1 - 101 MB / 96 MiB (RO)
 Disk /dev/loop10 - 148 MB / 141 MiB (RO)
 Disk /dev/loop11 - 36 MB / 35 MiB (RO)
 Disk /dev/loop12 - 52 MB / 49 MiB (RO)
 Disk /dev/loop13 - 78 MB / 75 MiB (RO)
 Disk /dev/loop14 - 173 MB / 165 MiB (RO)
 Disk /dev/loop15 - 169 MB / 161 MiB (RO)
>[Previous]  [  Next  ]  [Proceed ]  [  Quit  ]

在这个例子中,被删除的文件在 /dev/sdb 的主目录下。

此时,testdisk 应该已经选择了合适的分区类型。

Disk /dev/sdb - 500 GB / 465 GiB - SAMSUNG HE502HJ

Please select the partition table type, press Enter when done.
 [Intel  ] Intel/PC partition
>[EFI GPT] EFI GPT partition map (Mac i386, some x86_64...)
 [Humax  ] Humax partition table
 [Mac    ] Apple partition map (legacy)
 [None   ] Non partitioned media
 [Sun    ] Sun Solaris partition
 [XBox   ] XBox partition
 [Return ] Return to disk selection

在下一步中,按向下箭头指向 “[ Advanced ] Filesystem Utils”。

[ Analyse  ] Analyse current partition structure and search for lost partitions
>[ Advanced ] Filesystem Utils
 [ Geometry ] Change disk geometry
 [ Options  ] Modify options
 [ Quit     ] Return to disk selection

接下来,查看选定的分区。

Partition                  Start        End    Size in sectors
> 1 P Linux filesys. data         2048  910155775  910153728 [drive2]

然后按右箭头选择底部的 “[ List ]”,按回车键。

[  Type  ]  [Superblock] >[  List  ]  [Image Creation]  [  Quit  ]

请注意,它看起来就像我们从根目录 / 开始,但实际上这是我们正在工作的文件系统的基点。在这个例子中,就是 /home

Directory /   <== 开始点

>drwxr-xr-x     0     0      4096 23-Sep-2020 17:46 .
 drwxr-xr-x     0     0      4096 23-Sep-2020 17:46 ..
 drwx———     0     0     16384 22-Sep-2020 11:30 lost+found
 drwxr-xr-x  1008  1008      4096  9-Jul-2019 14:10 dorothy
 drwxr-xr-x  1001  1001      4096 22-Sep-2020 12:12 nemo
 drwxr-xr-x  1005  1005      4096 19-Jan-2020 11:49 eel
 drwxrwxrwx     0     0      4096 25-Sep-2020 08:08 recovery
...

接下来,我们按箭头指向具体的主目录。

drwxr-xr-x  1016  1016      4096 17-Feb-2020 16:40 gino
>drwxr-xr-x  1000  1000     20480 25-Sep-2020 08:00 shs

按回车键移动到该目录,然后根据需要向下箭头移动到子目录。注意,如果选错了,可以选择列表顶部附近的 .. 返回。

如果找不到文件,可以按 /(就像在 vi 中开始搜索时一样),提示你输入文件名或其中的一部分。

Directory /shs     <== current location
                                                   Previous
...
 -rw-rw-r—  1000  1000       426  8-Apr-2019 19:09 2-min-topics
>-rw-rw-r—  1000  1000     24667  8-Feb-2019 08:57 Up_on_the_Roof.pdf

一旦你找到需要恢复的文件,按 c 选择它。

注意:你会在屏幕底部看到有用的说明:

Use Left arrow to go back, Right to change directory, h to hide deleted files
    q to quit, : to select the current file, a to select all files
    C to copy the selected files, c to copy the current file <==

这时,你就可以在起始目录内选择恢复该文件的位置了(参见前面的说明,在将文件移回原点之前,先在一个合适的地方进行检查)。在这种情况下,/home/recovery 目录没有子目录,所以这就是我们的恢复点。

注意:你会在屏幕底部看到有用的说明:

Please select a destination where /shs/Up_on_the_Roof.pdf will be copied.
Keys: Arrow keys to select another directory
      C when the destination is correct
      Q to quit
Directory /home/recovery    <== 恢复位置

一旦你看到 “Copy done! 1 ok, 0 failed” 的绿色字样,你就会知道文件已经恢复了。

在这种情况下,文件被留在 /home/recovery/shs 下(起始目录,附加所选目录)。

在将文件移回原来的位置之前,你可能应该先验证恢复的文件看起来是否正确。确保你也恢复了原来的所有者和组,因为此时文件由 root 拥有。

注意: 对于文件恢复过程中的很多步骤,你可以使用退出(按 q 或“[ Quit ]”)来返回上一步。如果你愿意,可以选择退出选项一直回到该过程中的第一步,也可以选择按下 ^c 立即退出。

恢复训练

使用 testdisk 恢复文件相对来说没有痛苦,但有些复杂。在恐慌时间到来之前,最好先练习一下恢复文件,让自己有机会熟悉这个过程。


via: https://www.networkworld.com/article/3575524/recovering-deleted-files-on-linux-with-testdisk.html

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

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

扩展逻辑卷非常简单,只需要很少的步骤,而且不需要卸载某个逻辑卷就可以在线完成。

LVM 的主要目的是灵活的磁盘管理,当你需要的时候,可以很方便地调整、扩展和缩小逻辑卷的大小。

如果你是逻辑卷管理(LVM) 新手,我建议你从我们之前的文章开始学习。

扩展逻辑卷涉及到以下步骤:

  • 检查逻辑卷(LV)所在的卷组中是否有足够的未分配磁盘空间
  • 如果有,你可以使用这些空间来扩展逻辑卷
  • 如果没有,请向系统中添加新的磁盘或 LUN
  • 将物理磁盘转换为物理卷(PV)
  • 扩展卷组
  • 增加逻辑卷大小
  • 扩大文件系统
  • 检查扩展的文件系统大小

如何创建 LVM 物理卷?

使用 pvcreate 命令创建 LVM 物理卷。

当在操作系统中检测到磁盘,使用 pvcreate 命令初始化 LVM 物理卷:

# pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created

请注意:

  • 上面的命令将删除磁盘 /dev/sdc 上的所有数据。
  • 物理磁盘可以直接添加到 LVM 物理卷中,而不是磁盘分区。

使用 pvdisplay 命令来显示你所创建的物理卷:

# pvdisplay /dev/sdc

"/dev/sdc" is a new physical volume of "10.00 GiB"
--- NEW Physical volume ---
PV Name               /dev/sdc
VG Name
PV Size               10.00 GiB
Allocatable           NO
PE Size               0
Total PE              0
Free PE               0
Allocated PE          0
PV UUID               69d9dd18-36be-4631-9ebb-78f05fe3217f

如何扩展卷组

使用以下命令在现有的卷组(VG)中添加一个新的物理卷:

# vgextend vg01 /dev/sdc
Volume group "vg01" successfully extended

使用 vgdisplay 命令来显示你所创建的物理卷:

# vgdisplay vg01
--- Volume group ---
VG Name              vg01
System ID
Format               lvm2
Metadata Areas       2
Metadata Sequence No 1
VG Access            read/write
VG Status            resizable
MAX LV               0
Cur LV               0
Open LV              0
Max PV               0
Cur PV               2
Act PV               2
VG Size              14.99 GiB
PE Size              4.00 MiB
Total PE             3840
Alloc PE / Size      1280 / 4.99
Free PE / Size       2560 / 9.99 GiB
VG UUID              d17e3c31-e2c9-4f11-809c-94a549bc43b7

如何扩展逻辑卷?

使用以下命令增加现有逻辑卷大小。

逻辑卷扩展(lvextend)的常用语法:

lvextend [要增加的额外空间] [现有逻辑卷名称]

使用下面的命令将现有的逻辑卷增加 10GB:

# lvextend -L +10G /dev/mapper/vg01-lv002
Rounding size to boundary between physical extents: 5.90 GiB
Size of logical volume vg01/lv002 changed from 5.00 GiB (1280 extents) to 15.00 GiB (3840 extents).
Logical volume var successfully resized

使用 PE 大小来扩展逻辑卷:

# lvextend -l +2560 /dev/mapper/vg01-lv002

要使用百分比(%)扩展逻辑卷,请使用以下命令:

# lvextend -l +40%FREE /dev/mapper/vg01-lv002

现在,逻辑卷已经扩展,你需要调整文件系统的大小以扩展逻辑卷内的空间:

对于基于 ext3 和 ext4 的文件系统,运行以下命令:

# resize2fs /dev/mapper/vg01-lv002

对于 xfs 文件系统,使用以下命令:

# xfs_growfs /dev/mapper/vg01-lv002

使用 df 命令查看文件系统大小:

# df -h /lvmtest1
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg01-lv002 15360M 34M 15326M 4% /lvmtest1

via: https://www.2daygeek.com/extend-increase-resize-lvm-logical-volume-in-linux/

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

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

逻辑卷管理 Logical Volume Management (LVM)在 Linux 系统中扮演着重要的角色,它可以提高可用性、磁盘 I/O、性能和磁盘管理的能力。

LVM 是一种被广泛使用的技术,对于磁盘管理来说,它是非常灵活的。

它在物理磁盘和文件系统之间增加了一个额外的层,允许你创建一个逻辑卷而不是物理磁盘。

LVM 允许你在需要的时候轻松地调整、扩展和减少逻辑卷的大小。

如何创建 LVM 物理卷?

你可以使用任何磁盘、RAID 阵列、SAN 磁盘或分区作为 LVM 物理卷 Physical Volume (PV)。

让我们想象一下,你已经添加了三个磁盘,它们是 /dev/sdb/dev/sdc/dev/sdd

运行以下命令来发现 Linux 中新添加的 LUN 或磁盘

# ls /sys/class/scsi_host
host0
# echo "- - -" > /sys/class/scsi_host/host0/scan
# fdisk -l

创建物理卷 (pvcreate) 的一般语法:

pvcreate [物理卷名]

当在系统中检测到磁盘,使用 pvcreate 命令初始化 LVM PV:

# pvcreate /dev/sdb /dev/sdc /dev/sdd
Physical volume "/dev/sdb" successfully created
Physical volume "/dev/sdc" successfully created
Physical volume "/dev/sdd" successfully created

请注意:

  • 上面的命令将删除给定磁盘 /dev/sdb/dev/sdc/dev/sdd 上的所有数据。
  • 物理磁盘可以直接添加到 LVM PV 中,而不必是磁盘分区。

使用 pvdisplaypvs 命令来显示你创建的 PV。pvs 命令显示的是摘要输出,pvdisplay 显示的是 PV 的详细输出:

# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb lvm2 a-- 15.00g 15.00g
/dev/sdc lvm2 a-- 15.00g 15.00g
/dev/sdd lvm2 a-- 15.00g 15.00g
# pvdisplay

"/dev/sdb" is a new physical volume of "15.00 GiB"
--- NEW Physical volume ---
PV Name               /dev/sdb
VG Name
PV Size               15.00 GiB
Allocatable           NO
PE Size               0
Total PE              0
Free PE               0
Allocated PE          0
PV UUID               69d9dd18-36be-4631-9ebb-78f05fe3217f

"/dev/sdc" is a new physical volume of "15.00 GiB"
--- NEW Physical volume ---
PV Name               /dev/sdc
VG Name
PV Size               15.00 GiB
Allocatable           NO
PE Size               0
Total PE              0
Free PE               0
Allocated PE          0
PV UUID               a2092b92-af29-4760-8e68-7a201922573b

"/dev/sdd" is a new physical volume of "15.00 GiB"
--- NEW Physical volume ---
PV Name               /dev/sdd
VG Name
PV Size               15.00 GiB
Allocatable           NO
PE Size               0
Total PE              0
Free PE               0
Allocated PE          0
PV UUID               d92fa769-e00f-4fd7-b6ed-ecf7224af7faS

如何创建一个卷组

卷组 Volume Group (VG)是 LVM 结构中的另一层。基本上,卷组由你创建的 LVM 物理卷组成,你可以将物理卷添加到现有的卷组中,或者根据需要为物理卷创建新的卷组。

创建卷组 (vgcreate) 的一般语法:

vgcreate [卷组名] [物理卷名]

使用以下命令将一个新的物理卷添加到新的卷组中:

# vgcreate vg01 /dev/sdb /dev/sdc /dev/sdd
Volume group "vg01" successfully created

请注意:默认情况下,它使用 4MB 的 物理范围 Physical Extent (PE),但你可以根据你的需要改变它。

使用 vgsvgdisplay 命令来显示你创建的 VG 的信息:

# vgs vg01
VG #PV #LV #SN Attr VSize VFree
vg01 3 0 0 wz--n- 44.99g 44.99g
# vgdisplay vg01
--- Volume group ---
VG Name              vg01
System ID
Format               lvm2
Metadata Areas       3
Metadata Sequence No 1
VG Access            read/write
VG Status            resizable
MAX LV               0
Cur LV               0
Open LV              0
Max PV               0
Cur PV               3
Act PV               3
VG Size              44.99 GiB
PE Size              4.00 MiB
Total PE             11511
Alloc PE / Size      0 / 0
Free PE / Size       11511 / 44.99 GiB
VG UUID              d17e3c31-e2c9-4f11-809c-94a549bc43b7

如何扩展卷组

如果 VG 没有空间,请使用以下命令将新的物理卷添加到现有卷组中。

卷组扩展 (vgextend)的一般语法:

vgextend [已有卷组名] [物理卷名]
# vgextend vg01 /dev/sde
    Volume group "vg01" successfully extended

如何以 GB 为单位创建逻辑卷?

逻辑卷 Logical Volume (LV)是 LVM 结构中的顶层。逻辑卷是由卷组创建的块设备。它作为一个虚拟磁盘分区,可以使用 LVM 命令轻松管理。

你可以使用 lvcreate 命令创建一个新的逻辑卷。

创建逻辑卷(lvcreate) 的一般语法:

lvcreate –n [逻辑卷名] –L [逻辑卷大小] [要创建的 LV 所在的卷组名称]

运行下面的命令,创建一个大小为 10GB 的逻辑卷 lv001

# lvcreate -n lv001 -L 10G vg01
Logical volume "lv001" created

使用 lvslvdisplay 命令来显示你所创建的 LV 的信息:

# lvs /dev/vg01/lvol01
LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
lv001 vg01 mwi-a-m-- 10.00g lv001_mlog 100.00
# lvdisplay /dev/vg01/lv001
--- Logical volume ---
LV Path                /dev/vg01/lv001
LV Name                lv001
VG Name                vg01
LV UUID                ca307aa4-0866-49b1-8184-004025789e63
LV Write Access        read/write
LV Creation host, time localhost.localdomain, 2020-09-10 11:43:05 -0700
LV Status              available
# open                 0
LV Size                10.00 GiB
Current LE             2560
Segments               1
Allocation             inherit
Read ahead sectors     auto
- currently set to     256
Block device           253:4

如何以 PE 大小创建逻辑卷?

或者,你可以使用物理范围(PE)大小创建逻辑卷。

如何计算 PE 值?

很简单,例如,如果你有一个 10GB 的卷组,那么 PE 大小是多少?

默认情况下,它使用 4MB 的物理范围,但可以通过运行 vgdisplay 命令来检查正确的 PE 大小,因为这可以根据需求进行更改。

10GB = 10240MB / 4MB (PE 大小) = 2560 PE

用 PE 大小创建逻辑卷 (lvcreate) 的一般语法:

lvcreate –n [逻辑卷名] –l [物理扩展 (PE) 大小] [要创建的 LV 所在的卷组名称]

要使用 PE 大小创建 10GB 的逻辑卷,命令如下:

# lvcreate -n lv001 -l 2560 vg01

如何创建文件系统

在创建有效的文件系统之前,你不能使用逻辑卷。

创建文件系统的一般语法:

mkfs –t [文件系统类型] /dev/[LV 所在的卷组名称]/[LV 名称]

使用以下命令将逻辑卷 lv001 格式化为 ext4 文件系统:

# mkfs -t ext4 /dev/vg01/lv001

对于 xfs 文件系统:

# mkfs -t xfs /dev/vg01/lv001

挂载逻辑卷

最后,你需要挂载逻辑卷来使用它。确保在 /etc/fstab 中添加一个条目,以便系统启动时自动加载。

创建一个目录来挂载逻辑卷:

# mkdir /lvmtest

使用挂载命令挂载逻辑卷

# mount /dev/vg01/lv001 /lvmtest

/etc/fstab 文件中添加新的逻辑卷详细信息,以便系统启动时自动挂载:

# vi /etc/fstab
/dev/vg01/lv001 /lvmtest xfs defaults 0 0

使用 df 命令检查新挂载的卷:

# df -h /lvmtest
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg01-lv001 15360M 34M 15326M 4% /lvmtest

via: https://www.2daygeek.com/create-lvm-storage-logical-volume-manager-in-linux/

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

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

由于物联网(IoT)的兴起,对硬件进行编程变得越来越普遍。RT-Thread 可以让你可以用 FinSH 从 Linux 命令行与设备进行沟通、

RT-Thread 是一个开源的实时操作系统,用于对物联网(IoT)设备进行编程。FinSH 是 RT-Thread 的命令行组件,它提供了一套操作界面,使用户可以从命令行与设备进行沟通。它主要用于调试或查看系统信息。

通常情况下,开发调试使用硬件调试器和 printf 日志来显示。但在某些情况下,这两种方法并不是很有用,因为它是从运行的内容中抽象出来的,而且它们可能很难解析。不过 RT-Thread 是一个多线程系统,当你想知道一个正在运行的线程的状态,或者手动控制系统的当前状态时,这很有帮助。因为它是多线程的,所以你能够拥有一个交互式的 shell,你可以直接在设备上输入命令、调用函数来获取你需要的信息,或者控制程序的行为。如果你只习惯于 Linux 或 BSD 等现代操作系统,这在你看来可能很普通,但对于硬件黑客来说,这是极其奢侈的,远超将串行电缆直接连线到电路板上以获取一丝错误的做法。

FinSH 有两种模式。

  • C 语言解释器模式,称为 c-style。
  • 传统的命令行模式,称为 msh(模块 shell)。

在 C 语言解释器模式下,FinSH 可以解析执行大部分 C 语言的表达式,并使用函数调用访问系统上的函数和全局变量。它还可以从命令行创建变量。

在 msh 模式下,FinSH 的操作与 Bash 等传统 shell 类似。

GNU 命令标准

当我们在开发 FinSH 时,我们了解到,在编写命令行应用程序之前,你需要熟悉 GNU 命令行标准。这个标准实践的框架有助于给界面带入熟悉感,这有助于开发人员在使用时感到舒适和高效。

一个完整的 GNU 命令主要由四个部分组成。

  1. 命令名(可执行文件):命令行程序的名称;
  2. 子命令:命令程序的子函数名称。
  3. 选项:子命令函数的配置选项。
  4. 参数:子命令函数配置选项的相应参数。

你可以在任何命令中看到这一点。以 Git 为例:

git reset --hard HEAD~1

这一点可以分解为:

 title=

可执行的命令是 git,子命令是 reset,使用的选项是 --head,参数是 HEAD~1

再举个例子:

systemctl enable --now firewalld

可执行的命令是 systemctl,子命令是 enable,选项是 --now,参数是 firewalld

想象一下,你想用 RT-Thread 编写一个符合 GNU 标准的命令行程序。FinSH 拥有你所需要的一切,并且会按照预期运行你的代码。更棒的是,你可以依靠这种合规性,让你可以自信地移植你最喜欢的 Linux 程序。

编写一个优雅的命令行程序

下面是一个 RT-Thread 运行命令的例子,RT-Thread 开发人员每天都在使用这个命令:

usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]
                      [--upgrade] [--printenv]

optional arguments:
  -h, --help      show this help message and exit
  --force-update  force update and clean packages, install or remove the
                  packages by your settings in menuconfig
  --update        update packages, install or remove the packages by your
                  settings in menuconfig
  --list          list target packages
  --wizard        create a new package with wizard
  --upgrade       upgrade local packages list and ENV scripts from git repo
  --printenv      print environmental variables to check

正如你所看到的那样,它看起来很熟悉,行为就像你可能已经在 Linux 或 BSD 上运行的大多数 POSIX 应用程序一样。当使用不正确或不充分的语法时,它会提供帮助,它支持长选项和短选项。这种通用的用户界面对于任何使用过 Unix 终端的人来说都是熟悉的。

选项种类

选项的种类很多,按长短可分为两大类。

  1. 短选项:由一个连字符加一个字母组成,如 pkgs -h 中的 -h 选项。
  2. 长选项:由两个连字符加上单词或字母组成,例如,scons- --target-mdk5 中的 --target 选项。

你可以把这些选项分为三类,由它们是否有参数来决定。

  1. 没有参数:该选项后面不能有参数。
  2. 参数必选:选项后面必须有参数。
  3. 参数可选:选项后可以有参数,但不是必需的。

正如你对大多数 Linux 命令的期望,FinSH 的选项解析非常灵活。它可以根据空格或等号作为定界符来区分一个选项和一个参数,或者仅仅通过提取选项本身并假设后面的内容是参数(换句话说,完全没有定界符)。

  • wavplay -v 50
  • wavplay -v50
  • wavplay --vol=50

使用 optparse

如果你曾经写过命令行程序,你可能会知道,一般来说,你所选择的语言有一个叫做 optparse 的库或模块。它是提供给程序员的,所以作为命令的一部分输入的选项(比如 -v--verbose)可以与命令的其他部分进行解析。这可以帮助你的代码从一个子命令或参数中获取一个选项。

当为 FinSH 编写一个命令时,optparse 包希望使用这种格式:

MSH_CMD_EXPORT_ALIAS(pkgs, pkgs, this is test cmd.);

你可以使用长形式或短形式,或者同时使用两种形式来实现选项。例如:

static struct optparse_long long_opts[] =
{
    {"help"        , 'h', OPTPARSE_NONE}, // Long command: help, corresponding to short command h, without arguments.
    {"force-update",  0 , OPTPARSE_NONE}, // Long comman: force-update, without arguments
    {"update"      ,  0 , OPTPARSE_NONE},
    {"list"        ,  0 , OPTPARSE_NONE},
    {"wizard"      ,  0 , OPTPARSE_NONE},
    {"upgrade"     ,  0 , OPTPARSE_NONE},
    {"printenv"    ,  0 , OPTPARSE_NONE},
    { NULL         ,  0 , OPTPARSE_NONE}
};

创建完选项后,写出每个选项及其参数的命令和说明:

static void usage(void)
{
    rt_kprintf("usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]\n");
    rt_kprintf("                      [--upgrade] [--printenv]\n\n");
    rt_kprintf("optional arguments:\n");
    rt_kprintf("  -h, --help      show this help message and exit\n");
    rt_kprintf("  --force-update  force update and clean packages, install or remove the\n");
    rt_kprintf("                  packages by your settings in menuconfig\n");
    rt_kprintf("  --update        update packages, install or remove the packages by your\n");
    rt_kprintf("                  settings in menuconfig\n");
    rt_kprintf("  --list          list target packages\n");
    rt_kprintf("  --wizard        create a new package with wizard\n");
    rt_kprintf("  --upgrade       upgrade local packages list and ENV scripts from git repo\n");
    rt_kprintf("  --printenv      print environmental variables to check\n");
}

下一步是解析。虽然你还没有实现它的功能,但解析后的代码框架是一样的:

int pkgs(int argc, char **argv)
{
    int ch;
    int option_index;
    struct optparse options;

    if(argc == 1)
    {
        usage();
        return RT_EOK;
    }

    optparse_init(&options, argv);
    while((ch = optparse_long(&options, long_opts, &option_index)) != -1)
    {
        ch = ch;

        rt_kprintf("\n");
        rt_kprintf("optopt = %c\n", options.optopt);
        rt_kprintf("optarg = %s\n", options.optarg);
        rt_kprintf("optind = %d\n", options.optind);
        rt_kprintf("option_index = %d\n", option_index);
    }
    rt_kprintf("\n");

    return RT_EOK;
}

这里是函数头文件:

#include "optparse.h"
#include "finsh.h"

然后,编译并下载到设备上。

 title=

硬件黑客

对硬件进行编程似乎很吓人,但随着物联网的发展,它变得越来越普遍。并不是所有的东西都可以或者应该在树莓派上运行,但在 RT-Thread,FinSH 可以让你保持熟悉的 Linux 感觉。

如果你对在裸机上编码感到好奇,不妨试试 RT-Thread。


via: https://opensource.com/article/20/9/hardware-command-line

作者:Alan Smithee 选题:lujun9972 译者:wxy 校对:wxy

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

我最近在我的树莓派上安装了 Ubuntu 服务器。我在 Ubuntu 终端连接上了 Wi-Fi,然后做了我在安装任何 Linux 系统后都会做的事情,那就是更新系统。

当我使用 sudo apt update 命令时,它给了一个对我而言特别的错误。它报出仓库的发布文件在某个时间段内无效。

E: Release file for http://ports.ubuntu.com/ubuntu-ports/dists/focal-security/InRelease is not valid yet (invalid for another 159d 15h 20min 52s). Updates for this repository will not be applied.**

下面是完整输出:

ubuntu@ubuntu:~$ sudo apt update
Hit:1 http://ports.ubuntu.com/ubuntu-ports focal InRelease    
Get:2 http://ports.ubuntu.com/ubuntu-ports focal-updates InRelease [111 kB]                           
Get:3 http://ports.ubuntu.com/ubuntu-ports focal-backports InRelease [98.3 kB]      
Get:4 http://ports.ubuntu.com/ubuntu-ports focal-security InRelease [107 kB]                     
Reading package lists... Done
E: Release file for http://ports.ubuntu.com/ubuntu-ports/dists/focal/InRelease is not valid yet (invalid for another 21d 23h 17min 25s). Updates for this repository will not be applied.
E: Release file for http://ports.ubuntu.com/ubuntu-ports/dists/focal-updates/InRelease is not valid yet (invalid for another 159d 15h 21min 2s). Updates for this repository will not be applied.
E: Release file for http://ports.ubuntu.com/ubuntu-ports/dists/focal-backports/InRelease is not valid yet (invalid for another 159d 15h 21min 32s). Updates for this repository will not be applied.
E: Release file for http://ports.ubuntu.com/ubuntu-ports/dists/focal-security/InRelease is not valid yet (invalid for another 159d 15h 20min 52s). Updates for this repository will not be applied.

修复 Ubuntu 和其他 Linux 发行版中 “Release file is not valid yet” 的错误。

错误的原因是系统上的时间和现实世界的时间不同。

你看,每个仓库文件都是在某个日期签名的,你可以通过查看发布文件信息了解:

sudo head /var/lib/apt/lists/ports.ubuntu.com_ubuntu_dists_focal_InRelease
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Origin: Ubuntu
Label: Ubuntu
Suite: focal
Version: 20.04
Codename: focal
Date: Thu, 23 Apr 2020 17:33:17 UTC
Architectures: amd64 arm64 armhf i386 ppc64el riscv64 s390x

现在,由于某些原因,我的 Ubuntu 服务器上的时间是过去时间,这也是为什么 Ubuntu 报出发布文件已经无效 X 天的原因。

如果你连接到了互联网,你可以等待几分钟让系统同步时间

如果不行,你可以强制系统使用本地时间作为实时时钟(硬件时钟):

sudo timedatectl set-local-rtc 1

timedatectl 命令可以让你在 Linux 上配置时间、日期和更改时区

你应该不需要重新启动。它可以立即工作,你可以通过更新你的 Ubuntu 系统再次验证它。

如果问题解决了,你可以将实时时钟设置为使用 UTC(Ubuntu 推荐的)。

sudo timedatectl set-local-rtc 0

是否为你解决了这个问题?

我希望这个提示能帮助你解决这个错误。如果你仍然遇到这个问题,请在评论栏告诉我,我会尽力帮助你。


via: https://itsfoss.com/fix-repository-not-valid-yet-error-ubuntu/

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

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

这个老牌 Linux 备份方案迁移到了 Python 3 提供了添加许多新功能的机会。

2020 年 3 月,rdiff-backup 升级到了 2.0 版,这距离上一个主要版本已经过去了 11 年。2020 年初 Python 2 的废弃是这次更新的动力,但它为开发团队提供了整合其他功能和优势的机会。

大约二十年来,rdiff-backup 帮助 Linux 用户在本地或远程维护他们的数据的完整备份,而无需无谓地消耗资源。这是因为这个开源解决方案可以进行反向增量备份,只备份从上一次备份中改变的文件。

这次改版(或者说,重生)得益于一个新的、自组织的开发团队(由来自 IKUS Software 的 Eric Zolf 和 Patrik Dufresne,以及来自 Seravo 的 Otto Kekäläinen 共同领导)的努力,为了所有 rdiff-backup 用户的利益,他们齐心协力。

rdiff-backup 的新功能

在 Eric 的带领下,随着向 Python 3 的迁移,项目被迁移到了一个新的、不受企业限制的仓库,以欢迎贡献。团队还整合了多年来提交的所有补丁,包括对稀疏文件的支持和对硬链接的修复。

用 Travis CI 实现自动化

另一个巨大的改进是增加了一个使用开源 Travis CI 的持续集成/持续交付(CI/CD)管道。这允许在各种环境下测试 rdiff-backup,从而确保变化不会影响方案的稳定性。CI/CD 管道包括集成所有主要平台的构建和二进制发布。

使用 yum 和 apt 轻松安装

新的 rdiff-backup 解决方案可以运行在所有主流的 Linux 发行版上,包括 Fedora、Red Hat、Elementary、Debian 等。Frank 和 Otto 付出了艰辛的努力,提供了开放的仓库以方便访问和安装。你可以使用你的软件包管理器安装 rdiff-backup,或者按照 GitHub 项目页面上的分步说明进行安装。

新的主页

团队将网站从 Savannah 迁移到了 GitHub Pages,并对 rdiff-backup.net 官网进行了改版,加入了新的内容,让外观和感觉更加到位。

如何使用 rdiff-backup

如果你是 rdiff-backup 的新手,你可能会对它的易用性感到惊讶。备份方案应该让你对备份和恢复过程感到舒适,而不是吓人。

开始备份

要开始备份到本地驱动器,例如通过 USB 连接的驱动器,输入 rdiff-backup 命令,然后输入要备份的驱动器和要存储文件的目标目录。

例如,要备份到名为 my_backup_drive 的本地驱动器,请输入:

$ rdiff-backup /home/tux/ /run/media/tux/my_backup_drive/

要将数据备份到异地存储,请使用远程服务器的位置,并在 :: 后面指向备份驱动器的挂载点:

$ rdiff-backup /home/tux/ [email protected]::/my_backup_drive/

你可能需要设置 SSH 密钥来使这个过程更轻松。

还原文件

做备份的原因是有时文件会丢失。为了使恢复尽可能简单,你甚至不需要 rdiff-backup 来恢复文件(虽然使用 rdiff-backup 命令提供了一些方便)。

如果你需要从备份驱动器中获取一个文件,你可以使用 cp 将其从备份驱动器复制到本地系统,或者对于远程驱动器使用 scp 命令。

对于本地驱动器,使用:

$ cp _run_media/tux/my_backup_drive/Documents/example.txt ~/Documents

或者用于远程驱动器:

$ scp [email protected]::/my_backup_drive/Documents/example.txt ~/Documents

然而,使用 rdiff-backup 命令提供了其他选项,包括 --restore-as-of。这允许你指定你要恢复的文件的哪个版本。

例如,假设你想恢复一个文件在四天前的版本:

$ rdiff-backup --restore-as-of 4D /run/media/tux/foo.txt ~/foo_4D.txt

你也可以用 rdiff-backup 来获取最新版本:

$ rdiff-backup --restore-as-of now /run/media/tux/foo.txt ~/foo_4D.txt`

就是这么简单。另外,rdiff-backup 还有很多其他选项,例如,你可以从列表中排除文件,从一个远程备份到另一个远程等等,这些你可以在文档中了解。

总结

我们的开发团队希望用户能够喜欢这个改版后的开源 rdiff-backup 方案,这是我们不断努力的结晶。我们也感谢我们的贡献者,他们真正展示了开源的力量。


via: https://opensource.com/article/20/9/rdiff-backup-linux

作者:Patrik Dufresne 选题:lujun9972 译者:geekpi 校对:wxy

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