mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-03 01:10:13 +08:00
commit
f99dc5297d
@ -1,21 +1,22 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chenmu-kk)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12883-1.html)
|
||||
[#]: subject: (Linux Desktop Setup · HookRace Blog)
|
||||
[#]: via: (https://hookrace.net/blog/linux-desktop-setup/)
|
||||
[#]: author: (Dennis Felsing http://felsin9.de/nnis/)
|
||||
|
||||
Linux桌面设置
|
||||
十年 Linux 桌面生存指南
|
||||
======
|
||||
|
||||

|
||||
|
||||
从 2006 年开始转战 Linux 系统后,经过几年的实践,我的软件设置在过去十年内出人意料的固定。再过十年回顾一下,看看发生了什么,也许会非常有趣。在写这篇推文时,我迅速回顾了正在运行的内容:
|
||||
|
||||
[![htop overview][1]][2]
|
||||
![htop overview][2]
|
||||
|
||||
### 契机
|
||||
### 动机
|
||||
|
||||
我的软件介绍排序不分先后:
|
||||
|
||||
@ -25,27 +26,25 @@ Linux桌面设置
|
||||
* 最好使用快速高效的软件,我不喜欢听到风扇的声音和感到房间在变热。我还可以继续长久地运行旧硬件,已经使用了 10 年的 Thinkpad x200s 还能很好地支持我所使用的软件。
|
||||
* 组合。我不想手动执行每个步骤,而是在需要时自动执行更多操作,这时自然是支持 shell。
|
||||
|
||||
|
||||
|
||||
### 操作系统
|
||||
|
||||
十二年前移除 Windows 系统后,我在 Linux 系统上经历了一个艰难的开始,当时我手上只有 [Gentoo Linux][3] 系统的安装光盘和一本打印的说明书,要用它们来实现一个可运行的 Linux 系统。虽然花费了几天的时间去编辑和修整,但最终还是觉得自己受益颇多。
|
||||
十二年前移除 Windows 系统后,我在 Linux 系统上经历了一个艰难的开始,当时我手上只有 [Gentoo Linux][3] 系统的安装光盘和一本打印的说明书,要用它们来实现一个可运行的 Linux 系统。虽然花费了几天的时间去编译和修整,但最终还是觉得自己受益颇多。
|
||||
|
||||
自此我再也没有转回 Windows 系统,但在持续的编译压力导致风扇失灵后,我将我的电脑系统切换到 [Arch Linux][4]。之后我将其他的电脑和私人服务器也切换到了 Arch Linux。作为一个滚动发布发行版,你可以随时升级软件包,但 [Arch Linux News][5] 已经详细报道了其中最主要的漏洞。
|
||||
|
||||
不过,令人烦恼的事一旦你更新了旧的内核模组, Arch Linux 就会移除旧版的相关信息。我经常注意到一旦我试着插入一个 USB 闪存驱动,内核就无法加载相关组件。相反,每次内核升级后都应该进行重启。有一些 [方法][6] 可以解决这个问题,但我还没有实际地使用它们。
|
||||
不过,令人烦恼的是一旦你更新了旧的内核模组,Arch Linux 就会移除旧版的相关信息。我经常注意到一旦我试着插入一个 USB 闪存盘,内核就无法加载相关组件。相反,每次内核升级后都应该进行重启。有一些 [方法][6] 可以解决这个问题,但我还没有实际地使用它们。
|
||||
|
||||
其他程序也会出现类似的情况,通常 Firefox 、 cron 或者 Samba 在升级后都需要重启,但恼人的是,它们没有警告你存在这种情况不是提醒你这件事本身。我在工作中使用的 [SUSE][7] 很好地提醒了这种情况。
|
||||
其他程序也会出现类似的情况,通常 Firefox 、 cron 或者 Samba 在升级后都需要重启,但恼人的是,它们没有警告你存在这种情况。我在工作中使用的 [SUSE][7] 很好地提醒了这种情况。
|
||||
|
||||
对于 [DDNet][8] ,我更喜欢使用 Arch Linux 的 [Debian][9] 系统,这样在每次升级时出现故障的几率更低。我的防火墙和路由器使用了拥有干净系统、文件和强大的 [OpenBSD][10] 的 [pf firewall][11]。
|
||||
对于 [DDNet][8] 产品服务器,相较于 Arch Linux ,我更倾向于 [Debian][9] 系统,这样在每次升级时出现故障的几率更低。我的防火墙和路由器使用了 [OpenBSD][10] ,它拥有干净系统、文档和强大的 [pf 防火墙][11],而我现在不需要一个单独的路由器。
|
||||
|
||||
### 视窗管理
|
||||
### 窗口管理器
|
||||
|
||||
从我开始使用 Gentoo 后,我很快注意到 KDE 的编译时间非常长,这让我没办法继续使用它。我四处寻找更简单的解决方案,最初使用了 [Openbox][12] 和 [Fluxbox][13]。某次,为了能更多进行纯键盘操作,我开始转入平铺窗口管理器训练,并在研究其初始版本的时候学习了 [dwm][14] 和 [awesome][15]。
|
||||
从我开始使用 Gentoo 后,我很快注意到 KDE 的编译时间非常长,这让我没办法继续使用它。我四处寻找更简单的解决方案,最初使用了 [Openbox][12] 和 [Fluxbox][13]。某次,为了能更多进行纯键盘操作,我开始尝试转入平铺窗口管理器,并在研究其初始版本的时候学习了 [dwm][14] 和 [awesome][15]。
|
||||
|
||||
最终,由于 [xmonad][16]的灵活性,可扩展性以及使用纯 [Haskell][17] 一种出色的功能编程语言)编写和配置,最终选择了它。一个例子是,我在家中运行一个 40" 4K 的屏幕,但经常会将它分为四个虚拟屏幕,每个虚拟屏幕显示一个工作区,每个工作区自动排列在我的窗口上。 当然, xmonad 有一个对应的 [模块][18]。
|
||||
最终,由于 [xmonad][16]的灵活性、可扩展性以及使用纯 [Haskell][17](一种出色的函数编程语言)编写和配置,最终选择了它。一个例子是,我在家中运行一个 40" 4K 的屏幕,但经常会将它分为四个虚拟屏幕,每个虚拟屏幕显示一个工作区,每个工作区自动排列在我的窗口上。当然, xmonad 有一个对应的 [模块][18]。
|
||||
|
||||
[dzen][19] 和 [conky][20] 对我来说是一个非常简单的状态栏。我的整体conky配置看起来是这样的:
|
||||
[dzen][19] 和 [conky][20] 对我来说是一个非常简单的状态栏。我的整体 conky 配置看起来是这样的:
|
||||
|
||||
```
|
||||
out_to_console yes
|
||||
@ -56,13 +55,23 @@ TEXT
|
||||
${downspeed eth0} ${upspeed eth0} | $cpu% ${loadavg 1} ${loadavg 2} ${loadavg 3} $mem/$memmax | ${time %F %T}
|
||||
```
|
||||
|
||||
输入命令直接通过管道输入dzen2 `conky | dzen2 -fn '-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*' -bg '#000000' -fg '#ffffff' -p -e '' -x 1000 -w 920 -xs 1 -ta r`.
|
||||
输入命令直接通过管道输入 dzen2:
|
||||
|
||||
对我而言,一项重要功能是在完成工作后使终端发出蜂鸣声。只需要简单地在 zsh 中的 `PR_TITLEBAR` 变量中添加一个 `\a` 字符就可以做到,只要工作完成就可以发出蜂鸣声。当然,我使用了 `echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf` 命令,将 `pcspkr` 内核模块列入黑名单来禁用实际的蜂鸣声。相反 urxvt 的`URxvt.urgentOnBell: true` 设置会将声音变为尖锐。之后 xmonad 有一个 urgency hook 来捕捉这类信号,并且我可以使用组合键自动聚焦到当前紧急窗口。在 dzen 中我可以看到一个漂亮且明亮的 `#ff0000`紧急窗口。
|
||||
```
|
||||
conky | dzen2 -fn '-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*' -bg '#000000' -fg '#ffffff' -p -e '' -x 1000 -w 920 -xs 1 -ta r
|
||||
```
|
||||
|
||||
对我而言,一项重要功能是在完成工作后使终端发出蜂鸣声。只需要简单地在 zsh 中的 `PR_TITLEBAR` 变量中添加一个 `\a` 字符就可以做到,只要工作完成就可以发出蜂鸣声。当然,我使用了命令:
|
||||
|
||||
```
|
||||
echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf
|
||||
```
|
||||
|
||||
将 `pcspkr` 内核模块列入黑名单来禁用实际的蜂鸣声。相反 urxvt 的 `URxvt.urgentOnBell: true` 设置会将声音变为尖锐。之后 xmonad 有一个 urgency 钩子来捕捉这类信号,并且我可以使用组合键自动聚焦到当前的发出紧急信号的窗口。在 dzen 中我可以看到一个漂亮且明亮的 `#ff0000` 紧急窗口。
|
||||
|
||||
在我笔记本上所得到的最终成品是:
|
||||
|
||||
[![Laptop screenshot][21]][22]
|
||||
![Laptop screenshot][22]
|
||||
|
||||
我听说前几年 [i3][23] 变得非常流行,但它要求更多的手动窗口对齐而不是自动对齐。
|
||||
|
||||
@ -70,15 +79,15 @@ ${downspeed eth0} ${upspeed eth0} | $cpu% ${loadavg 1} ${loadavg 2} ${loadavg 3}
|
||||
|
||||
### 终端连续性
|
||||
|
||||
为了使终端保持活跃状态,我使用了 [dtach][25] ,它只是模拟屏幕分离功能。 为了使计算机上的每个终端都可连接和断开,我编写了一个小的封装脚本。 这意味着,即使必须重新启动 X 服务器,我也可以使所有终端都运行良好,包括本地和远程终端。
|
||||
为了使终端保持活跃状态,我使用了 [dtach][25] ,它只是模拟屏幕分离功能。为了使计算机上的每个终端都可连接和断开,我编写了一个小的封装脚本。 这意味着,即使必须重新启动 X 服务器,我也可以使所有终端都运行良好,包括本地和远程终端。
|
||||
|
||||
### Shell & 编程
|
||||
|
||||
对于 shell,我使用 [zsh][28] 而不是 [bash][27],因为它有众多的功能。
|
||||
|
||||
作为终端模拟,我发现 [urxvt][29] 足够轻巧,支持 Unicode 编码和 256 色,具有出色的性能。另一个重要的功能是可以分别运行 urxvt client 客户端和守护进程。因此,即使大量终端也几乎不占用任何内存( scrollback 除外)。
|
||||
作为终端模拟,我发现 [urxvt][29] 足够轻巧,支持 Unicode 编码和 256 色,具有出色的性能。另一个重要的功能是可以分别运行 urxvt 客户端和守护进程。因此,即使大量终端也几乎不占用任何内存(回滚缓冲区除外)。
|
||||
|
||||
对我而言,只有一种字体看起来绝对干净和完美: [Terminus][30]。 由于我是位图字体,因此所有内容都是完美像素,渲染速度极快且 CPU 使用率低。为了能使用 `CTRL-WIN-[1-7]` 在每个终端按需切换字体,我的 ~/.Xdefaults 包含:
|
||||
对我而言,只有一种字体看起来绝对干净和完美: [Terminus][30]。 由于它是位图字体,因此所有内容都是完美像素,渲染速度极快且 CPU 使用率低。为了能使用 `CTRL-WIN-[1-7]` 在每个终端按需切换字体,我的 `~/.Xdefaults` 包含:
|
||||
|
||||
```
|
||||
URxvt.font: -xos4-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*
|
||||
@ -96,7 +105,7 @@ URxvt.keysym.C-M-n: command:\033]10;#ffffff\007\033]11;#000000\007\033]12;#fffff
|
||||
URxvt.keysym.C-M-b: command:\033]10;#000000\007\033]11;#ffffff\007\033]12;#000000\007\033]706;#0000ff\007\033]707;#ff0000\007
|
||||
```
|
||||
|
||||
对于编程和书写,我使用 [Vim][31] 语法高亮显示和 [ctags][32] 进行索引,以及一些带有 grep 、sed 和其他用于搜索和操作的常用终端窗口。这可能不像 IDE 那样舒适,可以实现更多的自动化。
|
||||
对于编程和书写,我使用 [Vim][31] 语法高亮显示和 [ctags][32] 进行索引,以及一些带有 `grep` 、`sed` 和其他用于搜索和操作的常用终端窗口。这可能不像 IDE 那样舒适,但可以实现更多的自动化。
|
||||
|
||||
Vim 的一个问题是你已经习惯了它的键映射,因此希望在任何地方都使用它们。
|
||||
|
||||
@ -112,7 +121,7 @@ Vim 的一个问题是你已经习惯了它的键映射,因此希望在任何
|
||||
|
||||
### 邮件 & 同步
|
||||
|
||||
在我的 home server 服务器上,我为自己所有的邮箱账号运行了 [fetchmail][42] 守护进程。Fetchmail 只检索收到的邮件并调用 [procmail][43]:
|
||||
在我的家庭服务器上,我为自己所有的邮箱账号运行了 [fetchmail][42] 守护进程。fetchmail 只是检索收到的邮件并调用 [procmail][43]:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
@ -172,7 +181,7 @@ password XXX
|
||||
[...]
|
||||
```
|
||||
|
||||
但是到目前为止,邮件还在服务器上。 我的文档全部存储在一个目录中,我使用 [Unison][45] 在所有计算机之间进行同步。将 Unison 视为双向交互 [rsync][46],我的邮件是这个文件目录下的一部分因此它们最终存储在我的电脑上。
|
||||
但是到目前为止,邮件还在服务器上。 我的文档全部存储在一个目录中,我使用 [Unison][45] 在所有计算机之间进行同步。Unison 可以视为双向交互式 [rsync][46],我的邮件是这个文件目录下的一部分,因此它们最终存储在我的电脑上。
|
||||
|
||||
这也意味着,尽管邮件会立即到达我的邮箱,但我只是按需拿取,而不是邮件一到达时就立即收到通知。
|
||||
|
||||
@ -227,6 +236,7 @@ MSG Sun from [sunrise(trigdate())] to [sunset(trigdate())]
|
||||
```
|
||||
|
||||
遗憾的是,目前 remind 中还没有中国农历的提醒功能,因此中国的节日不易计算。
|
||||
|
||||
我给提醒设置了两个名字:
|
||||
|
||||
```
|
||||
@ -245,7 +255,7 @@ rem -m -b1 -q -cuc12 -w$(($(tput cols)+1)) | sed -e "s/\f//g" | less
|
||||
|
||||
### 字典
|
||||
|
||||
[rdictcc][52] 是鲜为人知的字典工具,它可以从 [dict.cc][53] 使用高级词典并将他们转存在本地数据库中:
|
||||
[rdictcc][52] 是鲜为人知的字典工具,它可以使用 [dict.cc][53] 很棒的词典并将他们转存在本地数据库中:
|
||||
|
||||
```
|
||||
$ rdictcc rasch
|
||||
@ -278,9 +288,9 @@ Rasch model:
|
||||
|
||||
### 记录和阅读
|
||||
|
||||
我有一个简单记录任务的备忘录,在 Vim 会话中基本上一直处于打开状态。我也使用备忘录作为工作中已做工作的记录,这样就可以检查自己每天完成了哪些任务。
|
||||
我有一个简单记录任务的备忘录,在 Vim 会话中基本上一直处于打开状态。我也使用备忘录作为工作中“已完成”工作的记录,这样就可以检查自己每天完成了哪些任务。
|
||||
|
||||
对于写文件,信件和演示文稿,我会使用 [LaTeX][54] 进行高级排版。德式的简单信件可以这样设置,例如:
|
||||
对于写文件、信件和演示文稿,我会使用 [LaTeX][54] 进行高级排版。德式的简单信件可以这样设置,例如:
|
||||
|
||||
```
|
||||
\documentclass[paper = a4, fromalign = right]{scrlttr2}
|
||||
@ -320,19 +330,19 @@ Ich fordere Sie hiermit zu Bla Bla Bla auf.
|
||||
|
||||
### 图片编辑
|
||||
|
||||
[GIMP][58] 和 [Inkscape][59] 分别是照片编辑和交互式向量图形是一个简便的选择。
|
||||
简便的选择是,[GIMP][58] 和 [Inkscape][59] 分别用于照片编辑和交互式向量图形。
|
||||
|
||||
有时 [Imagemagick][60] 已经足够好了,它可以从命令行直接使用,从而自动编辑图片。同样 [Graphviz][61] 和 [TikZ][62] 可以用来绘制曲线图和其他图表。
|
||||
|
||||
### 网络浏览器
|
||||
### Web 浏览器
|
||||
|
||||
对于网络浏览器,我一直在使用 [Firefox][63]。相较于 Chrome,它的可扩展性更好,资源使用率更低。
|
||||
对于 Web 浏览器,我一直在使用 [Firefox][63]。相较于 Chrome,它的可扩展性更好,资源使用率更低。
|
||||
|
||||
不幸的是,在 Firefox 完全改用 Chrome 风格的扩展之后, [Pentadactyl][64] l扩展的开发就停止了,所以我的浏览器中再也没有令人满意的 Vim 类控件了。
|
||||
不幸的是,在 Firefox 完全改用 Chrome 风格的扩展之后, [Pentadactyl][64] 扩展的开发就停止了,所以我的浏览器中再也没有令人满意的 Vim 类控件了。
|
||||
|
||||
### 媒体播放器
|
||||
|
||||
通过设置 `vo=gpu` 以及 `hwdec=vaapi`,具有硬件解码功能的 [mpv][65] 在播放期间 CPU 的占用率保持在 5%。相较于默认的t PulseAudio,mpv 中的 `audio-channels=2` 似乎可以使我的立体扬声器/耳机获得更清晰的降级混频。一个很棒的小功能是用 `Shift-Q` 退出,而不是只用 `Q` 来保存回放位置。当你与母语是其他语言的人一起看视频时,你可以使用 `--secondary-sid=` 同时显示两种字幕,主字幕位于底部,次字幕位于屏幕顶部。
|
||||
通过设置 `vo=gpu` 以及 `hwdec=vaapi`,具有硬件解码功能的 [mpv][65] 在播放期间 CPU 的占用率保持在 5%。相较于默认的 PulseAudio,mpv 中的 `audio-channels=2` 似乎可以使我的立体扬声器/耳机获得更清晰的降级混频。一个很棒的小功能是用 `Shift-Q` 退出,而不是只用 `Q` 来保存回放位置。当你与母语是其他语言的人一起看视频时,你可以使用 `--secondary-sid=` 同时显示两种字幕,主字幕位于底部,次字幕位于屏幕顶部。
|
||||
|
||||
我的无线鼠标可以简单地通过一个小的配置文件( `~/.config/mpv/input.conf` )实现远程控制 mpv :
|
||||
|
||||
@ -346,11 +356,11 @@ MOUSE_BTN8 add chapter 1
|
||||
|
||||
[youtube-dl][66] 非常适合观看在线托管的视频,使用 `-f bestvideo+bestaudio/best --all-subs --embed-subs` 命令可获得最高质量的视频。
|
||||
|
||||
作为音乐播放器, [MOC][67] 还未得到积极发展,但它仍是一个简易的播放器,可以播放各种可能的格式,包括最不常用的 Chiptune 格式。在 AUR 中有一个 [补丁][68] 增加了 PulseAudio 支持。即使在 CPU 时钟频率降到 800 MHz, MOC 也只使用了单核 CPU 的 1-2% 。
|
||||
作为音乐播放器, [MOC][67] 不再活跃开发,但它仍是一个简易的播放器,可以播放各种可能的格式,包括最不常用的 Chiptune 格式。在 AUR 中有一个 [补丁][68] 增加了 PulseAudio 支持。即使在 CPU 时钟频率降到 800 MHz, MOC 也只使用了单核 CPU 的 1-2% 。
|
||||
|
||||
![moc][69]
|
||||
|
||||
我的音乐收藏夹保存在我的 home server 上,因此我可以从任何地方访问它。它使用 [SSHFS][70] 挂载并自动安装在 `/etc/fstab/` 目录下:
|
||||
我的音乐收藏夹保存在我的家庭服务器上,因此我可以从任何地方访问它。它使用 [SSHFS][70] 挂载并自动安装在 `/etc/fstab/` 目录下:
|
||||
|
||||
```
|
||||
root@server:/media/media /mnt/media fuse.sshfs noauto,x-systemd.automount,idmap=user,IdentityFile=/root/.ssh/id_rsa,allow_other,reconnect 0 0
|
||||
@ -358,26 +368,26 @@ root@server:/media/media /mnt/media fuse.sshfs noauto,x-systemd.automount,idmap=
|
||||
|
||||
### 跨平台构建
|
||||
|
||||
除了系统本身,对于任何主流操作系统 Linux 在构建软件包方面都很优秀! 一开始,我使用 [QEMU][71] 与旧版 Debian、 Windows 以及 Mac OS X VM 一起构建这些平台。
|
||||
除了 Linux 本身,它对于构建任何主流操作系统的软件包都很优秀! 一开始,我使用 [QEMU][71] 与旧版 Debian、 Windows 以及 Mac OS X VM 一起构建这些平台。
|
||||
|
||||
现在我在旧版 Debian distribution 上转而使用 chroot (以获得最大的 Linux 兼容性),在 Windows 上使用 [MinGW][72] 进行交叉编译,在 Mac OS X 上则使用 [OSXCross][73]。
|
||||
现在我在旧版 Debian 发行版上转而使用 chroot (以获得最大的 Linux 兼容性),在 Windows 上使用 [MinGW][72] 进行交叉编译,在 Mac OS X 上则使用 [OSXCross][73]。
|
||||
|
||||
用于 [build DDNet][74] 以及 [instructions for updating library builds][75] 的脚本都基于此。
|
||||
用于 [构建 DDNet][74] 的脚本以及 [更新库构建的说明][75] 的脚本都基于这个。
|
||||
|
||||
### 备份
|
||||
|
||||
通常,我们都会忘记备份。即使这是终章,它也不应该成为事后诸葛。
|
||||
通常,我们都会忘记备份。即使这是最后一节,它也不应该成为事后诸葛。
|
||||
|
||||
十年前我写了 [rrb][76] (反向rsync备份)重新包装了 rsync ,因此我只需要授予正在备份的计算机,备份服务器的 root SSH 权限。令人惊讶地是,尽管我一直在使用 rrb ,但它在过去十年里没有任何改变。
|
||||
十年前我写了 [rrb][76] (反向 rsync 备份)重新封装了 `rsync` ,因此我只需要将备份服务器的 root SSH 权限授予正在备份的计算机。令人惊讶地是,尽管我一直在使用 rrb ,但它在过去十年里没有任何改变。
|
||||
|
||||
备份文件直接存储在文件系统中。使用硬链接实现增量备份 (`--link-dest`) 。一个简单的 [配置][77] 定义了备份保存时间,默认为:
|
||||
备份文件直接存储在文件系统中。使用硬链接实现增量备份(`--link-dest`)。一个简单的 [配置][77] 定义了备份保存时间,默认为:
|
||||
|
||||
```
|
||||
KEEP_RULES=( \
|
||||
7 7 \ # One backup a day for the last 7 days
|
||||
31 8 \ # 8 more backups for the last month
|
||||
7 7 \ # One backup a day for the last 7 days
|
||||
31 8 \ # 8 more backups for the last month
|
||||
365 11 \ # 11 more backups for the last year
|
||||
1825 4 \ # 4 more backups for the last 5 years
|
||||
1825 4 \ # 4 more backups for the last 5 years
|
||||
)
|
||||
```
|
||||
|
||||
@ -405,7 +415,7 @@ Host cr-remote
|
||||
Port 27276
|
||||
```
|
||||
|
||||
在谈论 SSH 攻击时,有时由于某些中断的路由会很难访问到服务器。在那种情况下你可以借道其他服务器的 SSH 连接,以获得更好的路由。在这种情况下,你可能通过美国连接访问到我的中国服务器,而来自德国的不可靠连接可能需要几个周:
|
||||
在谈及 SSH 技巧时,有时由于某些中断的路由会很难访问到服务器。在那种情况下你可以借道其他服务器的 SSH 连接,以获得更好的路由。在这种情况下,你可能通过美国连接访问到我的中国服务器,而来自德国的不可靠连接可能需要几个周:
|
||||
|
||||
```
|
||||
Host chn.ddnet.tw
|
||||
@ -426,7 +436,7 @@ via: https://hookrace.net/blog/linux-desktop-setup/
|
||||
作者:[Dennis Felsing][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[chenmu-kk](https://github.com/chenmu-kk)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
103
published/20190524 Dual booting Windows and Linux using UEFI.md
Normal file
103
published/20190524 Dual booting Windows and Linux using UEFI.md
Normal file
@ -0,0 +1,103 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12891-1.html)
|
||||
[#]: subject: (Dual booting Windows and Linux using UEFI)
|
||||
[#]: via: (https://opensource.com/article/19/5/dual-booting-windows-linux-uefi)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss/users/ckrzen)
|
||||
|
||||
使用 UEFI 双启动 Windows 和 Linux
|
||||
======
|
||||
|
||||
> 这是一份在同一台机器上设置 Linux 和 Windows 双重启动的速成解释,使用统一可扩展固件接口(UEFI)。
|
||||
|
||||

|
||||
|
||||
我将强调一些重要点,而不是一步一步地指导你来如何配置你的系统以实现双重启动。作为一个示例,我将提到我在几个月之前新买的笔记本计算机。我先是安装 [Ubuntu Linux][2] 到整个硬盘中,这就摧毁了预装的 [Windows 10][3] 环境。几个月后,我决定安装一个不同的 Linux 发行版 [Fedora Linux][4],也决定在双重启动配置中与它一起再次安装 Windows 10 。我将强调一些极其重要的实际情况。让我们开始吧!
|
||||
|
||||
### 固件
|
||||
|
||||
双重启动不仅仅是软件问题。或者说它算是软件的问题,因为它需要更改你的固件,以告诉你的机器如何开始启动程序。这里有一些和固件相关的重要事项要铭记于心。
|
||||
|
||||
#### UEFI vs BIOS
|
||||
|
||||
在尝试安装前,确保你的固件配置是最佳的。现在出售的大多数计算机有一个名为 <ruby>[统一可扩展固件接口][5]<rt>Unified Extensible Firmware Interface</rt></ruby> (UEFI)的新类型固件,UEFI 差不多取代了另一个名为 <ruby>[基本输入输出系统][6]<rt>Basic Input Output System</rt></ruby>(BIOS)的固件类型,(包括很多固件供应商在内的很多人)通常称 BIOS 为<ruby>传统启动模式<rt>Legacy Boot</rt></ruby>。
|
||||
|
||||
我不需要 BIOS,所以我选择了 UEFI 模式。
|
||||
|
||||
#### 安全启动
|
||||
|
||||
另一个重要的设置是<ruby>安全启动<rt>Secure Boot</rt></ruby>。这个功能将检测启动路径是否被篡改,并阻止未经批准的操作系统的启动。现在,我禁用这个选项来确保我能够安装 Fedora Linux 。依据 Fedora 项目维基“[功能/安全启动][7]”部分的介绍可知:Fedora Linux 在安全启动选项启用的时候也可以工作。这对其它的 Linux 发行版来说可能有所不同 — 我打算今后重新研究这项设置。
|
||||
|
||||
简而言之,如果你发现在这项设置启用时你不能安装你的 Linux 操作系统,那么禁用安全启动并再次重新尝试安装。
|
||||
|
||||
### 对启动驱动器进行分区
|
||||
|
||||
如果你选择双重启动并且两个操作系统都在同一个驱动器上,那么你必须将它分成多个分区。即使你使用两个不同的驱动器进行双重启动,出于各种各样的原因,大多数 Linux 环境也最好分成几个基本的分区。这里有一些选项值得考虑。
|
||||
|
||||
#### GPT vs MBR
|
||||
|
||||
如果你决定手动分区你的启动驱动器,在动手前,我建议使用<ruby>[GUID 分区表][8]<rt>GUID Partition Table</rt></ruby>(GPT),而不是使用旧的<ruby>[主启动记录][9]<rt>Master Boot Record</rt></ruby>(MBR) 。这种更改的原因之一是:MBR 有两个特定的限制,而 GPT 却没有:
|
||||
|
||||
* MBR 可以最多拥有 15 个分区,而 GPT 可以最多拥有 128 个分区。
|
||||
* MBR 最多仅支持 2 TB 磁盘,而 GPT 使用 64 位地址,这使得它最多支持 800 万 TB 的磁盘。
|
||||
|
||||
如果你最近购买过硬盘,那么你可能会知道现代的很多硬盘都超过了 2 TB 的限制。
|
||||
|
||||
#### EFI 系统分区
|
||||
|
||||
如果你正在进行一次全新的安装或使用一块新的驱动器,那么这里可能没有可以开始的分区。在这种情况下,操作系统安装程序将先创建一个分区,即<ruby>[EFI 系统分区][10]<rt>EFI System Partition</rt></ruby>(ESP)。如果你选择使用一个诸如 [gdisk][11] 之类的工具来手动分区你的驱动器,你将需要使用一些参数来创建这个分区。基于现有的 ESP ,我设置它为约 500 MB 的大小,并分配它为 `ef00`( EFI 系统 )分区类型。UEFI 规范要求格式化为 FAT32/msdos ,很可能是因为这种格式被大量的操作系统所支持。
|
||||
|
||||
![分区][12]
|
||||
|
||||
### 操作系统安装
|
||||
|
||||
在你完成先前的两个任务后,你就可以安装你的操作系统了。虽然我在这里关注的是 Windows 10 和 Fedora Linux ,当安装其它组合时的过程也是非常相似。
|
||||
|
||||
#### Windows 10
|
||||
|
||||
我开始 Windows 10 的安装,并创建了一个 20 GB 的 Windows 分区。因为我先前在我的笔记本计算机上安装了 Linux ,所以驱动器已经有了一个 ESP ,我选择保留它。我删除所有的现有 Linux 和交换分区来开始一次全新安装,然后开始我的 Windows 安装。Windows 安装程序自动创建另一个 16 MB 的小分区,称为 <ruby>[微软保留分区][13]<rt>Microsoft Reserved Partition</rt></ruby>(MSR)。在这完成后,在 512 GB 启动驱动器上仍然有大约 400 GB 的未分配空间。
|
||||
|
||||
接下来,我继续完成了 Windows 10 安装过程。随后我重新启动到 Windows 来确保它是工作的,在操作系统第一次启动时,创建我的用户账号,设置 Wi-Fi ,并完成其它必须的任务。
|
||||
|
||||
#### Fedora Linux
|
||||
|
||||
接下来,我将心思转移到安装 Linux 。我开始了安装过程,当安装进行到磁盘配置的步骤时,我确保不会更改 Windows NTFS 和 MSR 分区。我也不会更改 ESP ,但是我设置它的挂载点为 `/boot/efi`。然后我创建常用的 ext4 格式分区, `/`(根分区)、`/boot` 和 `/home`。我创建的最后一个分区是 Linux 的交换分区(swap)。
|
||||
|
||||
像安装 Windows 一样,我继续完成了 Linux 安装,随后重新启动。令我高兴的是,在启动时<ruby>[大一统启动加载程序][14]<rt>GRand Unified Boot Loader</rt></ruby>(GRUB)菜单提供选择 Windows 或 Linux 的选项,这意味着我不需要再做任何额外的配置。我选择 Linux 并完成了诸如创建我的用户账号等常规步骤。
|
||||
|
||||
### 总结
|
||||
|
||||
总体而言,这个过程是不难的,在过去的几年里,从 BIOS 过渡到 UEFI 有一些困难需要解决,加上诸如安全启动等功能的引入。我相信我们现在已经克服了这些障碍,可以可靠地设置多重启动系统。
|
||||
|
||||
我不再怀念 [Linux LOader][15](LILO)!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/5/dual-booting-windows-linux-uefi
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/alanfdoss/users/ckrzen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_keyboard_desktop.png?itok=I2nGw78_ (Linux keys on the keyboard for a desktop computer)
|
||||
[2]: https://www.ubuntu.com
|
||||
[3]: https://www.microsoft.com/en-us/windows
|
||||
[4]: https://getfedora.org
|
||||
[5]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface
|
||||
[6]: https://en.wikipedia.org/wiki/BIOS
|
||||
[7]: https://fedoraproject.org/wiki/Features/SecureBoot
|
||||
[8]: https://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||
[9]: https://en.wikipedia.org/wiki/Master_boot_record
|
||||
[10]: https://en.wikipedia.org/wiki/EFI_system_partition
|
||||
[11]: https://sourceforge.net/projects/gptfdisk/
|
||||
[12]: /sites/default/files/u216961/gdisk_screenshot_s.png
|
||||
[13]: https://en.wikipedia.org/wiki/Microsoft_Reserved_Partition
|
||||
[14]: https://en.wikipedia.org/wiki/GNU_GRUB
|
||||
[15]: https://en.wikipedia.org/wiki/LILO_(boot_loader)
|
164
published/20191118 Creating a Chat Bot with Recast.AI.md
Normal file
164
published/20191118 Creating a Chat Bot with Recast.AI.md
Normal file
@ -0,0 +1,164 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (alim0x)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12878-1.html)
|
||||
[#]: subject: (Creating a Chat Bot with Recast.AI)
|
||||
[#]: via: (https://opensourceforu.com/2019/11/creating-a-chat-bot-with-recast-ai/)
|
||||
[#]: author: (Athira Lekshmi C.V https://opensourceforu.com/author/athira-lekshmi/)
|
||||
|
||||
用 Recast.AI 创建一个聊天机器人
|
||||
======
|
||||
|
||||
[![][1]][2]
|
||||
|
||||
> 据 Gartner 2018 年 2 月的报告,“到 2020 年,25% 的客户服务和支持业务将在参与渠道中整合虚拟客户助理(VCA)或聊天机器人技术,而 2017 年只有不到 2%。”鉴于此,读者会发现本教程对理解开源的 Recast.AI 机器人创建平台的工作原理很有帮助。
|
||||
|
||||
聊天机器人,包括基于语音的以及其他技术的,已经实际使用了有一阵子了。从让用户参与谋杀解密游戏,到帮助完成房地产交易和医疗诊断,聊天机器人已经跨越了多个领域。
|
||||
|
||||
有许多平台可以让用户创建和部署机器人。Recast.AI(在被 SAP 收购之后现在是 SAP Conversational AI)是其中的先行者。
|
||||
|
||||
酷炫的界面、协作性以及它所提供的分析工具,让它成为流行的选择。
|
||||
|
||||
正如 Recast 官方网站说的,“它是一个创建、训练、部署和监控智能机器人的终极协作平台。”
|
||||
|
||||
### 创建一个基础的机器人
|
||||
|
||||
让我们来看看如何在 Recast 创建一个基础的机器人。
|
||||
|
||||
1. 在 https://cai.tools.sap 创建一个账户。注册可以使用电子邮箱或者 Github 账户。
|
||||
2. 在你登录之后,你会进入仪表板。点击右上角 “+” 新建机器人图标新建一个机器人。
|
||||
3. 在下一个界面,你会看到一系列可选的预定义技能。暂时选择<ruby>问候<rt>Greetings</rt></ruby>”(图 1)。这个机器人已经经过训练,能够理解基本的问候。
|
||||
![图 1: 设置机器人属性][3]
|
||||
4. 给机器人提供一个名字。目前来说,你可以让机器人讲一些笑话,所以我们将它命名为 Joke Bot,选择英语作为默认语言。
|
||||
5. 因为你不会处理任何敏感信息,所以在数据策略下选择非个人数据。然后选择公共机器人选项并点击创建一个机器人。
|
||||
|
||||
所以这就是你在 Recast 平台创建的机器人。
|
||||
|
||||
### 开发一个机器人的五个阶段
|
||||
|
||||
用 Recast 官方博客的话说,在机器人的生命中有五个阶段。
|
||||
|
||||
* 训练——教授机器人需要理解的内容
|
||||
* 构建——使用机器人构建工具创建你的对话流
|
||||
* 编写代码——将机器人连接到外部 API 或数据库
|
||||
* 连接——将机器人发布到一个或多个消息平台
|
||||
* 监控——训练机器人让它更敏锐,并且了解其使用情况
|
||||
|
||||
### 通过意图训练机器人
|
||||
|
||||
你可以在仪表板上看到搜索、分叉或创建一个<ruby>意图<rt>intent</rt></ruby>的选项。“‘意图’是一系列含义相同但构造不同的表达。‘意图’是你的机器人理解能力的核心。每个‘意图’代表了机器人可以理解的一种想法。”(摘自 Recast.AI 网站)
|
||||
|
||||
![图 2: 机器人面板][4]
|
||||
|
||||
就像先前定的,你需要一个讲笑话的机器人。所以底线是这个机器人可以理解用户在要求它讲笑话,它不应该在用户仅仅说了“Hi”的情况下回复一个笑话——这可不妙。把用户可能说的话进行分组,比如:
|
||||
|
||||
```
|
||||
Tell me a joke.(给我讲个笑话。)
|
||||
Tell me a funny fact.(告诉我一个有趣的事实。)
|
||||
Can you crack a joke?(你可以讲个笑话吗?)
|
||||
What’s funny today?(今天有什么有趣的?)
|
||||
```
|
||||
……
|
||||
|
||||
在继续从头开始创建意图之前,让我们来看看搜索/分叉选项。在搜索框输入 “Joke”(图 3)。系统给出了全球的 Recast 用户创建的公开的意图清单,这就是为什么说 Recast 天然就是协作性质的。所以其实没有必要从头开始创建所有的意图,可以在已经创建的基础上进行构建。这就降低了训练具有常见意图的机器人所需的投入。
|
||||
|
||||
![图 3: 搜索一个意图][5]
|
||||
|
||||
* 选择列表中的第一个意图并将其分叉到机器人上。
|
||||
* 点击<ruby>分叉<rt>Fork</rt></ruby>按钮。这个意图就添加到了机器人中(图 4)。
|
||||
![图 4: @joke 意图][6]
|
||||
* 点击意图 @joke,会显示出这个意图中已经存在的<ruby>表达<rt>expression</rt></ruby>列表(图 5)。
|
||||
![图 5: 预定义表达][7]
|
||||
* 向其添加更多的表达(图 6)。
|
||||
![图 6: 建议的表达][8]
|
||||
|
||||
添加了一些表达之后,机器人会给出一些建议,像图 7 展示的那样。选择几个将它们添加到意图中。你还可以根据机器人的上下文,标记你自己的自定义实体来检测关键词。
|
||||
|
||||
![图 7: 建议的表达][9]
|
||||
|
||||
### 技能
|
||||
|
||||
<ruby>技能<rt>skill</rt></ruby>是一块有明确目的的对话,机器人可以据此运行并达到目标。它可以像打招呼那么简单,也可以更复杂,比如基于用户提供的信息提供电影建议。
|
||||
|
||||
技能需要的不能只是一对问答,它需要多次交互。比如考虑一个帮你学习汇率的机器人。它一开始会问原货币,然后是目标货币,最后给出准确回应。结合技能可以创建复杂的对话流。
|
||||
|
||||
下面是如何给笑话机器人创建技能:
|
||||
|
||||
* 去到 构建(Build) 页。点击 “+” 图标创建技能。
|
||||
* 给技能命名 “Joke”(图 8)
|
||||
![图 8: 技能面板][10]
|
||||
* 创建之后,点击这个技能。你会看到四个标签。<ruby>读我<rt>Read me</rt></ruby>、<ruby>触发器<rt>Triggers</rt></ruby>、<ruby>需求<rt>Requirements</rt></ruby>和 <ruby>动作<rt>Actions</rt></ruby>。
|
||||
* 切换到需求页面。只有在笑话意图存在的时候,你才应该存储信息。所以,像图 9 那样添加一个需求。
|
||||
![图 9: 添加一个触发器][11]
|
||||
|
||||
由于这个简单的使用范例,你不需要在需求选项卡中考虑任何特定的需求,但可以考虑只有当某些关键字或实体出现时才需要触发响应的情况——在这种情况下你需要需求。
|
||||
|
||||
需求是某个技能执行动作之前需要检索的意图或实体。需求是对话中机器人可以使用的重要信息。例如用户的姓名或位置。一旦一个需求完成,相关的值就会存储在机器人的内存中,供整个对话使用。
|
||||
|
||||
现在让我们转到动作页面设置<ruby>回应<rt>response</rt></ruby>(参见图 10)。
|
||||
|
||||
![图 10: 添加动作][12]
|
||||
|
||||
点击添加<ruby>新消息组<rt>new message group</rt></ruby>。然后选择<ruby>发送消息<rt>Send message</rt></ruby>并添加一条文本消息,在这个例子中可以是任何笑话。当然,你肯定不想让你的机器人每次都说一样的笑话,你可以添加多条消息,每次从中随机选择一条。
|
||||
|
||||
![图 11: 添加文本消息][13]
|
||||
|
||||
### 频道集成
|
||||
|
||||
一个成功的机器人还依赖于它的易得性。Recast 有不少的内置消息频道集成,如 Skype for Business、Kik Messenger、Telegram、Line、Facebook Messenger、Slack、Alexa 等等。除此之外,Recast 还提供了 SDK 用于开发自定义的频道。
|
||||
|
||||
此外,Recast 还提供一个可立即使用的网页聊天(在连接页面中)。你可以自定义颜色主题、标题、机器人头像等。它给你提供了一个可以添加到页面的脚本标签。你的界面现在就可以使用了(图 12)。
|
||||
|
||||
![图 12: 设置网络聊天][14]
|
||||
|
||||
网页聊天的代码是开源的,开发者可以更方便地定制外观、标准回应类型等等。面板提供了如何将机器人部署到各种频道的逐步过程说明。这个笑话机器人部署在 Telegram 和网页聊天上,就像图 13 展示的那样。
|
||||
|
||||
![图 13: 网页聊天部署][15]
|
||||
|
||||
![图 14: Telegram 中开发的机器人][16]
|
||||
|
||||
### 还有更多
|
||||
|
||||
Recast 支持多语言,创建机器人的时候选择一个语言作为基础,但之后你有选项可以添加更多你想要的语言。
|
||||
|
||||
![图 15: 多语言机器人][17]
|
||||
|
||||
这里的例子是一个简单的静态笑话机器人,实际使用中可能需要更多的和不同系统的交互。Recast 有 Web 钩子功能,用户可以连接到不同的系统来获取回应。同时它还有详细的 API 文档来帮助使用平台的每个独立功能。
|
||||
|
||||
至于分析,Recast 有一个监控面板,帮助你了解机器人的准确度以及更加深入地训练机器人。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/11/creating-a-chat-bot-with-recast-ai/
|
||||
|
||||
作者:[Athira Lekshmi C.V][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/athira-lekshmi/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/04/Build-ChatBoat.jpg?resize=696%2C442&ssl=1 (Build ChatBoat)
|
||||
[2]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/04/Build-ChatBoat.jpg?fit=900%2C572&ssl=1
|
||||
[3]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-1-Setting-the-bot-properties.jpg
|
||||
[4]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-2-Setting-the-bot-properties.jpg
|
||||
[5]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-3-Searching-an-intent.jpg
|
||||
[6]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-4-@joke-intent.jpg
|
||||
[7]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-5-Predefined-expressions.jpg
|
||||
[8]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-6-Suggested-expressions.jpg
|
||||
[9]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-7-Suggested-expressions.jpg
|
||||
[10]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-8-Skills-dashboard.jpg
|
||||
[11]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-9-Adding-a-trigger.jpg
|
||||
[12]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-10-Adding-actions.jpg
|
||||
[13]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-11-Adding-text-messages.jpg
|
||||
[14]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-12-Setting-up-webchat.jpg
|
||||
[15]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-13-Webchat-deployed.jpg
|
||||
[16]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-14-Bot-deployed-in-Telegram.jpg
|
||||
[17]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-15-Multi-language-bot.jpg
|
||||
[18]: https://secure.gravatar.com/avatar/d24503a2a0bb8bd9eefe502587d67323?s=100&r=g
|
||||
[19]: https://opensourceforu.com/author/athira-lekshmi/
|
||||
[20]: https://opensourceforu.com/wp-content/uploads/2019/11/assoc.png
|
||||
[21]: https://feedburner.google.com/fb/a/mailverify?uri=LinuxForYou&loc=en_US
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12886-1.html)
|
||||
[#]: subject: (scanimage: scan from the command line!)
|
||||
[#]: via: (https://jvns.ca/blog/2020/07/11/scanimage--scan-from-the-command-line/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
@ -10,15 +10,17 @@
|
||||
scanimage:从命令行扫描!
|
||||
======
|
||||
|
||||

|
||||
|
||||
这又是一篇关于我很喜欢的一个命令行工具的文章。
|
||||
|
||||
昨晚,出于官僚原因,我需要扫描一些文档。我以前从来没有在 Linux 上使用过扫描仪,我担心会花上好几个小时才弄明白。我从使用 `gscan2pdf` 开始,但在用户界面上遇到了麻烦。我想同时扫描两面(我知道我们的扫描仪支持),但无法使它工作。
|
||||
|
||||
### 遇到 scanimage!
|
||||
|
||||
`scanimage` 是一个命令行工具,在 `sane-utils` Debian 软件包中。我想所有的 Linux 扫描工具都使用 `sane` (”scanner access now easy“) 库,所以我猜测它和其他扫描软件有类似的能力。在这里,我不需要 OCR,所以我们不打算谈论 OCR。
|
||||
`scanimage` 是一个命令行工具,在 `sane-utils` Debian 软件包中。我想所有的 Linux 扫描工具都使用 `sane` (“scanner access now easy”) 库,所以我猜测它和其他扫描软件有类似的能力。在这里,我不需要 OCR,所以我不打算谈论 OCR。
|
||||
|
||||
### 用 `scanimage -L` 得到你的扫描仪的名字
|
||||
### 用 scanimage -L 得到你的扫描仪的名字
|
||||
|
||||
`scanimage -L` 列出了你所有的扫描设备。
|
||||
|
||||
@ -26,7 +28,7 @@ scanimage:从命令行扫描!
|
||||
|
||||
插上后,它马上就能工作了。显然我们的扫描仪叫 `fujitsu:ScanSnap S1500:2314`。万岁!
|
||||
|
||||
### 用 `--help` 列出你的扫描仪选项
|
||||
### 用 --help 列出你的扫描仪选项
|
||||
|
||||
显然每个扫描仪有不同的选项(有道理!),所以我运行这个命令来获取我的扫描仪的选项:
|
||||
|
||||
@ -60,6 +62,7 @@ convert *.png $CUR/$1
|
||||
### 这真是太简单了!
|
||||
|
||||
我一直以为在 Linux 上使用打印机/扫描仪是一个噩梦,我真的很惊讶 `scanimage` 可以工作。我可以直接运行我的脚本 `scan-single-sided receipts.pdf`,它将扫描文档并将其保存到 `receipts.pdf`!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2020/07/11/scanimage--scan-from-the-command-line/
|
||||
@ -67,7 +70,7 @@ via: https://jvns.ca/blog/2020/07/11/scanimage--scan-from-the-command-line/
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12877-1.html)
|
||||
[#]: subject: (Add sound to your Python game)
|
||||
[#]: via: (https://opensource.com/article/20/9/add-sound-python-game)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
> 通过添加声音到你的游戏中,听听当你的英雄战斗、跳跃、收集战利品时会发生什么。学习如何在这个 Pygame 系列的第十三篇文章中,创建一个声音平台类精灵。
|
||||
|
||||
![彩色声波图][1]
|
||||

|
||||
|
||||
在 [Python 3][2] 中使用 [Pygame][3] 模块来创建电脑游戏的系列文章仍在进行中,这是第十三部分。先前的文章是:
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
9. [使你的 Python 游戏玩家能够向前和向后跑][12]
|
||||
10. [在你的 Python 平台类游戏中放一些奖励][13]
|
||||
11. [添加计分到你的 Python 游戏][14]
|
||||
12. [在你的 Python 游戏中加入投掷技巧][15]
|
||||
12. [在你的 Python 游戏中加入投掷机制][15]
|
||||
|
||||
Pygame 提供了一种简单的方法来集成声音到你的 Python 电脑游戏中。Pygame 的 [mixer 模块][16] 可以依据命令播放一个或多个声音,并且你也可以将这些声音混合在一起,例如,你能够在听到你的英雄收集奖励或跳过敌人声音的同时播放背景音乐。
|
||||
|
||||
@ -144,7 +144,7 @@ via: https://opensource.com/article/20/9/add-sound-python-game
|
||||
[12]: https://linux.cn/article-11819-1.html
|
||||
[13]: https://linux.cn/article-11828-1.html
|
||||
[14]: https://linux.cn/article-11839-1.html
|
||||
[15]: https://opensource.com/article/20/9/add-throwing-python-game
|
||||
[15]: https://linux.cn/article-12872-1.html
|
||||
[16]: https://www.pygame.org/docs/ref/mixer.html
|
||||
[17]: https://opensource.com/article/20/1/what-creative-commons
|
||||
[18]: https://freesound.org
|
189
published/20201026 7 Git tricks that changed my life.md
Normal file
189
published/20201026 7 Git tricks that changed my life.md
Normal file
@ -0,0 +1,189 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12894-1.html)
|
||||
[#]: subject: (7 Git tricks that changed my life)
|
||||
[#]: via: (https://opensource.com/article/20/10/advanced-git-tips)
|
||||
[#]: author: (Rajeev Bera https://opensource.com/users/acompiler)
|
||||
|
||||
改变我使用 Git 工作方式的七个技巧
|
||||
======
|
||||
|
||||
> 这些有用的技巧将改变你使用这个流行的版本控制系统的工作方式。
|
||||
|
||||

|
||||
|
||||
Git 是目前最常见的版本控制系统之一,无论是私有系统还是公开托管的网站,都在使用它进行各种开发工作。但无论我对 Git 的使用有多熟练,似乎总有一些功能还没有被发现,下面是改变我使用 Git 工作方式的七个技巧。
|
||||
|
||||
### 1、Git 中的自动更正
|
||||
|
||||
我们有时都会打错字,但如果启用了 Git 的自动更正功能,就可以让 Git 自动修正打错的子命令。
|
||||
|
||||
假设你想用 `git status` 检查状态,却不小心输入了 `git stats`。正常情况下,Git 会告诉你 `stats` 不是一条有效的命令:
|
||||
|
||||
```
|
||||
$ git stats
|
||||
git: ‘stats’ is not a git command. See ‘git --help’.
|
||||
|
||||
The most similar command is
|
||||
status
|
||||
```
|
||||
|
||||
为了避免类似的情况发生,请在 Git 配置中启用 Git 自动更正功能:
|
||||
|
||||
```
|
||||
$ git config --global help.autocorrect 1
|
||||
```
|
||||
|
||||
如果你希望这个命令只适用于你当前的版本库,请省略 `--global` 选项。
|
||||
|
||||
这条命令启用了自动更正功能。更深入的教程可以在 [Git Docs][2] 中找到,但尝试一下和上面一样的错误命令,就能很好地了解这个配置的作用:
|
||||
|
||||
```
|
||||
$ git stats
|
||||
git: ‘stats’ is not a git command. See ‘git --help’.
|
||||
On branch master
|
||||
Your branch is up to date with ‘origin/master’.
|
||||
|
||||
nothing to commit, working tree clean
|
||||
```
|
||||
|
||||
Git 现在不会建议使用其他子命令,而是直接运行最上面的建议,在本例中是 `git status`。
|
||||
|
||||
### 2、计算你的提交量
|
||||
|
||||
你需要计算提交数量可能有很多原因。例如,许多开发者通过计算提交数量来判断何时该增加构建版本号,或者只是想了解项目的进展情况。
|
||||
|
||||
要计算提交数量其实很简单直接,下面是 Git 的命令:
|
||||
|
||||
```
|
||||
$ git rev-list --count branch-name
|
||||
```
|
||||
|
||||
在上面的命令中,`branch-name` 应该是当前版本库中有效的分支名称:
|
||||
|
||||
```
|
||||
$ git rev-list –count master
|
||||
32
|
||||
$ git rev-list –count dev
|
||||
34
|
||||
```
|
||||
|
||||
### 3、优化你的仓库
|
||||
|
||||
你的代码仓库不仅对你有价值,对你的组织也有价值。你可以通过一些简单的做法来保持你的版本库的清洁和更新。其中一个最好的做法是 [使用 .gitignore 文件][3]。使用这个文件,就是告诉 Git 不要存储许多不需要的文件,比如二进制文件、临时文件等等。
|
||||
|
||||
为了进一步优化你的版本库,你可以使用 Git 的垃圾收集功能:
|
||||
|
||||
```
|
||||
$ git gc --prune=now --aggressive
|
||||
```
|
||||
|
||||
当你或你的团队大量使用 `pull` 或 `push` 命令时,这条命令就会起到帮助作用。
|
||||
|
||||
这个命令是一个内部工具,可以清理仓库中无法访问或 “孤儿” Git 对象。
|
||||
|
||||
### 4、备份未被跟踪的文件
|
||||
|
||||
大多数时候,删除所有未被跟踪的文件是安全的。不过很多时候,你不仅要删除,还要为你的未跟踪文件创建一个备份,以备以后需要。
|
||||
|
||||
通过 Git 和一些 Bash 命令管道,可以很容易地为你的未被跟踪的文件创建一个压缩包:
|
||||
|
||||
```
|
||||
$ git ls-files --others --exclude-standard -z |\
|
||||
xargs -0 tar rvf ~/backup-untracked.zip
|
||||
```
|
||||
|
||||
上面的命令制作了一个名为 `backup-untracked.zip` 的存档(并排除了 `.gitignore` 中列出的文件)。
|
||||
|
||||
### 5、了解你的 .git 文件夹
|
||||
|
||||
每个版本库都有一个 `.git` 文件夹。它是一个特殊的隐藏文件夹。
|
||||
|
||||
```
|
||||
$ ls -a
|
||||
. … .git
|
||||
```
|
||||
|
||||
Git 的工作主要依赖于两个部分:
|
||||
|
||||
1. 工作树(你当前签出的文件状态)。
|
||||
2. 你的 Git 仓库的路径(即你的 `.git` 文件夹的位置,其中包含版本信息)。
|
||||
|
||||
这个文件夹存储了所有的引用和其他重要的细节,比如配置、仓库数据、HEAD 状态、日志等等。
|
||||
|
||||
如果你删除这个文件夹,你的源代码的当前状态不会被删除,但你的远程信息,如你的项目历史记录,会被删除。删除这个文件夹意味着你的项目(至少是本地副本)不再处于版本控制之下。这意味着你不能跟踪你的变化;你不能从远程拉取或推送。
|
||||
|
||||
一般来说,不需要在 `.git` 文件夹里做什么,也没有什么应该做的。它是由 Git 管理的,基本上被认为是个禁区。然而,这个目录里有一些有趣的工件,包括 HEAD 的当前状态。
|
||||
|
||||
```
|
||||
$ cat .git/HEAD
|
||||
ref: refs/heads/master
|
||||
```
|
||||
|
||||
它还可能包含对你的存储库的描述:
|
||||
|
||||
```
|
||||
$ cat .git/description
|
||||
```
|
||||
|
||||
这是一个未命名的仓库,编辑这个 `description` 文件可以命名这个仓库。
|
||||
|
||||
Git 钩子文件夹(`hooks`)也在这里,里面有一些钩子示例文件。你可以阅读这些示例来了解通过 Git 钩子可以实现什么,你也可以 [阅读 Seth Kenlon 的 Git 钩子介绍][4]。
|
||||
|
||||
### 6、查看另一个分支的文件
|
||||
|
||||
有时你想查看另一个分支的文件的内容。用一个简单的 Git 命令就可以实现,而且不需要切换分支。
|
||||
|
||||
假设你有一个名为 [README.md][5] 的文件,它在 `main` 分支中,而你正在 `dev` 分支上工作。
|
||||
|
||||
使用下面的 Git 命令,你可以在终端上完成:
|
||||
|
||||
```
|
||||
$ git show main:README.md
|
||||
```
|
||||
|
||||
一旦你执行了这个命令,你就可以在你的终端上查看文件的内容。
|
||||
|
||||
### 7、在 Git 中搜索
|
||||
|
||||
只需一个简单的命令,你就可以像专业人士一样在 Git 中搜索。更棒的是,即使你不确定是在哪个提交或分支上做的修改,也可以在 Git 中搜索。
|
||||
|
||||
```
|
||||
$ git rev-list --all | xargs git grep -F 'string'
|
||||
```
|
||||
|
||||
例如,假设你想在你的版本库中搜索 `font-size: 52 px;` 这个字符串:
|
||||
|
||||
```
|
||||
$ git rev-list –all | xargs git grep -F 'font-size: 52 px;'
|
||||
F3022…9e12:HtmlTemplate/style.css: font-size: 52 px;
|
||||
E9211…8244:RR.Web/Content/style/style.css: font-size: 52 px;
|
||||
```
|
||||
|
||||
### 试试这些技巧
|
||||
|
||||
希望这些高级技巧对你有用,提高你的工作效率,为你节省很多时间。
|
||||
|
||||
你有喜欢的 [Git 小技巧][6] 吗?在评论中分享吧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/10/advanced-git-tips
|
||||
|
||||
作者:[Rajeev Bera][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/acompiler
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_screen_windows_files.png?itok=kLTeQUbY (Computer screen with files or windows open)
|
||||
[2]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_code_help_autocorrect_code
|
||||
[3]: https://linux.cn/article-12524-1.html
|
||||
[4]: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
|
||||
[5]: http://README.md
|
||||
[6]: https://acompiler.com/git-tips/
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12880-1.html)
|
||||
[#]: subject: (How to rebase to Fedora 33 on Silverblue)
|
||||
[#]: via: (https://fedoramagazine.org/how-to-rebase-to-fedora-33-on-silverblue/)
|
||||
[#]: author: (Michal Konečný https://fedoramagazine.org/author/zlopez/)
|
||||
@ -10,9 +10,9 @@
|
||||
如何在 Silverblue 上变基到 Fedora 33?
|
||||
======
|
||||
|
||||
![][1]
|
||||

|
||||
|
||||
Silverblue 是[一个建立在 Fedora 上的桌面操作系统][2]。它非常适合日常使用、开发和基于容器的工作流程。它提供了[众多的优势][3],例如在出现任何问题时能够回滚。如果你想在你的 Silverblue 系统上更新到 Fedora 33,这篇文章会告诉你如何做。它不仅告诉你该怎么做,还告诉你如果发生了不可预见的事情时该如何回退。
|
||||
Silverblue 是[一个建立在 Fedora 之上的桌面操作系统][2]。它非常适合日常使用、开发和基于容器的工作流程。它提供了[众多的优势][3],例如在出现任何问题时能够回滚。如果你想在你的 Silverblue 系统上更新到 Fedora 33,这篇文章会告诉你如何做。它不仅告诉你该怎么做,还告诉你如果发生了不可预见的事情时该如何回退。
|
||||
|
||||
在实际做变基到 Fedora 33 之前,你应该应用任何挂起的更新。在终端中输入以下内容:
|
||||
|
||||
@ -28,15 +28,15 @@ GNOME 软件中心会在更新界面显示有新版本的 Fedora 可用。
|
||||
|
||||
![Fedora 33 is available][4]
|
||||
|
||||
首先你需要做的是下载新镜像,点击 _Download_ 按钮。这将需要一些时间,完成后你会看到更新已经准备好安装了。
|
||||
首先你需要做的是下载新镜像,点击 “Download” 按钮。这将需要一些时间,完成后你会看到更新已经准备好安装了。
|
||||
|
||||
![Fedora 33 is ready for installation][5]
|
||||
|
||||
点击 _Install_ 按钮。这一步只需要几分钟,然后会提示你重启电脑。
|
||||
点击 “Install” 按钮。这一步只需要几分钟,然后会提示你重启电脑。
|
||||
|
||||
![Restart is needed to rebase to Fedora 33 Silverblue][6]
|
||||
|
||||
点击 _Restart_ 按钮就可以了。重启后,你将进入新的 Fedora 33 版本。很简单,不是吗?
|
||||
点击 “Restart” 按钮就可以了。重启后,你将进入新的 Fedora 33 版本。很简单,不是吗?
|
||||
|
||||
### 使用终端变基
|
||||
|
||||
@ -79,7 +79,7 @@ via: https://fedoramagazine.org/how-to-rebase-to-fedora-33-on-silverblue/
|
||||
作者:[Michal Konečný][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12884-1.html)
|
||||
[#]: subject: (Day 1: a confusing Rails error message)
|
||||
[#]: via: (https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
@ -10,7 +10,9 @@
|
||||
Rails 之旅第 1 天:一个令人困惑的 Rails 错误信息
|
||||
======
|
||||
|
||||
今天,我开始了一个 Recurse Center 的批次学习!我认识了一些人,并开始了一个小小的有趣的 Rails 项目。我想我今天不会谈太多关于这个项目的实际内容,但这里有一些关于 Rails 一天的快速笔记。
|
||||

|
||||
|
||||
今天,我开始了一个 Recurse Center 的班次学习!我认识了一些人,并开始了一个小小的有趣的 Rails 项目。我想我今天不会谈太多关于这个项目的实际内容,但这里有一些关于 Rails 一天的快速笔记。
|
||||
|
||||
### 一些关于开始的笔记
|
||||
|
@ -0,0 +1,117 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12890-1.html)
|
||||
[#]: subject: (Day 2: Rails associations & dragging divs around)
|
||||
[#]: via: (https://jvns.ca/blog/2020/11/10/day-2--rails-associations---dragging-divs-around/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
Rails 之旅第 2 天:Rails 关联和拖动 div
|
||||
======
|
||||
|
||||

|
||||
|
||||
大家好!今天是我搭建这个玩具项目的第 2 天。下面再来记录一下关于 Rails 的一些有趣的事情吧!
|
||||
|
||||
### 目标:做一个冰箱诗歌论坛
|
||||
|
||||
我想做一种无聊的标准网站来学习 Rails,并且其他人可以与之互动,就像一个论坛一样! 但如果人们真的可以在网站上打字,那就会产生各种各样的问题(如果他们是垃圾邮件发送者怎么办?又或者只是言语刻薄?)。
|
||||
|
||||
我想到的第一个想法是,可以让人们与网站互动,但实际上却不能在网站上打字,那就是一个“冰箱诗歌论坛”,只给你一组固定的字,你就可以随意组合。
|
||||
|
||||
所以,这就是我们的计划!
|
||||
|
||||
我这个项目的目标是想知道我是否能用 Rails 来做其他的小型网络项目(而不是像我通常做的那样,使用一些更基本的东西,比如 Flask,或者放弃后端,用 Javascript 来写所有东西)。
|
||||
|
||||
### 怎么把字拖来拖去呢?jQuery 的可拖放 UI!
|
||||
|
||||
我想让大家能够把文字拖动起来,但我又不想写很多 Javascript。结果发现这超级简单 —— 有一个 jQuery 库可以做到,它叫做 `draggable`!一开始,拖动并不成功。
|
||||
|
||||
一开始拖动在手机上是不行的,但是有一个技巧可以让 jQuery UI 在手机上工作,叫做 [jQuery UI touch punch][1]。下面是它的样子(有兴趣看工作原理的可以查看源码,代码很少)。
|
||||
|
||||
> `banana` `forest` `cake` `is`
|
||||
|
||||
### 一个有趣的 Rails 功能:关联
|
||||
|
||||
我以前从来没有使用过关系型 ORM,对于 Rails,我很兴奋的一件事就是想看看使用 Active Record 是什么样子的!今天我了解了 Rails 的 ORM 功能之一:[关联][2]。如果你像我一样对 ORM 完全不了解的话,那就来看看是怎么回事吧。
|
||||
|
||||
在我的论坛中,我有:
|
||||
|
||||
* 用户
|
||||
* 话题(我本来想把它叫做“线索”,但显然这在 Rails 中是一个保留词,所以现在叫做“话题”)。
|
||||
* 帖子
|
||||
|
||||
当显示一个帖子时,我需要显示创建该帖子的用户的用户名。所以我想我可能需要写一些代码来加载帖子,并为每个帖子加载用户,就像这样(在 Rails 中,`Post.where` 和 `User.find` 将会运行 SQL 语句,并将结果转化为 Ruby 对象):
|
||||
|
||||
```
|
||||
@posts = Post.where(topic_id: id)
|
||||
@posts.each do |post|
|
||||
user = User.find(post.user_id)
|
||||
post.user = user
|
||||
end
|
||||
```
|
||||
|
||||
这还不够好,它要为每个帖子做一次单独的 SQL 查询!我知道有一个更好的方法,我发现它叫做[关联][2]。这个链接是来自 <https://guides.rubyonrails.org> 的指南,到目前为止,它对我很有帮助。
|
||||
|
||||
基本上我需要做的就是:
|
||||
|
||||
1. 在 `User` 模型中添加一行 `has_many :post`。
|
||||
2. 在 `Post` 模型中添加一行 `belongs_to :user`。
|
||||
3. Rails 现在知道如何将这两个表连接起来,尽管我没有告诉它要连接到什么列上!我认为这是因为我按照它所期望的惯例命名了 `posts` 表中的 `user_id` 列。
|
||||
4. 对 `User` 和 `Topic` 做完全相同的事情(一个主题也有很多帖子:`has_many :posts`)。
|
||||
|
||||
然后我加载每一个帖子和它的关联用户的代码就变成了只有一行! 就是这一行:
|
||||
|
||||
```
|
||||
@posts = @topic.posts.order(created_at: :asc).preload(:user)
|
||||
```
|
||||
|
||||
比起只有一行更重要的是,它不是单独做一个查询来获取每个帖子的用户,而是在 1 个查询中获取所有用户。显然,在 Rails 中,有一堆[不同的方法][3]来做类似的事情(预加载、急切加载、联接和包含?),我还不知道这些都是什么,但也许我以后会知道的。
|
||||
|
||||
### 一个有趣的 Rails 功能:脚手架!
|
||||
|
||||
Rails 有一个叫 `rails` 的命令行工具,它可以生成很多代码。例如,我想添加一个 `Topic` 模型/控制器。我不用去想在哪里添加所有的代码,可以直接运行
|
||||
|
||||
```
|
||||
rails generate scaffold Topic title:text
|
||||
```
|
||||
|
||||
并生成了一堆代码,这样我已经有了基本的端点来创建/编辑/删除主题(`Topic`)。例如,这是我的[现在的主题控制器][4],其中大部分我没有写(我只写了高亮的 3 行)。我可能会删除很多内容,但是有一个起点,让我可以扩展我想要的部分,删除我不想要的部分,感觉还不错。
|
||||
|
||||
### 数据库迁移!
|
||||
|
||||
`rails` 工具还可以生成数据库迁移! 例如,我决定要删除帖子中的 `title` 字段。
|
||||
|
||||
下面是我要做的:
|
||||
|
||||
```
|
||||
rails generate migration RemoveTitleFromPosts title:string
|
||||
rails db:migrate
|
||||
```
|
||||
|
||||
就是这样 —— 只要运行几个命令行咒语就可以了! 我运行了几个这样的迁移,因为我改变了对我的数据库模式的设想。它是相当直接的,到目前为止 —— 感觉很神奇。
|
||||
|
||||
当我试图在一列中的某些字段为空的地方添加一个“不为空”(`not null`)约束时,情况就变得有点有趣了 —— 迁移失败。但我可以修复违例的记录,并轻松地重新运行迁移。
|
||||
|
||||
### 今天就到这里吧!
|
||||
|
||||
明天,如果我有更多的进展,也许我会把它放在互联网上。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2020/11/10/day-2--rails-associations---dragging-divs-around/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/furf/jquery-ui-touch-punch
|
||||
[2]: https://guides.rubyonrails.org/association_basics.html
|
||||
[3]: https://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html
|
||||
[4]: https://github.com/jvns/refrigerator-forum/blob/776b3227cfd7004cb1efb00ec7e3f82a511cbdc4/app/controllers/topics_controller.rb#L13-L15
|
@ -0,0 +1,242 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12900-1.html)
|
||||
[#]: subject: (How to use Serializers in the Django Python web framework)
|
||||
[#]: via: (https://opensource.com/article/20/11/django-rest-framework-serializers)
|
||||
[#]: author: (Renato Oliveira https://opensource.com/users/renato-oliveira)
|
||||
|
||||
如何在 Python Web 框架 Django 中使用序列化器
|
||||
======
|
||||
|
||||
> 序列化用于将数据转换为方便存储或传输的格式,然后将其重新构建以供使用。DRF 是最具有知名的序列化器。
|
||||
|
||||

|
||||
|
||||
序列化是将数据转换为可以存储或传输的格式,然后对其进行重新构建的过程。在开发应用程序或将数据存储在数据库、内存或将其转换为文件时,一直会用到它。
|
||||
|
||||
我最近帮助 [Labcodes][2] 的两名初级开发人员理解序列化器,我想也可以与诸位读者分享一下我的方法。
|
||||
|
||||
假设你正在编写一个电子商务网站,你有一个订单,该订单记录了某人在某个日期以某种价格购买了一个产品:
|
||||
|
||||
```
|
||||
class Order:
|
||||
def __init__(self, product, customer, price, date):
|
||||
self.product = product
|
||||
self.customer = customer
|
||||
self.price = price
|
||||
self.date = date
|
||||
```
|
||||
|
||||
现在,假设你想从一个键值数据库中存储和检索订单数据。幸运的是,它的接口可以接受和返回字典,因此你需要将对象转换成字典:
|
||||
|
||||
```
|
||||
def serialize_order(order):
|
||||
return {
|
||||
'product': order.product,
|
||||
'customer': order.customer,
|
||||
'price': order.price,
|
||||
'date': order.date
|
||||
}
|
||||
```
|
||||
|
||||
如果你想从数据库中获取一些数据,你可以获取字典数据并将其转换为订单对象(`Order`):
|
||||
|
||||
```
|
||||
def deserialize_order(order_data):
|
||||
return Order(
|
||||
product=order_data['product'],
|
||||
customer=order_data['customer'],
|
||||
price=order_data['price'],
|
||||
date=order_data['date'],
|
||||
)
|
||||
```
|
||||
|
||||
这对于简单的数据非常直接了当,但是当你需要处理一些由复杂属性构成的复杂对象时,这种方法就无法很好地扩展。你还需要处理不同类型字段的验证,这需要手工完成大量工作。
|
||||
|
||||
此时框架的序列化可以很方便的派上用场。它们使你可以创建带有少量模板的序列化器,这将适用于复杂的情况。
|
||||
|
||||
[Django][3] 提供了一个序列化模块,允许你将模型“转换”为其它格式:
|
||||
|
||||
```
|
||||
from django.core import serializers
|
||||
|
||||
serializers.serialize('json', Order.objects.all())
|
||||
```
|
||||
|
||||
它涵盖了 Web 应用程序最常用的种类,例如 JSON、YAML 和 XML。但是你也可以使用第三方序列化器或创建自己的序列化器。你只需要在 `settings.py` 文件中注册它:
|
||||
|
||||
```
|
||||
# settings.py
|
||||
SERIALIZATION_MODULES = {
|
||||
'my_format': appname.serializers.MyFormatSerializer,
|
||||
}
|
||||
```
|
||||
|
||||
要创建自己的 `MyFormatSerializer`,你需要实现 `.serialize()` 方法并接受一个查询集和其它选项作为参数:
|
||||
|
||||
```
|
||||
class MyFormatSerializer:
|
||||
def serialize(self, queryset, **options):
|
||||
# serious serialization happening
|
||||
```
|
||||
|
||||
现在,你可以将查询集序列化为新格式:
|
||||
|
||||
```
|
||||
from django.core import serializers
|
||||
|
||||
serializers.serialize('my_format', Order.objects.all())
|
||||
```
|
||||
|
||||
你可以使用选项参数来定义序列化程序的行为。例如,如果要定义在处理 `ForeignKeys` 时要使用嵌套序列化,或者只希望数据返回其主键,你可以传递一个 `flat=True` 参数作为选项,并在方法中处理:
|
||||
|
||||
```
|
||||
class MyFormatSerializer:
|
||||
def serializer(self, queryset, **options):
|
||||
if options.get('flat', False):
|
||||
# don't recursively serialize relationships
|
||||
# recursively serialize relationships
|
||||
```
|
||||
|
||||
使用 Django 序列化的一种方法是使用 `loaddata` 和 `dumpdata` 管理命令。
|
||||
|
||||
### DRF 序列化器
|
||||
|
||||
在 Django 社区中,[Django REST 框架][4](DRF)提供了最著名的序列化器。尽管你可以使用 Django 的序列化器来构建将在 API 中响应的 JSON,但 REST 框架中的序列化器提供了更出色的功能,可以帮助你处理并轻松验证复杂的数据。
|
||||
|
||||
在订单的例子中,你可以像这样创建一个序列化器:
|
||||
|
||||
```
|
||||
from restframework import serializers
|
||||
|
||||
class OrderSerializer(serializers.Serializer):
|
||||
product = serializers.CharField(max_length=255)
|
||||
customer = serializers.CharField(max_lenght=255)
|
||||
price = serializers.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = serializers.DateField()
|
||||
```
|
||||
|
||||
轻松序列化其数据:
|
||||
|
||||
```
|
||||
order = Order('pen', 'renato', 10.50, date.today())
|
||||
serializer = OrderSerializer(order)
|
||||
|
||||
serializer.data
|
||||
# {'product': 'pen', 'customer': 'renato', 'price': '10.50', 'date': '2020-08-16'}
|
||||
```
|
||||
|
||||
为了能够从数据返回实例,你需要实现两个方法:`create` 和 `update`:
|
||||
|
||||
```
|
||||
from rest_framework import serializers
|
||||
|
||||
class OrderSerializer(serializers.Serializer):
|
||||
product = serializers.CharField(max_length=255)
|
||||
customer = serializers.CharField(max_length=255)
|
||||
price = serializers.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = serializers.DateField()
|
||||
|
||||
def create(self, validated_data):
|
||||
# 执行订单创建
|
||||
return order
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
# 执行实例更新
|
||||
return instance
|
||||
```
|
||||
|
||||
之后,你可以通过调用 `is_valid()` 来验证数据,并通过调用 `save()` 来创建或更新实例:
|
||||
|
||||
```
|
||||
serializer = OrderSerializer(**data)
|
||||
## 若要验证数据,在调用 save 之前必须执行
|
||||
serializer.is_valid()
|
||||
serializer.save()
|
||||
```
|
||||
|
||||
### 模型序列化器
|
||||
|
||||
序列化数据时,通常需要从数据库(即你创建的模型)进行数据处理。`ModelSerializer` 与 `ModelForm` 一样,提供了一个 API,用于从模型创建序列化器。假设你有一个订单模型:
|
||||
|
||||
```
|
||||
from django.db import models
|
||||
|
||||
class Order(models.Model):
|
||||
product = models.CharField(max_length=255)
|
||||
customer = models.CharField(max_length=255)
|
||||
price = models.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = models.DateField()
|
||||
```
|
||||
|
||||
你可以像这样为它创建一个序列化器:
|
||||
|
||||
```
|
||||
from rest_framework import serializers
|
||||
|
||||
class OrderSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = '__all__'
|
||||
```
|
||||
|
||||
Django 会自动在序列化器中包含所有模型字段,并创建 `create` 和 `udpate` 方法。
|
||||
|
||||
### 在基于类的视图(CBV)中使用序列化器
|
||||
|
||||
像 Django CBV 中的 `Forms` 一样,序列化器可以很好地与 DRF 集成。你可以设置 `serializer_class` 属性,方便序列化器用于视图:
|
||||
|
||||
```
|
||||
from rest_framework import generics
|
||||
|
||||
class OrderListCreateAPIView(generics.ListCreateAPIView):
|
||||
queryset = Order.objects.all()
|
||||
serializer_class = OrderSerializer
|
||||
```
|
||||
|
||||
你也可以定义 `get_serializer_class()` 方法:
|
||||
|
||||
```
|
||||
from rest_framework import generics
|
||||
|
||||
class OrderListCreateAPIView(generics.ListCreateAPIView):
|
||||
queryset = Order.objects.all()
|
||||
|
||||
def get_serializer_class(self):
|
||||
if is_free_order():
|
||||
return FreeOrderSerializer
|
||||
return OrderSerializer
|
||||
```
|
||||
|
||||
在 CBV 中还有其它与序列化器交互的方法。例如,[get_serializer()][5] 返回一个已经实例化的序列化器,[get_serializer_context()][6] 返回创建实例时传递给序列化器的参数。对于创建或更新数据的视图,有 `create` 和 `update`,它们使用 `is_valid` 方法验证数据,还有 [perform_create][7] 和 [perform_update][8] 调用序列化器的 `save` 方法。
|
||||
|
||||
### 了解更多
|
||||
|
||||
要了解更多资源,参考我朋友 André Ericson 的[经典 Django REST 框架][9]网站。它是一个[基于类的经典视图][10]的 REST 框架版本,可让你深入查看组成 DRF 的类。当然,官方[文档][11]也是一个很棒的资源。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/11/django-rest-framework-serializers
|
||||
|
||||
作者:[Renato Oliveira][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/renato-oliveira
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_analytics_cloud.png?itok=eE4uIoaB (Net catching 1s and 0s or data in the clouds)
|
||||
[2]: http://www.labcodes.com.br
|
||||
[3]: https://www.djangoproject.com/
|
||||
[4]: https://www.django-rest-framework.org/
|
||||
[5]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#get_serializer
|
||||
[6]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#get_serializer_context
|
||||
[7]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#perform_create
|
||||
[8]: http://www.cdrf.co/3.9/rest_framework.generics/RetrieveUpdateAPIView.html#perform_update
|
||||
[9]: http://www.cdrf.co/
|
||||
[10]: https://ccbv.co.uk/
|
||||
[11]: https://www.django-rest-framework.org/api-guide/serializers/#serializers
|
@ -1,16 +1,18 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-12875-1.html"
|
||||
[#]: subject: "Get started with Fossil, an alternative to Git"
|
||||
[#]: via: "https://opensource.com/article/20/11/fossil"
|
||||
[#]: author: "Klaatu https://opensource.com/users/klaatu"
|
||||
|
||||
开始学习 Fossil,Git 的一个替代品
|
||||
了解一下 Fossil,一个 Git 的替代品
|
||||
======
|
||||
Fossil 是一个集版本控制系统、bug 追踪、维基、论坛以及文档解决方案于一体的系统。
|
||||
![Dinosaurs on land at sunset][1]
|
||||
|
||||
> Fossil 是一个集版本控制系统、bug 追踪、维基、论坛以及文档解决方案于一体的系统。
|
||||
|
||||

|
||||
|
||||
每个开发者都知道,追踪代码的修改是至关重要的。有时候你会处于好奇或者教育的目的需要展示你的项目开始和进化的历史。有时候你想让其他的开发者参与到你的项目中,因此你需要一种值得信赖的能合并不同代码分支的方法。更极端一点,有时候你为了解决一个问题而修改的代码导致已有的功能不能正常使用。
|
||||
|
||||
@ -18,13 +20,11 @@ Fossil 是一个集版本控制系统、bug 追踪、维基、论坛以及文档
|
||||
|
||||
### 安装 Fossil
|
||||
|
||||
Fossil 是一个独立的 C 程序,因此你可以从它的网站上[下载][4]后放在环境变量 [PATH][5] 中的任意位置。例如,假定 `/usr/local/bin` 已经在你的环境变量中(默认情况下是在的)
|
||||
|
||||
Fossil 是一个独立的 C 程序,因此你可以从它的网站上[下载][4]后放在环境变量 [PATH][5] 中的任意位置。例如,假定 `/usr/local/bin` 已经在你的环境变量中(默认情况下是在的):
|
||||
|
||||
```
|
||||
$ wget <https://fossil-scm.org/home/uv/fossil-linux-x64-X.Y.tar.gz>
|
||||
$ sudo tar xvf fossil-linux-x64-X.Y.tar.gz \
|
||||
\--directory /usr/local/bin
|
||||
$ wget https://fossil-scm.org/home/uv/fossil-linux-x64-X.Y.tar.gz
|
||||
$ sudo tar xvf fossil-linux-x64-X.Y.tar.gz --directory /usr/local/bin
|
||||
```
|
||||
|
||||
你也可以通过包管理器从软件仓库中找到 Fossil,或者直接从源码编译。
|
||||
@ -33,7 +33,6 @@ $ sudo tar xvf fossil-linux-x64-X.Y.tar.gz \
|
||||
|
||||
如果你已经有一个代码项目,想用 Fossil 来追踪,那么第一步就是创建一个 Fossil 仓库:
|
||||
|
||||
|
||||
```
|
||||
$ fossil init myproject.fossil
|
||||
project-id: 010836ac6112fefb0b015702152d447c8c1d8604
|
||||
@ -41,15 +40,14 @@ server-id: 54d837e9dc938ba1caa56d31b99c35a4c9627f44
|
||||
admin-user: klaatu (initial password is "14b605")
|
||||
```
|
||||
|
||||
创建 Fossil 仓库的过程中会返回三行信息:一个唯一的项目 ID、一个唯一的服务 ID 以及管理员 ID 和密码。项目 ID 和服务 ID 是版本数字。管理员资质表明你对这个仓库的所有权,当你把这个 Fossil 仓库作为服务器让其他用户来访问时可以使用管理员权限。
|
||||
创建 Fossil 仓库的过程中会返回三行信息:一个唯一的项目 ID、一个唯一的服务器 ID 以及管理员 ID 和密码。项目 ID 和服务器 ID 是版本数字。管理员凭证表明你对这个仓库的所有权,当你把 Fossil 作为服务器让其他用户来访问时可以使用管理员权限。
|
||||
|
||||
### Fossil 仓库工作流
|
||||
|
||||
在你使用 Fossil 仓库之前,你需要先为它的数据创建一个工作路径。你可以把这个过程类比为使用 Python 时创建一个虚拟环境或者解压一个只会用来备份的 ZIP 文件。
|
||||
在你使用 Fossil 仓库之前,你需要先为它的数据创建一个工作路径。你可以把这个过程类比为使用 Python 时创建一个虚拟环境或者解压一个只用来备份的 ZIP 文件。
|
||||
|
||||
创建一个工作目录并进入:
|
||||
|
||||
|
||||
```
|
||||
$ mkdir myprojectdir
|
||||
$ cd myprojectdir
|
||||
@ -57,29 +55,27 @@ $ cd myprojectdir
|
||||
|
||||
把你的 Fossil 打开到刚刚创建的目录:
|
||||
|
||||
|
||||
```
|
||||
$ fossil open ../myproject
|
||||
project-name: <unnamed>
|
||||
repository: /home/klaatu/myprojectdir/../myproject
|
||||
local-root: /home/klaatu/myprojectdir/
|
||||
config-db: /home/klaatu/.fossil
|
||||
project-name: <unnamed>
|
||||
repository: /home/klaatu/myprojectdir/../myproject
|
||||
local-root: /home/klaatu/myprojectdir/
|
||||
config-db: /home/klaatu/.fossil
|
||||
project-code: 010836ac6112fefb0b015702152d447c8c1d8604
|
||||
checkout: 9e6cd96dd675544c58a246520ad58cdd460d1559 2020-11-09 04:09:35 UTC
|
||||
tags: trunk
|
||||
comment: initial empty check-in (user: klaatu)
|
||||
check-ins: 1
|
||||
checkout: 9e6cd96dd675544c58a246520ad58cdd460d1559 2020-11-09 04:09:35 UTC
|
||||
tags: trunk
|
||||
comment: initial empty check-in (user: klaatu)
|
||||
check-ins: 1
|
||||
```
|
||||
|
||||
你可能注意到了,Fossil 在你的家目录下创建了一个名为 `.fossil` 的隐藏文件,用来追踪你的全局 Fossil 配置。这个配置不是只适用于你的一个项目的;这个文件只会在你第一次使用 Fossil 时生成。
|
||||
|
||||
#### 添加文件
|
||||
|
||||
使用 `add` 和 `commit` 子命令来向你的仓库添加文件。例如,创建一个简单的 README 文件,把它添加到仓库:
|
||||
|
||||
使用 `add` 和 `commit` 子命令来向你的仓库添加文件。例如,创建一个简单的 `README` 文件,把它添加到仓库:
|
||||
|
||||
```
|
||||
$ echo "My first Fossil project" > README
|
||||
$ echo "My first Fossil project" > README
|
||||
$ fossil add README
|
||||
ADDED README
|
||||
$ fossil commit -m 'My first commit'
|
||||
@ -90,7 +86,6 @@ New_Version: 2472a43acd11c93d08314e852dedfc6a476403695e44f47061607e4e90ad01aa
|
||||
|
||||
Fossil 仓库开始时默认使用的主分支名为 `trunk`。当你想修改代码而又不影响主干代码时,你可以从 trunk 分支切走。创建新分支需要使用 `branch` 子命令,这个命令需要两个参数:一个新分支的名字,一个新分支的基分支名字。在本例中,只有一个分支 `trunk`,因此尝试创建一个名为 `dev` 的新分支:
|
||||
|
||||
|
||||
```
|
||||
$ fossil branch --help
|
||||
Usage: fossil branch new BRANCH-NAME BASIS ?OPTIONS?
|
||||
@ -100,7 +95,6 @@ New branch: cb90e9c6f23a9c98e0c3656d7e18d320fa52e666700b12b5ebbc4674a0703695
|
||||
|
||||
你已经创建了一个新分支,但是你当前所在的分支仍然是 `trunk`:
|
||||
|
||||
|
||||
```
|
||||
$ fossil branch current
|
||||
trunk
|
||||
@ -108,7 +102,6 @@ trunk
|
||||
|
||||
使用 `checkout` 命令切换到你的新分支 `dev`:
|
||||
|
||||
|
||||
```
|
||||
$ fossil checkout dev
|
||||
dev
|
||||
@ -130,7 +123,6 @@ README
|
||||
|
||||
这个分支中没有你的新文件(或者你对其他文件的修改),而那些内容是合并的过程需要的信息:
|
||||
|
||||
|
||||
```
|
||||
$ fossil merge dev
|
||||
"fossil undo" is available to undo changes to the working checkout.
|
||||
@ -142,7 +134,6 @@ myfile.lua README
|
||||
|
||||
使用 `timeline` 选项来查看仓库的历史。这个命令列出了你的仓库的所有活动的详细信息,包括用来表示每次修改的哈希值、每次提交时填写的信息以及提交者:
|
||||
|
||||
|
||||
```
|
||||
$ fossil timeline
|
||||
=== 2020-11-09 ===
|
||||
@ -156,25 +147,21 @@ $ fossil timeline
|
||||
|
||||
![Fossil UI][6]
|
||||
|
||||
(Klaatu, [CC BY-SA 4.0][7])
|
||||
|
||||
### 公开你的 Fossil 仓库
|
||||
|
||||
因为 Fossil 有个内置的 web 界面,所以 Fossil 不像 GitLab 和 Gitea 那样需要主机服务。Fossil 就是它自己的主机服务,只要你把它放在一台机器上就行了。在你公开你的 Fossil 仓库之前,你还需要通过 web 用户界面(UI)来配置一些信息:
|
||||
|
||||
使用 `ui` 子命令启动一个本地的实例:
|
||||
|
||||
|
||||
```
|
||||
$ pwd
|
||||
/home/klaatu/myprojectdir/
|
||||
$ fossil ui
|
||||
```
|
||||
|
||||
`用户`和`设置`是安全相关的,`配置`是项目属性相关的(包括一个合适的标题)。web 界面不仅仅是一个方便的功能。 它是能在生产环境中使用并作为 Fossil 项目的宿主来使用的。它还有一些其他的高级选项,比如用户管理(或者叫自我管理)、在同一个服务器上与其他的 Fossil 仓库进行单点登录(SSO)。
|
||||
|
||||
当配置完成后,关掉 web 界面并按下 **Ctrl+C** 来停止 UI 引擎。像提交代码一样提交你的 web 修改。
|
||||
“Users” 和 “Settings” 是安全相关的,“Configuration” 是项目属性相关的(包括一个合适的标题)。web 界面不仅仅是一个方便的功能。 它是能在生产环境中使用并作为 Fossil 项目的宿主机来使用的。它还有一些其他的高级选项,比如用户管理(或者叫自我管理)、在同一个服务器上与其他的 Fossil 仓库进行单点登录(SSO)。
|
||||
|
||||
当配置完成后,关掉 web 界面并按下 `Ctrl+C` 来停止 UI 引擎。像提交代码一样提交你的 web 修改。
|
||||
|
||||
```
|
||||
$ fossil commit -m 'web ui updates'
|
||||
@ -187,9 +174,6 @@ New_Version: 11fe7f2855a3246c303df00ec725d0fca526fa0b83fa67c95db92283e8273c60
|
||||
2. 如果你的服务器没有安装 Fossil,就在你的服务器上安装 Fossil。在服务器上安装的过程跟在本地一样。
|
||||
3. 在你的 `cgi-bin` 目录下(或它对应的目录,这取决于你的 HTTP 守护进程)创建一个名为 `repo_myproject.cgi` 的文件:
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
#!/usr/local/bin/fossil
|
||||
repository: /home/klaatu/public_html/myproject.fossil
|
||||
@ -197,9 +181,8 @@ repository: /home/klaatu/public_html/myproject.fossil
|
||||
|
||||
添加可执行权限:
|
||||
|
||||
|
||||
```
|
||||
`$ chmod +x repo_myproject.cgi`
|
||||
$ chmod +x repo_myproject.cgi
|
||||
```
|
||||
|
||||
你需要做的都已经做完了。现在可以通过互联网访问你的项目了。
|
||||
@ -208,21 +191,19 @@ repository: /home/klaatu/public_html/myproject.fossil
|
||||
|
||||
你也可以通过命令行来进行交互:
|
||||
|
||||
|
||||
```
|
||||
`$ fossil clone https://klaatu@example.com/cgi-bin/repo_myproject.cgi`
|
||||
$ fossil clone https://klaatu@example.com/cgi-bin/repo_myproject.cgi
|
||||
```
|
||||
|
||||
在本地的克隆仓库中工作时,你需要使用 `push` 子命令把本地的修改推送到远程的仓库,使用 `pull` 子命令把远程的修改拉取到本地仓库:
|
||||
|
||||
|
||||
```
|
||||
`$ fossil push https://klaatu@example.com/cgi-bin/repo_myproject.cgi`
|
||||
$ fossil push https://klaatu@example.com/cgi-bin/repo_myproject.cgi
|
||||
```
|
||||
|
||||
### 使用Fossil 作为独立的主机
|
||||
### 使用 Fossil 作为独立的托管
|
||||
|
||||
Fossil 大大提高了你的效率(也提高了你的合作者的效率),让你不再依赖主机副刷。本文只是简单的介绍了基本概念。你的代码项目还会用到很多有用的 Fossil 功能。尝试一下 Fossil。它不仅会改变你对版本控制的理解;它会让你不再考虑其他的版本控制系统。
|
||||
Fossil 将大量的权力交到了你的手中(以及你的合作者的手中),让你不再依赖托管服务。本文只是简单的介绍了基本概念。你的代码项目还会用到很多有用的 Fossil 功能。尝试一下 Fossil。它不仅会改变你对版本控制的理解;它会让你不再考虑其他的版本控制系统。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -231,7 +212,7 @@ via: https://opensource.com/article/20/11/fossil
|
||||
作者:[Klaatu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12893-1.html)
|
||||
[#]: subject: (How to Go Full Dark Mode With LibreOffice)
|
||||
[#]: via: (https://itsfoss.com/libreoffice-dark-mode/)
|
||||
[#]: author: (Dimitrios Savvopoulos https://itsfoss.com/author/dimitrios/)
|
||||
|
||||
如何在 LibreOffice 中完全启用深色模式
|
||||
======
|
||||
|
||||

|
||||
|
||||
[LibreOffice][1] 是一款自由开源的跨平台办公生产力软件。如果你没有充分利用它,那么必须看下 [LibreOffice 小技巧][2]。
|
||||
|
||||
甚至在非编程人员中,深色主题也越来越受欢迎。它减轻了眼睛的压力,特别适合长时间使用屏幕。有人认为,这使文本看起来清晰明了,有助于提高生产率。
|
||||
|
||||
如今,某些 Linux 发行版例如 [Ubuntu 带有深色模式][3],使你的系统具有更暗的色彩。当你打开<ruby>深色模式<rt>dark mode</rt></ruby>时,某些应用将自动切换到深色模式。
|
||||
|
||||
LibreOffice 也会这样,但你编辑的主区域除外:
|
||||
|
||||
![LibreOffice semi dark mode matching with the system theme][4]
|
||||
|
||||
你可以更改它。如果要让 LibreOffice 进入完全深色模式,只需更改一些设置。让我告诉你如何做。
|
||||
|
||||
### 如何在 LibreOffice 中完全启用深色模式
|
||||
|
||||
如前所述,你需要先启用系统范围的深色模式。这样可以确保窗口颜色(或标题栏)与应用内深色完全融合。
|
||||
|
||||
接下来,打开套件中的**任意** LibreOffice 应用,例如 **Writer**。然后从菜单中,依次点击 **Tools -> Options -> Application Colors**,然后选择 **Document background 和 Application background** 为 **Black** 或 **Automatic**(任意适合你的方式)。
|
||||
|
||||
![][5]
|
||||
|
||||
如果图标不是深色,那么可以从菜单(如下图所示)中更改它们,**Tools -> Options -> View** ,我在 MX Linux 上的个人选择是 Ubuntu 的 [Yaru][6] 图标样式(如果你使用的图标包为深色版本,请选择它) 。
|
||||
|
||||
![][7]
|
||||
|
||||
当然,你也可以尝试其他 Linux 发行版的 [icon 主题][8]。
|
||||
|
||||
最终结果应如下所示:
|
||||
|
||||
![][9]
|
||||
|
||||
#### LibreOffice flatpak 软件包的其他技巧
|
||||
|
||||
如果你使用的是 LibreOffice 套件的 [Flatpak 软件包][10],那么 LibreOffice 的标题区域(或菜单区域)可能看起来是白色的。在这种情况下,你可以尝试进入 **Tools -> Options -> Personalization**,然后选择 “**灰色主题**”,如下截图所示。
|
||||
|
||||
![][11]
|
||||
|
||||
它并不完全是黑色的,但应该可以使外观看起来更好。希望可以帮助你切换到深色主题的 LibreOffice 体验!
|
||||
|
||||
#### 总结
|
||||
|
||||
深色主题逐渐开始在我们的台式机中占主导地位,它具有现代品味并减少了眼睛疲劳,尤其是在弱光条件下。
|
||||
|
||||
LibreOffice 使你可以自由地将工作环境切换为深色主题或保留浅色主题元素。实际上,你将有大量的自定义选项来调整你喜欢的内容。你是否已在 LibreOffice 上切换为深色主题?你首选哪种颜色组合?在下面的评论中让我们知道!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/libreoffice-dark-mode/
|
||||
|
||||
作者:[Dimitrios Savvopoulos][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/dimitrios/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.libreoffice.org
|
||||
[2]: https://itsfoss.com/libreoffice-tips/
|
||||
[3]: https://itsfoss.com/dark-mode-ubuntu/
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/libreOffice-dark-mode.png?resize=799%2C450&ssl=1
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/1-libreoffice-application-colours.png?resize=800%2C551&ssl=1
|
||||
[6]: https://extensions.libreoffice.org/en/extensions/show/yaru-icon-theme
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/2-libreoffice-iconstyle-1.png?resize=800%2C531&ssl=1
|
||||
[8]: https://itsfoss.com/best-icon-themes-ubuntu-16-04/
|
||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/3-libreoffice-dark.png?resize=800%2C612&ssl=1
|
||||
[10]: https://itsfoss.com/what-is-flatpak/
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/libre-office-personalization.png?resize=800%2C636&ssl=1
|
256
published/20201130 8 Git aliases that make me more efficient.md
Normal file
256
published/20201130 8 Git aliases that make me more efficient.md
Normal file
@ -0,0 +1,256 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12904-1.html)
|
||||
[#]: subject: (8 Git aliases that make me more efficient)
|
||||
[#]: via: (https://opensource.com/article/20/11/git-aliases)
|
||||
[#]: author: (Ricardo Gerardi https://opensource.com/users/rgerardi)
|
||||
|
||||
8 个让我更有效率的 Git 别名
|
||||
======
|
||||
|
||||
> 使用别名为你最常用或复杂的 Git 命令创建快捷方式。
|
||||
|
||||

|
||||
|
||||
这篇出色的文章《[改变我使用 Git 工作方式的七个技巧][2]》启发了我写下另一个对我在命令行上使用 Git 的经验有重大影响的 Git 特性:别名。
|
||||
|
||||
定义 Git 的别名来替代命令有两大好处。
|
||||
|
||||
* 它简化了有许多选项的长命令,使它们更短,更容易记住。
|
||||
* 缩短了经常使用的命令,使你的工作更有效率。
|
||||
|
||||
### 如何定义和使用别名
|
||||
|
||||
要定义 Git 的别名,请使用 `git config` 命令,加上别名和要替换的命令。例如,要为 `git push` 创建别名 `p`:
|
||||
|
||||
```
|
||||
$ git config --global alias.p 'push'
|
||||
```
|
||||
|
||||
你可以通过将别名作为 `git` 的参数来使用别名,就像其他命令一样:
|
||||
|
||||
```
|
||||
$ git p
|
||||
```
|
||||
|
||||
要查看所有的别名,用 `git config` 列出你的配置:
|
||||
|
||||
```
|
||||
$ git config --global -l
|
||||
user.name=ricardo
|
||||
user.email=ricardo@example.com
|
||||
alias.p=push
|
||||
```
|
||||
|
||||
你也可以用你喜欢的 shell 来定义别名,比如 Bash 或 Zsh。不过,用 Git 定义别名有几个功能是用 shell 无法实现的。首先,它允许你在不同的 shell 中使用别名,而无需额外配置。此外,它还集成了 Git 的自动更正功能,所以当你输入错误的命令时,Git 可以建议你正确的别名。最后,Git 还会将别名保存在用户配置文件中,你可以通过复制一个文件将别名转移到其他机器上。
|
||||
|
||||
无论使用哪种方法,定义别名都能改善你使用 Git 的整体体验。更多关于定义 Git 别名的信息,请看《[Git Book][4]》。
|
||||
|
||||
### 8 个有用的 Git 别名
|
||||
|
||||
现在你知道如何创建和使用别名了,来看看一些有用的别名。
|
||||
|
||||
#### 1、Git 状态
|
||||
|
||||
Git 命令行用户经常使用 `status` 命令来查看已更改或未跟踪的文件。默认情况下,这个命令提供了很多行的冗长输出,你可能不想要或不需要。你可以使用一个别名来处理这两个组件。定义别名 `st` 来缩短命令,并使用选项 `-sb` 来输出一个不那么啰嗦的状态和分支信息。
|
||||
|
||||
```
|
||||
$ git config --global alias.st 'status -sb'
|
||||
```
|
||||
|
||||
如果你在一个干净的分支上使用这个别名,你的输出就像这样:
|
||||
|
||||
```
|
||||
$ git st
|
||||
## master
|
||||
```
|
||||
|
||||
在一个带有已更改和未跟踪文件的分支上使用它,会产生这样的输出:
|
||||
|
||||
```
|
||||
$ git st
|
||||
## master
|
||||
M test2
|
||||
?? test3
|
||||
```
|
||||
|
||||
#### 2、Git 单行日志
|
||||
|
||||
创建一个别名,以单行方式显示你的提交,使输出更紧凑:
|
||||
|
||||
```
|
||||
$ git config --global alias.ll 'log --oneline'
|
||||
```
|
||||
|
||||
使用这个别名可以提供所有提交的简短列表:
|
||||
|
||||
```
|
||||
$ git ll
|
||||
33559c5 (HEAD -> master) Another commit
|
||||
17646c1 test1
|
||||
```
|
||||
|
||||
#### 3、Git 的最近一次提交
|
||||
|
||||
这将显示你最近一次提交的详细信息。这是扩展了《Git Book》中 [别名][4] 一章的例子:
|
||||
|
||||
```
|
||||
$ git config --global alias.last 'log -1 HEAD --stat'
|
||||
```
|
||||
|
||||
用它来查看最后的提交:
|
||||
|
||||
```
|
||||
$ git last
|
||||
commit f3dddcbaabb928f84f45131ea5be88dcf0692783 (HEAD -> branch1)
|
||||
Author: ricardo <ricardo@example.com>
|
||||
Date: Tue Nov 3 00:19:52 2020 +0000
|
||||
|
||||
Commit to branch1
|
||||
|
||||
test2 | 1 +
|
||||
test3 | 0
|
||||
2 files changed, 1 insertion(+)
|
||||
```
|
||||
|
||||
#### 4、Git 提交
|
||||
|
||||
当你对 Git 仓库进行修改时,你会经常使用 `git commit`。使用 `cm` 别名使 `git commit -m` 命令更有效率:
|
||||
|
||||
```
|
||||
$ git config --global alias.cm 'commit -m'
|
||||
```
|
||||
|
||||
因为 Git 别名扩展了命令,所以你可以在执行过程中提供额外的参数:
|
||||
|
||||
```
|
||||
$ git cm "A nice commit message"
|
||||
[branch1 0baa729] A nice commit message
|
||||
1 file changed, 2 insertions(+)
|
||||
```
|
||||
|
||||
#### 5、Git 远程仓库
|
||||
|
||||
`git remote -v` 命令列出了所有配置的远程仓库。用别名 `rv` 将其缩短:
|
||||
|
||||
```
|
||||
$ git config --global alias.rv 'remote -v'
|
||||
```
|
||||
|
||||
#### 6、Git 差异
|
||||
|
||||
`git diff` 命令可以显示不同提交的文件之间的差异,或者提交和工作树之间的差异。用 `d` 别名来简化它:
|
||||
|
||||
```
|
||||
$ git config --global alias.d 'diff'
|
||||
```
|
||||
|
||||
标准的 `git diff` 命令对小的改动很好用,但对于比较复杂的改动,外部工具如 `vimdiff` 就更有用。创建别名 `dv` 来使用 `vimdiff` 显示差异,并使用 `y` 参数跳过确认提示:
|
||||
|
||||
```
|
||||
$ git config --global alias.dv 'difftool -t vimdiff -y'
|
||||
```
|
||||
|
||||
使用这个别名来显示两个提交之间的 `file1` 差异:
|
||||
|
||||
```
|
||||
$ git dv 33559c5 ca1494d file1
|
||||
```
|
||||
|
||||
![vim-diff results][5]
|
||||
|
||||
#### 7、Git 配置列表
|
||||
|
||||
`gl` 别名可以更方便地列出所有用户配置:
|
||||
|
||||
```
|
||||
$ git config --global alias.gl 'config --global -l'
|
||||
```
|
||||
|
||||
现在你可以看到所有定义的别名(和其他配置选项):
|
||||
|
||||
```
|
||||
$ git gl
|
||||
user.name=ricardo
|
||||
user.email=ricardo@example.com
|
||||
alias.p=push
|
||||
alias.st=status -sb
|
||||
alias.ll=log --oneline
|
||||
alias.last=log -1 HEAD --stat
|
||||
alias.cm=commit -m
|
||||
alias.rv=remote -v
|
||||
alias.d=diff
|
||||
alias.dv=difftool -t vimdiff -y
|
||||
alias.gl=config --global -l
|
||||
alias.se=!git rev-list --all | xargs git grep -F
|
||||
```
|
||||
|
||||
#### 8、搜索提交
|
||||
|
||||
Git 别名允许你定义更复杂的别名,比如执行外部 shell 命令,可以在别名前加上 `!` 字符。你可以用它来执行自定义脚本或更复杂的命令,包括 shell 管道。
|
||||
|
||||
例如,定义 `se` 别名来搜索你的提交:
|
||||
|
||||
```
|
||||
$ git config --global alias.se '!git rev-list --all | xargs git grep -F'
|
||||
```
|
||||
|
||||
使用这个别名来搜索提交中的特定字符串:
|
||||
|
||||
```
|
||||
$ git se test2
|
||||
0baa729c1d683201d0500b0e2f9c408df8f9a366:file1:test2
|
||||
ca1494dd06633f08519ec43b57e25c30b1c78b32:file1:test2
|
||||
```
|
||||
|
||||
### 自动更正你的别名
|
||||
|
||||
使用 Git 别名的一个很酷的好处是它与自动更正功能的原生集成。如果你犯了错误,默认情况下,Git 会建议使用与你输入的命令相似的命令,包括别名。例如,如果你把 `status` 打成了 `ts`,而不是 `st`,Git 会推荐正确的别名:
|
||||
|
||||
```
|
||||
$ git ts
|
||||
git: 'ts' is not a git command. See 'git --help'.
|
||||
|
||||
The most similar command is
|
||||
st
|
||||
```
|
||||
|
||||
如果你启用了自动更正功能,Git 会自动执行正确的命令:
|
||||
|
||||
```
|
||||
$ git config --global help.autocorrect 20
|
||||
$ git ts
|
||||
WARNING: You called a Git command named 'ts', which does not exist.
|
||||
Continuing in 2.0 seconds, assuming that you meant 'st'.
|
||||
## branch1
|
||||
?? test4
|
||||
```
|
||||
|
||||
### 优化 Git 命令
|
||||
|
||||
Git 别名是一个很有用的功能,它可以优化常见的重复性命令的执行,从而提高你的效率。Git 允许你定义任意数量的别名,有些用户会定义很多别名。我更喜欢只为最常用的命令定义别名 —— 定义太多别名会让人难以记忆,而且可能需要查找才能使用。
|
||||
|
||||
更多关于别名的内容,包括其他有用的内容,请参见 [Git 维基的别名页面][7]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/11/git-aliases
|
||||
|
||||
作者:[Ricardo Gerardi][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/rgerardi
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/terminal_command_linux_desktop_code.jpg?itok=p5sQ6ODE (Terminal command prompt on orange background)
|
||||
[2]: https://linux.cn/article-12894-1.html
|
||||
[3]: mailto:ricardo@example.com
|
||||
[4]: https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases
|
||||
[5]: https://opensource.com/sites/default/files/uploads/vimdiff.png (vim-diff results)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://git.wiki.kernel.org/index.php/Aliases
|
151
published/20201130 Journal five minutes a day with Jupyter.md
Normal file
151
published/20201130 Journal five minutes a day with Jupyter.md
Normal file
@ -0,0 +1,151 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12887-1.html)
|
||||
[#]: subject: (Journal five minutes a day with Jupyter)
|
||||
[#]: via: (https://opensource.com/article/20/11/daily-journal-jupyter)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
每天用 Jupyter 写 5 分钟的日记
|
||||
======
|
||||
|
||||
> 用 Jupyter 和 Python 在你的日常写作背后实现一些自动化。
|
||||
|
||||

|
||||
|
||||
有些人会遵循传统,制定一年的计划。不过,一年的时间很长,所以我以季节性的主题或轨迹来规划。每个季度,我都会坐下来,看看即将到来的三个月的季节,并决定在这段时间里我将努力做什么。
|
||||
|
||||
对于我最新的主题,我决定要每天写一篇日记。我喜欢有明确的承诺,所以我承诺每天写 5 分钟。我也喜欢有可观察的承诺,哪怕只是对我而言,所以我把我的记录放在 Git 里。
|
||||
|
||||
我决定在写日记的过程中实现一些自动化,于是我使用了我最喜欢的自动化工具:[Jupyter][2]。Jupyter 有一个有趣的功能 [ipywidgets][3],这是一套用于 Jupyter Notebooks、JupyterLab 和 IPython 内核的交互式 HTML 组件。
|
||||
|
||||
如果你想跟着本文的代码走,请注意,让你的 JupyterLab 实例支持组件可能有点复杂,请按照[这些说明][4]来进行设置。
|
||||
|
||||
### 导入 ipywidgets 模块
|
||||
|
||||
首先,你需要导入一堆东西,比如 ipywidgets 和 [Twisted][5]。Twisted 模块可以用来创建一个异步时间计数器:
|
||||
|
||||
```
|
||||
import twisted.internet.asyncioreactor
|
||||
twisted.internet.asyncioreactor.install()
|
||||
from twisted.internet import reactor, task
|
||||
import ipywidgets, datetime, subprocess, functools, os
|
||||
```
|
||||
|
||||
### 设置定时条目
|
||||
|
||||
用 Twisted 实现时间计数器是利用了 `task.LoopingCall`。然而,结束循环调用的唯一方法是用一个异常。倒计时时钟总会停止,所以你需要一个自定义的异常来指示“一切正常;计数器结束”:
|
||||
|
||||
```
|
||||
class DoneError(Exception):
|
||||
pass
|
||||
```
|
||||
|
||||
现在你已经写好了异常,你可以写定时器了。第一步是创建一个 `ipywidgets.Label` 的文本标签组件。循环使用 `divmod` 计算出分和秒,然后设置标签的文本值:
|
||||
|
||||
```
|
||||
def time_out_counter(reactor):
|
||||
label = ipywidgets.Label("Time left: 5:00")
|
||||
current_seconds = datetime.timedelta(minutes=5).total_seconds()
|
||||
def decrement(count):
|
||||
nonlocal current_seconds
|
||||
current_seconds -= count
|
||||
time_left = datetime.timedelta(seconds=max(current_seconds, 0))
|
||||
minutes, left = divmod(time_left, minute)
|
||||
seconds = int(left.total_seconds())
|
||||
label.value = f"Time left: {minutes}:{seconds:02}"
|
||||
if current_seconds < 0:
|
||||
raise DoneError("finished")
|
||||
minute = datetime.timedelta(minutes=1)
|
||||
call = task.LoopingCall.withCount(decrement)
|
||||
call.reactor = reactor
|
||||
d = call.start(1)
|
||||
d.addErrback(lambda f: f.trap(DoneError))
|
||||
return d, label
|
||||
```
|
||||
|
||||
### 从 Jupyter 组件中保存文本
|
||||
|
||||
下一步是写一些东西,将你输入的文字保存到一个文件中,并提交到 Git。另外,由于你要写 5 分钟的日记,你需要一个能给你提供写字区域的组件(滚动肯定是可以的,但一次能看到更多的文字就更好了)。
|
||||
|
||||
这就用到了组件 `Textarea`,这是一个你可以书写的文本字段,而 `Output` 则是用来给出反馈的。这一点很重要,因为 `git push` 可能会花点时间或失败,这取决于网络。如果备份失败,用反馈提醒用户很重要:
|
||||
|
||||
```
|
||||
def editor(fname):
|
||||
textarea = ipywidgets.Textarea(continuous_update=False)
|
||||
textarea.rows = 20
|
||||
output = ipywidgets.Output()
|
||||
runner = functools.partial(subprocess.run, capture_output=True, text=True, check=True)
|
||||
def save(_ignored):
|
||||
with output:
|
||||
with open(fname, "w") as fpout:
|
||||
fpout.write(textarea.value)
|
||||
print("Sending...", end='')
|
||||
try:
|
||||
runner(["git", "add", fname])
|
||||
runner(["git", "commit", "-m", f"updated {fname}"])
|
||||
runner(["git", "push"])
|
||||
except subprocess.CalledProcessError as exc:
|
||||
print("Could not send")
|
||||
print(exc.stdout)
|
||||
print(exc.stderr)
|
||||
else:
|
||||
print("Done")
|
||||
textarea.observe(save, names="value")
|
||||
return textarea, output, save
|
||||
```
|
||||
|
||||
`continuous_update=False` 是为了避免每个字符都保存一遍并发送至 Git。相反,只要脱离输入焦点,它就会保存。这个函数也返回 `save` 函数,所以可以明确地调用它。
|
||||
|
||||
### 创建一个布局
|
||||
|
||||
最后,你可以使用 `ipywidgets.VBox` 把这些东西放在一起。这是一个包含一些组件并垂直显示的东西。还有一些其他的方法来排列组件,但这足够简单:
|
||||
|
||||
```
|
||||
def journal():
|
||||
date = str(datetime.date.today())
|
||||
title = f"Log: Startdate {date}"
|
||||
filename = os.path.join(f"{date}.txt")
|
||||
d, clock = time_out_counter(reactor)
|
||||
textarea, output, save = editor(filename)
|
||||
box = ipywidgets.VBox([
|
||||
ipywidgets.Label(title),
|
||||
textarea,
|
||||
clock,
|
||||
output
|
||||
])
|
||||
d.addCallback(save)
|
||||
return box
|
||||
```
|
||||
|
||||
biu!你已经定义了一个写日记的函数了,所以是时候试试了。
|
||||
|
||||
```
|
||||
journal()
|
||||
```
|
||||
|
||||
![Jupyter journal][6]
|
||||
|
||||
你现在可以写 5 分钟了!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/11/daily-journal-jupyter
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tea-cup-mug-flowers-book-window.jpg?itok=JqThhl51 (Ceramic mug of tea or coffee with flowers and a book in front of a window)
|
||||
[2]: https://jupyter.org/
|
||||
[3]: https://ipywidgets.readthedocs.io/en/latest/
|
||||
[4]: https://ipywidgets.readthedocs.io/en/latest/user_install.html
|
||||
[5]: https://twistedmatrix.com/trac/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/journaling_output_13_0.png (Jupyter journal)
|
||||
[7]: https://creativecommons.org/licenses/by-sa/4.0/
|
@ -0,0 +1,69 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12897-1.html)
|
||||
[#]: subject: (How this open source security tool halted significant DDoS attacks)
|
||||
[#]: via: (https://opensource.com/article/20/12/open-source-vs-ddos-attacks)
|
||||
[#]: author: (Philippe Humeau https://opensource.com/users/philippe-humeau)
|
||||
|
||||
如何在 1 分钟内阻止 7000 台机器的僵尸网络
|
||||
======
|
||||
|
||||
> 对 CrowdSec 的配置更改,在不到一分钟的时间内阻止了一个 7000 台机器的僵尸网络的攻击。
|
||||
|
||||

|
||||
|
||||
2020 年,我们的生活和工作方式在短短几天内被彻底颠覆。随着 COVID-19 开始在全球范围内蔓延,我们将工作带回家,与同事、朋友和家人保持在线联系成为关键的必需品。这为黑客造成破坏打开了大门。例如,根据 Neustar 的数据,今年上半年全球的分布式拒绝服务(DDOS) 攻击[增长了 151%][2]。
|
||||
|
||||
[CrowdSec][3] 是一个开源的安全引擎,它可以分析访问者的行为,并提供适应各种攻击的响应。它能解析来自各种来源的日志,并应用启发式方案来识别攻击性行为,并防范大多数攻击类别。并且,它与其它安装的 CrowdSec 系统共享该情报。每次 IP 地址被阻止时,它都会通知整个用户社区。这就创建了一个[实时、协作的 IP 信誉数据库][4],利用人群的力量使互联网更加安全。
|
||||
|
||||
### CrowdSec 如何工作:案例研究
|
||||
|
||||
Sorf Networks 是一家总部位于土耳其的技术公司,为客户提供高配置的托管服务器和 DDoS 防护解决方案,它提供了一个 CrowdSec 工作的例子。Sorf 的一个客户每天都会遇到来自 1 万多台机器僵尸网络的 DDoS 攻击,并努力寻找一种能够满足技术要求的解决方案来及时处理这些攻击。
|
||||
|
||||
虽然客户采取了一般的预防措施来缓解这些攻击,比如引入 JavaScript(JS)<ruby>挑战<rt>challenges</rt></ruby>、限速等,但这些措施在整个攻击面并不可行。一些 URL 需要被非常基本的软件使用,而这些软件不支持 JS 挑战。黑客就是黑客,这正是他们每天的目标:链条上最薄弱的环节。
|
||||
|
||||
Sorf Networks 首先使用 [Fail2ban][5](这启发了 CrowdSec)为其客户建立了一个 DDoS 缓解策略。它在一定程度上帮助了客户,但它太慢了。它需要 50 分钟来处理日志和处理 7000 到 10000 台机器的 DDoS 攻击。这使得它在这种情况下没有效果。另外,因为它没有禁止 IP,日志会持续堆积,它需要每秒处理几千条日志,这是不可能的。
|
||||
|
||||
在使用租用的僵尸网络进行的 DDoS 测试中,一次攻击可以高达每秒 6700 个左右的请求,这些请求来自 8600 个独立 IP。这是对一台服务器流量的捕捉:
|
||||
|
||||
![Server traffic][6]
|
||||
|
||||
虽然 CrowdSec 技术可以应对巨大的攻击,但其默认设置每秒只能处理约 1000 个端点。Sorf 需要一个量身定做的配置来处理单台机器上这么多的流量。
|
||||
|
||||
Sorf 的团队对 CrowdSec 的配置进行了修改,以显著提高其吞吐量来处理日志。首先,它去掉了高消耗且非关键的<ruby>富集<rt>enrichment</rt></ruby>解析器,例如 [GeoIP 富集][7]。它还将允许的 goroutine 的默认数量从一个增加到五个。之后,团队又用 8000 到 9000 台主机做了一次实测,平均每秒 6000 到 7000 个请求。这个方案是有代价的,因为 CrowdSec 在运行过程中吃掉了 600% 的 CPU,但其内存消耗却保持在 270MB 左右。
|
||||
|
||||
然而,结果却显示出明显的成功:
|
||||
|
||||
* 在一分钟内,CrowdSec 能够处理所有的日志
|
||||
* 95% 的僵尸网络被禁止,攻击得到有效缓解
|
||||
* 15 个域现在受到保护,不受 DDoS 攻击
|
||||
|
||||
根据 Sorf Networks 的总监 Cagdas Aydogdu 的说法,CrowdSec 的平台使团队“能够在令人难以置信的短时间内提供一个世界级的高效防御系统”。
|
||||
|
||||
* * *
|
||||
|
||||
本文改编自[如何用 CrowdSec 在 1 分钟内阻止 7000 台机器的僵尸网络][8],原载于 CrowdSec 网站。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/open-source-vs-ddos-attacks
|
||||
|
||||
作者:[Philippe Humeau][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/philippe-humeau
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security_password_chaos_engineer_monster.png?itok=J31aRccu (Security monster)
|
||||
[2]: https://www.businesswire.com/news/home/20200916005046/en/DDoS-Attacks-Increase-by-151-in-First-Half-Of-2020
|
||||
[3]: https://crowdsec.net/
|
||||
[4]: https://opensource.com/article/20/10/crowdsec
|
||||
[5]: https://www.fail2ban.org
|
||||
[6]: https://opensource.com/sites/default/files/uploads/crowdsec_servertraffic.png (Server traffic)
|
||||
[7]: https://hub.crowdsec.net/author/crowdsecurity/configurations/geoip-enrich
|
||||
[8]: https://crowdsec.net/2020/10/21/how-to-stop-a-botnet-with-crowdsec/
|
115
published/20201201 Try Jed as your Linux terminal text editor.md
Normal file
115
published/20201201 Try Jed as your Linux terminal text editor.md
Normal file
@ -0,0 +1,115 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12901-1.html)
|
||||
[#]: subject: (Try Jed as your Linux terminal text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/jed)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
尝试将 Jed 作为你的 Linux 终端文本编辑器
|
||||
======
|
||||
|
||||
> Jed 方便的下拉菜单,让新用户可以轻松地使用终端文本编辑器。
|
||||
|
||||

|
||||
|
||||
你可能听说过 Emacs、Vim 和 Nano 这些典型的 Linux 文本编辑器,但 Linux 有大量的开源文本编辑器,我的目标是在 12 月份对其中的 31 个文本编辑器进行一次公平的测试。
|
||||
|
||||
在这篇文章中,我将介绍 [Jed][2],它是一个基于终端的编辑器,它的特点是有一个方便的下拉菜单,这让那些刚刚接触终端编辑器的用户,以及那些不喜欢记住每个功能的组合键的用户而言变得特别容易。
|
||||
|
||||
### 安装 Jed
|
||||
|
||||
在 Linux 上,你的发行版软件仓库可能会让 Jed 通过你的软件包管理器安装:
|
||||
|
||||
```
|
||||
$ sudo dnf install jed
|
||||
```
|
||||
|
||||
并不是所有发行版都是如此,但它是一个很容易从源码编译的应用。首先,下载 [S 语言][3](Jed 的编写语言)并安装(其中 `x.y.z` 请替换为对应的版本号):
|
||||
|
||||
```
|
||||
$ wget https://www.jedsoft.org/releases/slang/slang-x.y.z.tar.bz2
|
||||
$ tar xvf slang*bz2
|
||||
$ cd slang-x.y.z
|
||||
$ ./configure ; make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
安装好后,对 [Jed 源码][4]也同样操作(其中 `x.y.z` 请替换为对应的版本号):
|
||||
|
||||
```
|
||||
$ wget https://www.jedsoft.org/releases/jed/jed-x.y.z.tar.bz2
|
||||
$ tar xvf jed*bz2
|
||||
$ cd jed-x.y.z
|
||||
$ ./configure ; make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
### 启动 Jed
|
||||
|
||||
Jed 在终端中运行,所以要启动它,只需打开终端,输入 `jed`:
|
||||
|
||||
```
|
||||
F10 key ==> File Edit Search Buffers Windows System Help
|
||||
|
||||
|
||||
This is a scratch buffer. It is NOT saved when you exit.
|
||||
|
||||
To access the menus, press F10 or ESC-m and the use the arrow
|
||||
keys to navigate.
|
||||
|
||||
Latest version information is available on the web from
|
||||
<http://www.jedsoft.org/jed/>. Other sources of JED
|
||||
information include the usenet newsgroups comp.editors and
|
||||
alt.lang.s-lang. To subscribe to the jed-users mailing list, see
|
||||
<http://www.jedsoft.org/jed/mailinglists.html>.
|
||||
|
||||
Copyright (C) 1994, 2000-2009 John E. Davis
|
||||
Email comments or suggestions to <jed@jedsoft.org>.
|
||||
|
||||
[ (Jed 0.99.19U) Emacs: *scratch* () 1/16 8:49am ]
|
||||
```
|
||||
|
||||
### 如何使用 Jed
|
||||
|
||||
Jed 自动加载的说明很清晰且很有帮助。你可以按 `F10` 键或 `Esc` 键,然后按字母 `M` 进入顶部菜单。这将使你的光标进入 Jed 顶部的菜单栏,但它不会打开菜单。要打开菜单,请按键盘上的回车键。使用方向键来浏览每个菜单。
|
||||
|
||||
屏幕上的菜单不仅对初次使用的用户很有帮助,对有经验的用户来说,它还提供了很好的键盘快捷键提醒。例如,你大概能猜到如何保存正在处理的文件。进入 **File** 菜单,选择 **Save**。如果你想加快这个过程,你可以记住 `Ctrl+X`,然后 `Ctrl+S` 的组合键(是的,这是连续的两个组合键)。
|
||||
|
||||
### 探索 Jed 的功能
|
||||
|
||||
对于一个简单的编辑器来说,Jed 拥有一系列令人惊讶的实用功能。它有一个内置的多路复用器,允许你同时打开多个文件,但它会“叠”在另一个文件之上,所以你可以在它们之间切换。你可以分割你的 Jed 窗口,让多个文件同时出现在屏幕上,改变你的颜色主题,或者打开一个 shell。
|
||||
|
||||
对于任何有 Emacs 使用经验的人来说,Jed 的许多“没有宣传”的功能,例如用于导航和控制的组合键,都是一目了然的。然而,当一个组合键与你所期望的大相径庭时,就会有一个轻微的学习(或者说没有学习)曲线。例如,GNU Emacs 中的 `Alt+B` 可以将光标向后移动一个字,但在 Jed 中,默认情况下,它是 **Buffers** 菜单的快捷键。这让我措手不及,大约本文每句话都遇到一次。
|
||||
|
||||
![Jed][8]
|
||||
|
||||
Jed 也有**模式**,允许你加载模块或插件来帮助你编写特定种类的文本。例如,我使用默认的 text 模式写了这篇文章,但当我在编写 [Lua][9] 时,我能够切换到 lua 模式。这些模式提供语法高亮,并帮助匹配括号和其他分隔符。你可以在 `/usr/share/jed/lib` 中查看 Jed 捆绑了哪些模式,而且因为它们是用 S 语言编写的,你可以浏览代码,并可能学习一种新的语言。
|
||||
|
||||
### 尝试 Jed
|
||||
|
||||
Jed 是一个令人愉快且清新的 Linux 终端文本编辑器。它轻量级,易于使用,设计相对简单。作为 Vi 的替代方案,你可以在你的 `~/.bashrc` 文件中(如果你是 root 用户,在 root 用户的 `~/.bashrc` 文件中)将 Jed 设置为 `EDITOR` 和 `VISUAL` 变量。今天就试试 Jed 吧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/jed
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
|
||||
[2]: https://www.jedsoft.org/jed
|
||||
[3]: https://www.jedsoft.org/releases/slang/
|
||||
[4]: https://www.jedsoft.org/releases/jed
|
||||
[5]: http://www.jedsoft.org/jed/\>
|
||||
[6]: http://www.jedsoft.org/jed/mailinglists.html\>
|
||||
[7]: mailto:jed@jedsoft.org
|
||||
[8]: https://opensource.com/sites/default/files/jed.png (Jed)
|
||||
[9]: https://opensource.com/article/20/2/lua-cheat-sheet
|
@ -0,0 +1,109 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12905-1.html)
|
||||
[#]: subject: (Zotero: An Open Source App to Help You Collect & Share Research)
|
||||
[#]: via: (https://itsfoss.com/zotero/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Zotero:一款帮助你收集和分享研究成果的开源应用
|
||||
======
|
||||
|
||||
> Zotero 是一款令人印象深刻的自由开源的应用,它让你可以收集、组织、引用和共享研究成果。你还可以使用 Zotero 为你的文档即时创建参考文献和书目。
|
||||
|
||||

|
||||
|
||||
通常,你可以[使用 Linux 上任何一款笔记应用][1]来收集和分享你的想法。但是,在这里,我想分享一些专门为你量身定做的东西,来帮助你收集、整理和分享你的研究成果,即 [Zotero][2]。
|
||||
|
||||
### Zotero:收集、整理和分享研究成果
|
||||
|
||||
![][3]
|
||||
|
||||
Zotero 是一个完全开源的项目,你可以在 [GitHub][4] 上找到它。它的目的是帮助你轻松地收集、整理、添加笔记和分享你的研究成果。
|
||||
|
||||
而且,这一切都不需要基于云端的服务,它是完全离线的。所以,你的研究成果是属于你的。当然,除非你出于协作目的想将其同步,为此你可能需要参考[该文档][5]。
|
||||
|
||||
作为一个好的起点,你可以选择 [WebDAV 存储][6],或者直接创建一个 Zotero 帐户来轻松同步和分享你的研究成果。
|
||||
|
||||
例如,我创建了一个名为 `ankush9` 的 Zotero 账户,你可以在 <https://www.zotero.org/ankush9> 找到我的研究合集(我添加到我的出版物中)。
|
||||
|
||||
![][7]
|
||||
|
||||
这使得它很容易分享你组织的研究成果,你可以选择将哪些部分共享到出版物中。
|
||||
|
||||
让我着重介绍一下 Zotero 的主要功能,来帮助你决定是否需要尝试一下。
|
||||
|
||||
### Zotero 的功能
|
||||
|
||||
![][8]
|
||||
|
||||
* 能够使用浏览器插件从网页直接添加信息
|
||||
* 为每份资料添加说明
|
||||
* 支持添加标签
|
||||
* 支持添加语音记录
|
||||
* 添加视频作为附件
|
||||
* 添加软件作为附件
|
||||
* 将电子邮件作为附件
|
||||
* 将播客作为附件
|
||||
* 添加博客文章
|
||||
* 添加一个文件链接
|
||||
* 根据项目建立书目
|
||||
* 离线快照存储(无需连接互联网即可访问保存的网页)
|
||||
* 可以复制项目
|
||||
* 整理库中的项目
|
||||
* 提供了一个垃圾箱,可以删除你的项目,并在需要时轻松恢复。
|
||||
* 支持同步
|
||||
* 支持数据导出
|
||||
* 可整合 LibreOffice 插件
|
||||
* 使用你的 Zotero 个人资料链接轻松分享你的研究笔记。
|
||||
* 跨平台支持
|
||||
|
||||
如果你只是想快速创建书目,你可以尝试他们的另一个工具,[ZoteroBib][9]。
|
||||
|
||||
### 在 Linux 上安装 Zotero
|
||||
|
||||
![][12]
|
||||
|
||||
它适用于 Windows、macOS 和 Linux。对于 Linux,如果你使用的是基于 Ubuntu 的发行版(或 Ubuntu 本身),你可以下载一个 deb 文件(由第三方维护)并安装它。
|
||||
|
||||
安装 [deb 文件][13]很简单,它在 Pop OS 20.04 上工作得很好。如果你使用的是其他 Linux 发行版,你可以[解压 tar 包][14]并进行安装。
|
||||
|
||||
你可以按照[官方安装说明][15]来找到合适的方法。
|
||||
|
||||
- [下载 Zotero][2]
|
||||
|
||||
### 总结
|
||||
|
||||
它有大量的功能,你可以组织、分享、引用和收集资源,以供你进行搜索。由于支持音频、视频、文本和链接,它应该适合几乎所有的东西。
|
||||
|
||||
当然,我会将它推荐给有经验的用户,让它发挥最大的作用。而且,如果你之前使用过树状图(思维导图)笔记工具的人,你就知道要做什么了。
|
||||
|
||||
你觉得 Zotero 怎么样?如果它不适合你,你有更好的替代品建议么?请在下面的评论中告诉我你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/zotero/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/note-taking-apps-linux/
|
||||
[2]: https://www.zotero.org/
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/zotero-app.png?resize=800%2C481&ssl=1
|
||||
[4]: https://github.com/zotero/zotero
|
||||
[5]: https://www.zotero.org/support/
|
||||
[6]: https://en.wikipedia.org/wiki/WebDAV
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/zotero-online-publication.jpg?resize=800%2C600&ssl=1
|
||||
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/zotero-extension.jpg?resize=800%2C414&ssl=1
|
||||
[9]: https://zbib.org/
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/zotero-preferences.png?resize=800%2C489&ssl=1
|
||||
[13]: https://itsfoss.com/install-deb-files-ubuntu/
|
||||
[14]: https://en.wikipedia.org/wiki/Tarball
|
||||
[15]: https://www.zotero.org/support/installation
|
@ -0,0 +1,118 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12898-1.html)
|
||||
[#]: subject: (How to Add Third-Party Repositories in Fedora and Get Access to a Huge Number of Additional Software)
|
||||
[#]: via: (https://itsfoss.com/fedora-third-party-repos/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
如何在 Fedora 中添加第三方存储库以访问大量附加软件
|
||||
======
|
||||
|
||||

|
||||
|
||||
在你安装 Fedora 后。你可能会发现你想要安装和使用的一些软件在软件商店中找不到。出于一些原因,这些软件包不能出现在 Fedora 存储库中。
|
||||
|
||||
不用担心,我将告诉你如何为 Fedora 添加第三方存储库来使这些软件包可使用。
|
||||
|
||||
### 在 Fedora 中的第三方存储库是什么?
|
||||
|
||||
操作系统开发人员通常会决定哪些软件包可以在其存储库中使用,哪些软件包不可以在其存储库中使用。Fedora 也是如此。依据 [Fedora 文档][1] ,第三方存储库包含有 “拥有更为宽松的许可政策,并提供 Fedora 因各种原因所排除软件包” 的软件包。
|
||||
|
||||
Fedora 强制执行下面的 [准则][2] ,当它打包软件包时:
|
||||
|
||||
* 如果它是专有的,它就不能包含在 Fedora 中
|
||||
* 如果它在法律上被限制,它就不能包含在 Fedora 中
|
||||
* 如果它违反美国法律(特别是联邦政府或适用于州政府的法律),它就不能包含在 Fedora 中
|
||||
|
||||
因此,有一些可以由用户自行添加的存储库。这使得用户能够访问附加的软件包。
|
||||
|
||||
### 在 Fedora 中启用 RPM Fusion 存储库
|
||||
|
||||
[RPM Fusion][3] 是 Fedora 的第三方应用程序的主要来源。RPM Fusion 是由三个项目(Dribble、Freshrpms 和 Livna)合并而成的。RPM Fusion 提供两种不同的软件存储库。
|
||||
|
||||
* free 存储库:包含开源软件。
|
||||
* nonfree 存储库:包含没有开源协议的软件,但是它们的源文件代码却是可以自由使用的。
|
||||
|
||||
这里有两种方法来启动 RPM Fusion:从终端启用,或通过点击几个按钮来启用。我们将逐一查看。
|
||||
|
||||
#### 方法 1:命令行方法
|
||||
|
||||
这是启用 RPM Fusion 存储库的最简单的方法。只需要输入下面的命令即可启用两个存储库:
|
||||
|
||||
```
|
||||
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
```
|
||||
|
||||
会要求你输入密码、确认是否你想要安装这些存储库。在你确认后,安装过程将在几秒钟或几分钟内完成。
|
||||
|
||||
![通过命令行安装 RPM Fusion][4]
|
||||
|
||||
#### 方法 2:图形用户界面方法
|
||||
|
||||
使用这个方法来启用 RPM Fusion 存储库,你需要访问 [RPM Fusion 网站][5] 。你将看到针对不同 Fedora 版本的两个存储库的链接。
|
||||
|
||||
RPM Fusion 建议先安装 free 存储库。因此,单击针对你 Fedora 版本的 free 存储库的链接。然后会打开一个窗口来询问你是否想安装该存储库。单击安装。
|
||||
|
||||
![通过图形用户界面安装 RPM Fusion][6]
|
||||
|
||||
在安装过程完成后,返回并使用相同的步骤安装 nonfree 存储库。
|
||||
|
||||
### 启用 Fedora 的第三方存储库
|
||||
|
||||
Fedora 最近开始提供它自己的 [第三方应用程序存储库][7] 。在这个存储库中 [可使用的应用程序的数量][8] 是非常少的。你可以 [使用它来在 Fedora 上安装 Chrome 浏览器][9] 。除 Chrome 外,它也包含 Adobe Brackets、Atom、Steam、Vivaldi、Opera 等应用程序。
|
||||
|
||||
就像 RPM Fusion 一样,你可以通过终端或图形用户界面的方法来启用这个存储库。
|
||||
|
||||
#### 方法 1:命令行方法
|
||||
|
||||
为启用 Fedora 的第三方存储库,输入下面的命令到你的终端中:
|
||||
|
||||
```
|
||||
sudo dnf install fedora-workstation-repositories
|
||||
```
|
||||
|
||||
当被提示时,确保输入你的密码并输入 `Y` 来确认安装。
|
||||
|
||||
#### 方法 2:图形用户界面方法
|
||||
|
||||
如果你不习惯使用终端,你可以使用图形用户界面方法。
|
||||
|
||||
首先,你需要打开 Gnome “软件”。接下来,你需要单击右上角的汉堡菜单,并从菜单中选择“软件存储库”。
|
||||
|
||||
![Gnome 软件的菜单][10]
|
||||
|
||||
在软件存储库窗口中,你将在其顶部看到写着 “第三方存储库” 字样的部分。单击“安装”按钮。当你被提示时,输入你的密码。
|
||||
|
||||
![Fedora 第三方存储库安装][11]
|
||||
|
||||
随着这些附加存储库的启用,你可以安装软件到你的系统当中。你可以从软件中心管理器或使用 DNF 软件包管理器来轻松地安装它们。
|
||||
|
||||
如果你发现这篇文章很有趣,请花费一些时间来在社交媒体上分享它。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/fedora-third-party-repos/
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://docs.fedoraproject.org/en-US/quick-docs/setup_rpmfusion/#third-party-repositories
|
||||
[2]: https://fedoraproject.org/wiki/Forbidden_items
|
||||
[3]: https://rpmfusion.org/RPM%20Fusion
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/install-rpmfusion-cli.png?resize=800%2C604&ssl=1
|
||||
[5]: https://rpmfusion.org/Configuration
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/install-rpmfusion-gui.png?resize=800%2C582&ssl=1
|
||||
[7]: https://fedoraproject.org/wiki/Workstation/Third_Party_Software_Repositories
|
||||
[8]: https://fedoraproject.org/wiki/Workstation/Third_party_software_list
|
||||
[9]: https://itsfoss.com/install-google-chrome-fedora/
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/software-meni.png?resize=800%2C672&ssl=1
|
||||
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/fedora-third-party-repo-gui.png?resize=746%2C800&ssl=1
|
||||
[12]: https://%0Areddit.com/r/linuxusersgroup
|
@ -0,0 +1,73 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12889-1.html)
|
||||
[#]: subject: (Download the 2020 Linux Foundation Annual Report)
|
||||
[#]: via: (https://www.linux.com/news/download-the-2020-linux-foundation-annual-report/)
|
||||
[#]: author: (The Linux Foundation https://www.linuxfoundation.org/blog/2020/12/download-the-2020-linux-foundation-annual-report/)
|
||||
|
||||
下载 2020 年度 Linux 基金会年度报告
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
2020 年对于 <ruby>Linux 基金会<rt>Linux Foundation</rt></ruby>(LF)和我们托管的社区来说,是充满挑战的一年。在这次大流行期间,我们都看到我们和世界各地许多同事、朋友和家人的日常生活完全改变了。在我们的社区中,有太多的人也为失去家人和朋友而悲痛。
|
||||
|
||||
看到 LF 的成员加入到对抗 COVID-19 的斗争中,令人振奋。我们在世界各地的成员为科研人员贡献了技术资源,为挣扎中的家庭和个人提供了援助,为国家和国际努力做出了贡献,有些人甚至一起在 [LF 公共卫生][3] 下创建了开源项目,以帮助各国应对这场大流行病。
|
||||
|
||||
今年,我们的项目社区在继续发展,在许多开放技术领域、开放标准、开放数据和开放硬件方面都有新的举措。今年,我们迎接了 150 多个新社区加入 LF,包括 [FINOS 基金会][4],它是开源金融服务项目的保护项目。
|
||||
|
||||
我们的 [活动团队][5] 不得不进行了重大转型,在几周内,从面对面的活动转变为虚拟活动,参与者从不足 100 人到数万人不等。这些虚拟聚会帮助我们社区中的许多人在这个困难时期建立了联系。我们也学到了很多关于未来可能通过提供虚拟体验的<ruby>混合亲身活动<rt>hybrid in-person events</rt></ruby>来提供更具包容性的体验。今年,我们很想念在我们的社区中见到的许多朋友,并期待着在安全的情况下再次见到你们。
|
||||
|
||||
我们的 [培训和认证][6] 团队能够帮助 170 多万名报名参加我们免费培训课程的人。我要祝贺今年获得 LF 认证的 4 万多人。
|
||||
|
||||
《[LF 的 2020 年度工作报告][7]》显示,尽管商业环境充满挑战,但经过培训和认证的开源专业人员仍有大有需求,并能轻松地展示其价值。
|
||||
|
||||
作为我们正在进行的多元化努力的一部分,在加入反对不平等的斗争中,我们的社区专注于该如何在项目中使用语言,并寻找导师来指导下一代的贡献者。我们的社区,如 Linux 内核团队和在北美 KubeCon 上发起的 <ruby>[包容性命名倡议][8]<rt>Inclusive Naming Initiative</rt></ruby>,在加强我们的互动方式上取得了进展。
|
||||
|
||||
今年是我们<ruby>联合发展基金会<rt>Joint Development Foundation</rt></ruby>(JDF)和<ruby>开放标准社区<rt>open standards communities</rt></ruby>的突破性一年。我们迎来了六个建立开放标准的新项目。[JDF 还被批准为 ISO/IEC JTC 1 公开发布规范(PAS)提交者][9]。今年还标志着我们的第一个开放标准社区 OpenChain 通过 PAS 程序,被正式认可为国际标准。今天,Linux 基金会可以把我们的社区,从开源仓库带到一个公认的全球标准。
|
||||
|
||||
今年,我们生态系统中的许多人已经站出来帮助安全工作。一个新的社区 <ruby>[开源安全基金会][10]<rt>Open Source Security Foundation</rt></ruby>(OpenSSF)启动了,以协调专注于提高开源软件安全性的努力。
|
||||
|
||||
当我们继续在美国与挑战作斗争时,[我们也重申 LF 是全球社区的一部分][11]。
|
||||
|
||||
我们的成员必须得应对国际贸易政策变化的一年,并了解到开放源码在政治上的蓬勃发展。来自世界各地的我们的成员社区参与了<ruby>开放合作<rt>open collaboration</rt></ruby>,因为它是开放、中立和透明的。这些参与者显然希望继续与全球同行合作,以应对大大小小的挑战。
|
||||
|
||||
在这困难的一年结束时,所有这些都让我们确信,开放合作是解决世界上最复杂挑战的模式。没有任何一个人、组织或政府能够单独创造出我们解决最紧迫问题所需的技术。我们代表整个 Linux 基金会团队,期待着帮助您和我们的社区应对接下来的任何挑战。
|
||||
|
||||
![][12]
|
||||
|
||||
Jim Zemlin,Linux 基金会执行总监
|
||||
|
||||
- [下载 Linux 基金会 2020 年度报告][2]
|
||||
|
||||
这篇文章首先发布于 [Linux 基金会][14]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/download-the-2020-linux-foundation-annual-report/
|
||||
|
||||
作者:[The Linux Foundation][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxfoundation.org/blog/2020/12/download-the-2020-linux-foundation-annual-report/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linuxfoundation.org/wp-content/uploads/2020/12/2020-Linux-Foundation-Annual-Report_blogheader.png
|
||||
[2]: http://linuxfoundation.org/2020-annual-report
|
||||
[3]: https://www.lfph.io/
|
||||
[4]: https://www.finos.org/
|
||||
[5]: https://events.linuxfoundation.org/
|
||||
[6]: https://training.linuxfoundation.org/
|
||||
[7]: https://training.linuxfoundation.org/resources/2020-open-source-jobs-report/
|
||||
[8]: https://inclusivenaming.org/
|
||||
[9]: https://www.linuxfoundation.org/blog/2020/05/joint-development-foundation-recognized-as-an-iso-iec-jtc-1-pas-submitter-and-submits-openchain-for-international-review/
|
||||
[10]: https://openssf.org/
|
||||
[11]: https://www.linuxfoundation.org/blog/2020/08/open-source-collaboration-is-a-global-endeavor/
|
||||
[12]: https://www.linuxfoundation.org/wp-content/uploads/2020/12/JimZemlin_Sig-150x150.png
|
||||
[13]: https://www.linuxfoundation.org/blog/2020/12/download-the-2020-linux-foundation-annual-report/
|
||||
[14]: https://www.linuxfoundation.org/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (chenmu-kk)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -0,0 +1,106 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Openness is the key to innovation, history shows)
|
||||
[#]: via: (https://opensource.com/open-organization/20/12/open-innovation-history)
|
||||
[#]: author: (Ron McFarland https://opensource.com/users/ron-mcfarland)
|
||||
|
||||
Openness is the key to innovation, history shows
|
||||
======
|
||||
History demonstrates the kinds of organizational structures that foster
|
||||
innovation: open, communal, and humble. Here are just two examples.
|
||||
![Team checklist][1]
|
||||
|
||||
In the [first part of this article series][2]—an extended review of the book [How Innovation Works][3] by [Matt Ridley][4]—I examined Ridley's characterization of innovation: it's gradual, incremental, and collective, and involves extensive collaboration between parties. This, I argued, is why [open organization principles][5] are so important and play a major role in fostering innovation.
|
||||
|
||||
In [part two of the series][6], I reviewed Ridley's assessment of the environments where innovation and discovery thrive, and I demonstrated some essential characteristics of the innovation process.
|
||||
|
||||
Now, in this concluding part of my review, I bring these ideas alive by recounting case studies of innovative discoveries throughout history.
|
||||
|
||||
### Innovation throughout history
|
||||
|
||||
In _How Innovation Works_, Ridley mentions that innovation is mostly a "bottom-up phenomenon." For example, throughout the 19th century, as Britain and Europe developed new railways, the steel industry, new applications for electricity, the textile industry, and many other breakthroughs, governments weren't involved. Only after the fact did governments play the role of regulator and standards creator. Sometimes, governments even played the role of the customer or user.
|
||||
|
||||
The same was true in America in the early 20th century. There were few public subsidies for research and development before 1940. And after World War II, the Japanese miracle was a function of private corporations backed by a vast ecosystem of small enterprises. Most efforts resembled open organizations—a modest group of dedicated hands-on, ground floor members. That's where most innovation originated, on the ground floor according to open organization principles.
|
||||
|
||||
By contrast, the Soviet Union was a very clear case of a public governmental entrepreneurial state; it funded a great deal of research centrally, and allowed virtually no involvement from private enterprise. Innovation in transportation, food production, health care, and consumer products suffered as a result. (In this environment open organization principles were not in use.)
|
||||
|
||||
Innovations come from humble places, Ridley's argues, and large, bureaucratic corporations were not particularly good at developing innovative products. Instead, small, loosely assembled communities (open organizations with front line teams) have been more innovative throughout history. They have been far more capable of exploring new concepts, particularly if they have a wide base of contributions to work with.
|
||||
|
||||
Let me review two historical examples of this, drawn from Ridley's work (one brief, one lengthier).
|
||||
|
||||
### Lighting every house (the light bulb)
|
||||
|
||||
Who invented the light bulb? Easy answer: Thomas Edison.
|
||||
|
||||
But at least a dozen other people were working on similar technologies around the same time, even before Edison, as Ridley documents in detail in _How Innovation Works_. Edison, however, [gets recognition for the invention][2].
|
||||
|
||||
Through some 50,000 trial-and-error experiments, a full complement of staff developed a usable, affordable light bulb for interior and room lighting (Edison's team tested roughly 6,000 plant materials until it found the right kind of bamboo for the bulb's filament). The invention made both oil lamps and gas lamps things of the past. Perhaps better than anyone else at the time, Edison knew that innovation was largely a team effort. He hired groups of skilled craftsmen and scientists (totalling 200 people in all) and worked them incredibly hard. Their collaboration, iterative and adaptive testing, and sharing eventually led to the registration of more than 400 patents in six years. Edison supported his innovative teams extensively, stuffing his workshops with every kind of material, tool, and book. His goal was not simply to inspire invention; it was to turn ideas into practical, reliable, and affordable items—the result of extensive application of open organization principles.
|
||||
|
||||
### Two approaches to flight (the powered aircraft)
|
||||
|
||||
Now let me offer a more detailed example, one focused on the innovation of powered aircraft. To better illustrate the advantage of an open organizational approach, I'll juxtapose two approaches to this innovation.
|
||||
|
||||
#### Samuel Langley's approach
|
||||
|
||||
In 1903, the East Coast of the United States saw the first airplane flight by Samuel Langley. It impressed the US government, which expressed a desire to invest in the development of powered flight (powered flight, of course, would allow people to travel longer distances).
|
||||
|
||||
Innovations come from humble places.
|
||||
|
||||
Initially, the American government supported Langley's experiments with an investment of $50,000. Later, it offered another US$20,000. Langley had convinced the government he could build a powered plane that would stay in the air longer than a simple glider (Langley was a professor from New England, an astronomer, and a well-connected head of the Smithsonian Institute in Washington, DC, so his reputation would have seemed to support his claims).
|
||||
|
||||
Because of his confidence, he decided to _keep all his research and experiments confidential_. He could not have been more closed in his approach to research and experimentation.
|
||||
|
||||
This went on for seven years, until a test plane was finally ready for presentation to the government. Langley was not a hands-on experimenter and was not willing to pilot his prototype plane himself (he commissioned Charles Manly). The plane crashed after flying just a short distance, to everyone's disappointment. Langley's reputation never recovered. The fiasco led to the US government pulling all funding for the project, and it gave up on powered flight after a decade of wasting money.
|
||||
|
||||
From the perspective of someone thinking with open organization principles, Langley would seem to have done everything wrong. He spent lots of money, depended on a single authority (the government), consulted with very few outside people, and built the full aircraft from scratch instead of building and testing components in an incremental way, by experimenting with different designs, shapes, sizes, and weights. He built _no community_ to work on the project. He _included_ only the minimum necessary outsiders. He was _not transparent_ of his activities or concerns. He did not establish step-by-step milestones in which he could make _adaptations_ if need be. And, he _collaborated_ with as few people as possible.
|
||||
|
||||
#### The Wright brothers' approach
|
||||
|
||||
But just south of Langley's failure, in an area called [Kitty Hawk][7], with almost nobody watching, two brothers from Ohio were busy achieving innovation in powered flight, and by spending only a fraction of what Langley did. They were Orville and Wilbur Wright.
|
||||
|
||||
The Wright brothers' initial test flight lasted 12 seconds and traveled 40 yards (37 meters). Their second flight (later that day) lasted almost one minute and covered more than 800 feet (244 meters). Just five people were present to observe these successful powered flights.
|
||||
|
||||
Thinking again with open organization principles, we might say the Wright brothers did everything right.
|
||||
|
||||
Innovation happens when someone creates a community while working on a problem. Through concurrent community collaboration, that group might make discoveries that lead to an innovation.
|
||||
|
||||
These two brothers were not well-known researchers (or even engineers for that matter). They simply were experienced bicycle builders and had a small shop. They were diligent craftsmen and loved building things. They simply wanted to address the challenges and problems of powered flight through building an aircraft. Fueled by those passions, they started building a development team (_community_ building), which included others in the project to bring in valued experience. They _included_ key outside people. They were very _transparent_ regarding their activities and concerns (more on this in a moment). They established step-by-step milestones in which they could make _adaptations_ if need be.
|
||||
|
||||
Moreover, they _collaborated_ with as many people as they needed to, gathering expertise where they could find it. First they wrote to Otto Lillienthal in Frankfurt, Germany**,** a famous designer of gliders. They also approached a rather eccentric French-American in Chicago by the name of Octave Chanute, who studied the powered flight problems to overcome and published papers on them. These are examples of inclusivity at its best—approaching people far different than them to achieve something. Thorough documentation of the Wright brother's collaboration with Chanute (and his extensive network of like-minded thinkers) helped solidify their basic design for a powered aircraft. And just by luck, someone the Wright brothers hired to work in the bicycle shop was an extremely good mechanic and loved designing machines. His name was Charlie Taylor. The internal combustion engine was just being developed at that time, and the Wright brothers knew that the motors on the market were too heavy for an aircraft, so Charlie built one from scratch, using aluminium (a much lighter material).
|
||||
|
||||
This more open approach to innovating in the field of powered aircraft is the one that eventually gave rise to the inventions (and industry) we enjoy today and brought the Wright brothers fame.
|
||||
|
||||
### History lessons
|
||||
|
||||
Think about both those examples, two case studies of innovation through open organization principles. Both indicate that, for _any_ innovation, quite a few people are required (not lone individuals). In both cases, inventors needed to "cross-pollinate" ideas in two ways:
|
||||
|
||||
1. concurrently, working together directly, and
|
||||
2. learning sequentially over time.
|
||||
|
||||
|
||||
|
||||
Our lessons from history illustrate these approaches to innovation. Innovation happens when someone creates a _community_ while working on a problem. Through concurrent community collaboration, that group might make discoveries that lead to an innovation. Sometimes, however, those communities fail. But because they _document_ their work as they collaborate, another person (and community) can replicate what they've done and improve upon it (sequential innovation)—perhaps succeeding where the first group did not.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/open-organization/20/12/open-innovation-history
|
||||
|
||||
作者:[Ron McFarland][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ron-mcfarland
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/checklist_todo_clock_time_team.png?itok=1z528Q0y (Team checklist)
|
||||
[2]: https://opensource.com/open-organization/20/10/best-ideas-recognition-innovation
|
||||
[3]: https://www.goodreads.com/en/book/show/45449488-how-innovation-works
|
||||
[4]: https://en.wikipedia.org/wiki/Matt_Ridley
|
||||
[5]: https://theopenorganization.org/definition/
|
||||
[6]: https://opensource.com/open-organization/20/11/environments-for-innovation
|
||||
[7]: https://www.google.com/search?rlz=1CAKMJF_enJP874&sxsrf=ALeKk02B7m1kL1nXrRT2cH4-zyr8VV_DDw:1597632027500&ei=u-05X5byJ8Ko-QaRt6HoDQ&q=kitty%20hawk%20museum&oq=kitty+hawk+mus&gs_lcp=CgZwc3ktYWIQARgAMgIIADICCAAyAggAMgIIADICCAAyAggAMgIIADoECAAQRzoHCC4QJxCTAjoHCAAQFBCHAjoICC4QxwEQrwE6BAgAEENQ04sBWIqeAWCvtAFoAXABeACAAY4BiAHEBZIBAzEuNZgBAKABAaoBB2d3cy13aXrAAQE&sclient=psy-ab&npsic=0&rflfq=1&rlha=0&rllag=36111118,-75775286,9090&tbm=lcl&rldimm=17550871878646241173&lqi=ChFraXR0eSBoYXdrIG11c2V1bVobCgZtdXNldW0iEWtpdHR5IGhhd2sgbXVzZXVt&phdesc=B2b85nIlVwQ&ved=2ahUKEwjz-uuLm6HrAhVLFogKHXjGD7YQvS4wAHoECAoQLQ&rldoc=1&tbs=lrf:!1m4!1u3!2m2!3m1!1e1!1m4!1u2!2m2!2m1!1e1!1m4!1u16!2m2!16m1!1e1!1m4!1u16!2m2!16m1!1e2!1m5!1u15!2m2!15m1!1shas_1wheelchair_1accessible_1entrance!4e2!2m1!1e2!2m1!1e16!2m1!1e3!3sIAE,lf:1,lf_ui:1&rlst=f#rlfi=hd:;si:17259280498191889741,l,ChFraXR0eSBoYXdrIG11c2V1bVobCgZtdXNldW0iEWtpdHR5IGhhd2sgbXVzZXVt,y,tBWxg7TmYyk;mv:%5B%5B41.993476711913615,-73.13628440817928%5D,%5B33.753275807154516,-89.35208728632068%5D,null,%5B37.98892655631248,-81.24418584724998%5D,6%5D
|
@ -1,104 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Dual booting Windows and Linux using UEFI)
|
||||
[#]: via: (https://opensource.com/article/19/5/dual-booting-windows-linux-uefi)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss/users/ckrzen)
|
||||
|
||||
Dual booting Windows and Linux using UEFI
|
||||
======
|
||||
A quick rundown of setting up Linux and Windows to dual boot on the same
|
||||
machine, using the Unified Extensible Firmware Interface (UEFI).
|
||||
![Linux keys on the keyboard for a desktop computer][1]
|
||||
|
||||
Rather than doing a step-by-step how-to guide to configuring your system to dual boot, I’ll highlight the important points. As an example, I will refer to my new laptop that I purchased a few months ago. I first installed [Ubuntu Linux][2] onto the entire hard drive, which destroyed the pre-installed [Windows 10][3] installation. After a few months, I decided to install a different Linux distribution, and so also decided to re-install Windows 10 alongside [Fedora Linux][4] in a dual boot configuration. I’ll highlight some essential facts to get started.
|
||||
|
||||
### Firmware
|
||||
|
||||
Dual booting is not just a matter of software. Or, it is, but it involves changing your firmware, which among other things tells your machine how to begin the boot process. Here are some firmware-related issues to keep in mind.
|
||||
|
||||
#### UEFI vs. BIOS
|
||||
|
||||
Before attempting to install, make sure your firmware configuration is optimal. Most computers sold today have a new type of firmware known as [Unified Extensible Firmware Interface (UEFI)][5], which has pretty much replaced the other firmware known as [Basic Input Output System (BIOS)][6], which is often included through the mode many providers call Legacy Boot.
|
||||
|
||||
I had no need for BIOS, so I chose UEFI mode.
|
||||
|
||||
#### Secure Boot
|
||||
|
||||
One other important setting is Secure Boot. This feature detects whether the boot path has been tampered with, and stops unapproved operating systems from booting. For now, I disabled this option to ensure that I could install Fedora Linux. According to the Fedora Project Wiki [Features/Secure Boot ][7] Fedora Linux will work with it enabled. This may be different for other Linux distributions —I plan to revisit this setting in the future.
|
||||
|
||||
In short, if you find that you cannot install your Linux OS with this setting active, disable Secure Boot and try again.
|
||||
|
||||
### Partitioning the boot drive
|
||||
|
||||
If you choose to dual boot and have both operating systems on the same drive, you have to break it into partitions. Even if you dual boot using two different drives, most Linux installations are best broken into a few basic partitions for a variety of reasons. Here are some options to consider.
|
||||
|
||||
#### GPT vs MBR
|
||||
|
||||
If you decide to manually partition your boot drive in advance, I recommend using the [GUID Partition Table (GPT)][8] rather than the older [Master Boot Record (MBR)][9]. Among the reasons for this change, there are two specific limitations of MBR that GPT doesn’t have:
|
||||
|
||||
* MBR can hold up to 15 partitions, while GPT can hold up to 128.
|
||||
* MBR only supports up to 2 terabytes, while GPT uses 64-bit addresses which allows it to support disks up to 8 million terabytes.
|
||||
|
||||
|
||||
|
||||
If you have shopped for hard drives recently, then you know that many of today’s drives exceed the 2 terabyte limit.
|
||||
|
||||
#### The EFI system partition
|
||||
|
||||
If you are doing a fresh installation or using a new drive, there are probably no partitions to begin with. In this case, the OS installer will create the first one, which is the [EFI System Partition (ESP)][10]. If you choose to manually partition your drive using a tool such as [gdisk][11], you will need to create this partition with several parameters. Based on the existing ESP, I set the size to around 500MB and assigned it the ef00 (EFI System) partition type. The UEFI specification requires the format to be FAT32/msdos, most likely because it is supportable by a wide range of operating systems.
|
||||
|
||||
![Partitions][12]
|
||||
|
||||
### Operating System Installation
|
||||
|
||||
Once you accomplish the first two tasks, you can install your operating systems. While I focus on Windows 10 and Fedora Linux here, the process is fairly similar when installing other combinations as well.
|
||||
|
||||
#### Windows 10
|
||||
|
||||
I started the Windows 10 installation and created a 20 Gigabyte Windows partition. Since I had previously installed Linux on my laptop, the drive had an ESP, which I chose to keep. I deleted all existing Linux and swap partitions to start fresh, and then started my Windows installation. The Windows installer automatically created another small partition—16 Megabytes—called the [Microsoft Reserved Partition (MSR)][13]. Roughly 400 Gigabytes of unallocated space remained on the 512GB boot drive once this was finished.
|
||||
|
||||
I then proceeded with and completed the Windows 10 installation process. I then rebooted into Windows to make sure it was working, created my user account, set up wi-fi, and completed other tasks that need to be done on a first-time OS installation.
|
||||
|
||||
#### Fedora Linux
|
||||
|
||||
I next moved to install Linux. I started the process, and when it reached the disk configuration steps, I made sure not to change the Windows NTFS and MSR partitions. I also did not change the EPS, but I did set its mount point to **/boot/efi**. I then created the usual ext4 formatted partitions, **/** (root), **/boot** , and **/home**. The last partition I created was Linux **swap**.
|
||||
|
||||
As with Windows, I continued and completed the Linux installation, and then rebooted. To my delight, at boot time the [GRand][14] [Unified Boot Loader (GRUB)][14] menu provided the choice to select either Windows or Linux, which meant I did not have to do any additional configuration. I selected Linux and completed the usual steps such as creating my user account.
|
||||
|
||||
### Conclusion
|
||||
|
||||
Overall, the process was painless. In past years, there has been some difficulty navigating the changes from UEFI to BIOS, plus the introduction of features such as Secure Boot. I believe that we have now made it past these hurdles and can reliably set up multi-boot systems.
|
||||
|
||||
I don’t miss the [Linux LOader (LILO)][15] anymore!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/5/dual-booting-windows-linux-uefi
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/alanfdoss/users/ckrzen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_keyboard_desktop.png?itok=I2nGw78_ (Linux keys on the keyboard for a desktop computer)
|
||||
[2]: https://www.ubuntu.com
|
||||
[3]: https://www.microsoft.com/en-us/windows
|
||||
[4]: https://getfedora.org
|
||||
[5]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface
|
||||
[6]: https://en.wikipedia.org/wiki/BIOS
|
||||
[7]: https://fedoraproject.org/wiki/Features/SecureBoot
|
||||
[8]: https://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||
[9]: https://en.wikipedia.org/wiki/Master_boot_record
|
||||
[10]: https://en.wikipedia.org/wiki/EFI_system_partition
|
||||
[11]: https://sourceforge.net/projects/gptfdisk/
|
||||
[12]: /sites/default/files/u216961/gdisk_screenshot_s.png
|
||||
[13]: https://en.wikipedia.org/wiki/Microsoft_Reserved_Partition
|
||||
[14]: https://en.wikipedia.org/wiki/GNU_GRUB
|
||||
[15]: https://en.wikipedia.org/wiki/LILO_(boot_loader)
|
@ -1,181 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (alim0x)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Creating a Chat Bot with Recast.AI)
|
||||
[#]: via: (https://opensourceforu.com/2019/11/creating-a-chat-bot-with-recast-ai/)
|
||||
[#]: author: (Athira Lekshmi C.V https://opensourceforu.com/author/athira-lekshmi/)
|
||||
|
||||
Creating a Chat Bot with Recast.AI
|
||||
======
|
||||
|
||||
[![][1]][2]
|
||||
|
||||
_According to a Gartner report from February 2018, “25 per cent of customer service and support operations will integrate virtual customer assistant (VCA) or chatbot technology across engagement channels by 2020, up from less than 2 per cent in 2017.” In the light of this, readers will find this tutorial on how the open source Recast. AI bot-creating platform works, helpful._
|
||||
|
||||
Chat bots, both voice based and others, have been in use for quite a while now. From chatbots that engage the user in a murder mystery game to bots which help in real estate deals and medical diagnosis, chatbots have traversed across domains.
|
||||
|
||||
There are many platforms which enable users to create and deploy bots. Recast.AI (now known as SAP Conversational AI after its acquisition by SAP) is a forerunner amongst these.
|
||||
|
||||
The cool interface, its collaborative nature and the analytics tools it provides, make it a popular choice.
|
||||
As the Recast official site says, “It is an ultimate collaborative platform to build, train, deploy and monitor intelligent bots.”
|
||||
|
||||
![Figure 1: Setting the bot properties][3]
|
||||
|
||||
![Figure 2: Bot dashboard][4]
|
||||
|
||||
![Figure 3: Searching an intent][5]
|
||||
|
||||
**Building a basic bot in Recast**
|
||||
Let us look at how to build a basic bot in Recast.
|
||||
|
||||
1. Create an account in _<https://cai.tools.sap>_. Signing up can be done either with an email ID or with a GitHub account.
|
||||
2. Once you log in, you will land on the dashboard. Click on the + New Bot icon on the top right-hand side to create a new bot.
|
||||
3. On the next screen, you will see that there is a set of predefined skills you can select. Select Greetings for the time being (Figure 1). This bot is already trained to understand basic greetings.
|
||||
4. Provide a name for your bot. For now, since this is a very basic bot, you can have the bot crack some jokes, so let us name it Joke Bot and select the default language as English.
|
||||
5. Select Non-personal data under the data policy since you won’t be dealing with any sensitive information; then select the Public bot option and click on Create a bot.
|
||||
|
||||
|
||||
|
||||
So that’s your bot created on the Recast platform.
|
||||
|
||||
![Figure 4: @joke intent][6]
|
||||
|
||||
![Figure 5: Predefined expressions][7]
|
||||
|
||||
**The five stages of developing a bot**
|
||||
To use the words from the official Recast blog, there are five stages in a bot’s life.
|
||||
|
||||
* Training – Teaching your bot what it needs to understand
|
||||
* Building – Creating your conversational flow with the Bot Builder tool
|
||||
* Coding – Connecting your bot with external APIs or a database
|
||||
* Connecting – Shipping your bot to one or several messaging platforms
|
||||
* Monitoring – Training your bot to make it sharper and get insights on its usage
|
||||
|
||||
|
||||
|
||||
**Training a bot through intents**
|
||||
You will be able to see the options to either search, fork or create an intent in the dashboard.
|
||||
“An intent is a box of expressions that mean the same thing but which are constructed in different ways. Intents are the heart of your bot’s understanding. Each one of your intents represents an idea your bot is able to understand.” (from the _Recast.AI_ website)
|
||||
As decided earlier, you need the bot to be able to crack jokes. So the base line is that the bot should be able to understand that the user is asking it to tell a joke; it shouldn’t be that even when the user just says, “Hi,” the bot responds with a joke – that would not be good.
|
||||
So group the utterances that the user might make, like:
|
||||
|
||||
```
|
||||
Tell me a joke.
|
||||
Tell me a funny fact.
|
||||
Can you crack a joke?
|
||||
What’s funny today?
|
||||
```
|
||||
|
||||
…………………
|
||||
|
||||
Before going on to create the intent from scratch, let us explore the Search/fork option. Type _Joke_ in the search field (Figure 3). This gives a list of intents created by users of Recast around the globe, which is public, and this is why Recast is said to be collaborative in nature. So there’s no need to create all intents from scratch, one can build upon intents already created. This brings down the effort needed to train the bot with common intents.
|
||||
|
||||
* Select the first intent in the list and fork it into the bot.
|
||||
* Click on the Fork button. The intent is now added to the bot (Figure 4).
|
||||
* Click on the intent @joke, and a list of expressions which already exist in the intent will be displayed (Figure 5).
|
||||
* Add a few more expressions to it (Figure 6).
|
||||
|
||||
|
||||
|
||||
![Figure 6: Suggested expressions][8]
|
||||
|
||||
![Figure 7: Suggested expressions][9]
|
||||
|
||||
Once a few expressions are added, the bot gives suggestions like shown in Figure 7. Select a few and add them to the intent (Figure 7).
|
||||
You can also tag your own custom entities to detect keywords, depending on your bot’s context.
|
||||
|
||||
**Skills**
|
||||
A skill is a block of conversation that has a clear purpose and that your bot can execute to achieve a goal. It can be as simple as the ability to greet someone, but it can also be more complex, like giving movie suggestions based on information provided by the user.
|
||||
|
||||
It need not be just a one query-answer set, but rather, skills running through multiple exchanges. For example, consider a bot which helps you learn about currency exchange rates. It starts by asking the source currency, then the target currency, before giving the exact response. Skills can be combined to create complex conversational flows.
|
||||
Here’s how you create a skill for the joke bot:
|
||||
|
||||
* Go to the _Build_ tab. Click on the + icon to create a skill.
|
||||
* Name the skill _Joke_ (Figure 8)
|
||||
* Once created, click on the skill. You will see four tabs. _Read me, Triggers, Requirements and Actions_.
|
||||
* Navigate to the Requirements tab. You should store the information only if the intent joke is present. So, add a requirement as shown in Figure 9.
|
||||
|
||||
|
||||
|
||||
![Figure 8: Skills dashboard][10]
|
||||
|
||||
![Figure 9: Adding a trigger][11]
|
||||
|
||||
Since this is a simple use case, you needn’t consider any specific requirements in the Requirement tab but consider a case for which a response needs to be triggered only if certain keywords or entities are present – in such a case you will need ‘requirements’.
|
||||
|
||||
Requirements are either intents or entities that your skill needs to retrieve before executing actions. Requirements are pieces of information that are important in the conversation and that your bot can use; for example, the user’s name or a location. Once a requirement is completed, the associated value is stored in the bot’s memory for the entire conversation.
|
||||
|
||||
Now let us move to the Action tab to set the responses (see Figure 10).
|
||||
Click on Add _new message group_. Then select _Send message_ and add a text message, which can be any joke in this case. Also, since you don’t want your bot to crack the same joke each time, you can add multiple messages which will be randomly picked each time.
|
||||
|
||||
![Figure 10: Adding actions][12]
|
||||
|
||||
![Figure 11: Adding text messages][13]
|
||||
|
||||
![Figure 12: Setting up webchat][14]
|
||||
|
||||
**Channel integrations**
|
||||
Well, the success of a bot also depends upon how easily it is accessible. Recast has built-in integrations with many messaging channels such as Skype for Business, Kik Messenger, Telegram, Line, Facebook Messenger, Slack, Alexa, etc. In addition to that, Recast also provides SDKs to develop custom channels.
|
||||
|
||||
Also, there is a ready-to-use Web chat provided by Recast (in the Connect tab). You can customise the colour schemes, headers, bot pictures, etc. It provides you with a script tag to be injected into the page. Your interface is now up (Figure 12).
|
||||
|
||||
The Web chat code base is open sourced, which makes it easier for developers to play around with the look and feel, the standard response types and much more.
|
||||
The dashboard provides step-by-step procedures on how to deploy the bot on various channels. The joke bot was deployed in Telegram and in Web chat, as shown in Figure 13.
|
||||
|
||||
![Figure 13: Webchat deployed][15]
|
||||
|
||||
![Figure 14: Bot deployed in Telegram][16]
|
||||
|
||||
![Figure 15: Multi-language bot][17]
|
||||
|
||||
**And there is more**
|
||||
Recast supports multiple languages, Select one language as the base while creating the bot, but then you also have the option to add as many languages as you want.
|
||||
|
||||
The example considered here is a simple static joke bot, but actual use cases will need interaction with various systems. Recast has a Web hook feature which allows users to connect with various systems to get responses. Also, there is detailed API documentation to help leverage each independent feature of the platform.
|
||||
|
||||
As for analytics, Recast has a monitoring dashboard which helps you understand the accuracy of the bot and train it further.
|
||||
|
||||
![Avatar][18]
|
||||
|
||||
[Athira Lekshmi C.V][19]
|
||||
|
||||
The author is an open-source enthusiast.
|
||||
|
||||
[![][20]][21]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/11/creating-a-chat-bot-with-recast-ai/
|
||||
|
||||
作者:[Athira Lekshmi C.V][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/athira-lekshmi/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/04/Build-ChatBoat.jpg?resize=696%2C442&ssl=1 (Build ChatBoat)
|
||||
[2]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/04/Build-ChatBoat.jpg?fit=900%2C572&ssl=1
|
||||
[3]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-1-Setting-the-bot-properties.jpg?resize=350%2C201&ssl=1
|
||||
[4]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-2-Setting-the-bot-properties.jpg?resize=350%2C217&ssl=1
|
||||
[5]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-3-Searching-an-intent.jpg?resize=350%2C271&ssl=1
|
||||
[6]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-4-@joke-intent.jpg?resize=350%2C214&ssl=1
|
||||
[7]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-5-Predefined-expressions-350x227.jpg?resize=350%2C227&ssl=1
|
||||
[8]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-6-Suggested-expressions-350x197.jpg?resize=350%2C197&ssl=1
|
||||
[9]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-7-Suggested-expressions-350x248.jpg?resize=350%2C248&ssl=1
|
||||
[10]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-8-Skills-dashboard.jpg?resize=350%2C187&ssl=1
|
||||
[11]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-9-Adding-a-trigger.jpg?resize=350%2C197&ssl=1
|
||||
[12]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-10-Adding-actions.jpg?resize=350%2C175&ssl=1
|
||||
[13]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-11-Adding-text-messages.jpg?resize=350%2C255&ssl=1
|
||||
[14]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-12-Setting-up-webchat.jpg?resize=350%2C326&ssl=1
|
||||
[15]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-13-Webchat-deployed.jpg?resize=350%2C425&ssl=1
|
||||
[16]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-14-Bot-deployed-in-Telegram.jpg?resize=350%2C269&ssl=1
|
||||
[17]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-15-Multi-language-bot.jpg?resize=350%2C419&ssl=1
|
||||
[18]: https://secure.gravatar.com/avatar/d24503a2a0bb8bd9eefe502587d67323?s=100&r=g
|
||||
[19]: https://opensourceforu.com/author/athira-lekshmi/
|
||||
[20]: https://opensourceforu.com/wp-content/uploads/2019/11/assoc.png
|
||||
[21]: https://feedburner.google.com/fb/a/mailverify?uri=LinuxForYou&loc=en_US
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,119 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Day 2: Rails associations & dragging divs around)
|
||||
[#]: via: (https://jvns.ca/blog/2020/11/10/day-2--rails-associations---dragging-divs-around/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
Day 2: Rails associations & dragging divs around
|
||||
======
|
||||
null
|
||||
Hello! Today was day 2 of building my toy project. Here are a few more notes on things that have been fun about Rails!
|
||||
|
||||
### the goal: make a refrigerator poetry forum
|
||||
|
||||
I wanted to make kind of a boring standard website to learn Rails, and that other people could interact with. Like a forum! But of course if people can actually type on a website that creates all kinds of problems (what if they’re spammers? or just mean?).
|
||||
|
||||
The first idea I came up with that would let people interact with the website but not actually be able to type things into it was a refrigerator poetry forum where you can write poems given only a fixed set of words.
|
||||
|
||||
So, that’s the plan!
|
||||
|
||||
My goal with this project is to find out if I want to use Rails for other small web projects (instead of what I usually do, which is use something more basic like Flask, or give up on having a backend at all and write everything in Javascript).
|
||||
|
||||
### how do you drag the words around? jQuery UI draggable!
|
||||
|
||||
I wanted people to be able to drag the words around, but I didn’t feel like writing a lot of Javascript. It turns out that this is SUPER easy – there’s a jQuery library to do it called “draggable”!
|
||||
|
||||
At first the dragging didn’t work on mobile, but there’s a hack to make jQuery UI work on mobile called [jQuery UI touch punch][1]. Here’s what it looks like (you can view source if you’re interested in seeing how it works, there’s very little code).
|
||||
|
||||
banana forest cake is
|
||||
|
||||
### a fun Rails feature: “associations”
|
||||
|
||||
I’ve never used a relational ORM before, and one thing I was excited about with Rails was to see what using Active Record is like! Today I learned about one of Rails’ ORM features: [associations][2]. Here’s what that’s about if you know absolutely nothing about ORMs like me.
|
||||
|
||||
In my forum, I have:
|
||||
|
||||
* users
|
||||
* topics (I was going to call this “threads” but apparently that’s a reserved word in Rails so they’re called “topics” for now)
|
||||
* posts
|
||||
|
||||
|
||||
|
||||
When displaying a post, I need to show the username of the user who created the post. So I thought I might need to write some code to load the posts and load the user for each post like this: (in Rails, `Post.where` and `User.find` will run SQL statements and turn the results into Ruby objects)
|
||||
|
||||
```
|
||||
@posts = Post.where(topic_id: id)
|
||||
@posts.each do |post|
|
||||
user = User.find(post.user_id)
|
||||
post.user = user
|
||||
end
|
||||
```
|
||||
|
||||
This is no good though – it’s doing a separate SQL query for every post! I knew there was a better way, and I found out that it’s called [Associations][2]. That link is to the guide from <https://guides.rubyonrails.org>, which has treated me well so far.
|
||||
|
||||
Basically all I needed to do was:
|
||||
|
||||
1. Add a `has_many :posts` line to the User model
|
||||
2. Add a `belongs_to :user` line to the Post model
|
||||
3. Rails now knows how to join these two tables even though I didn’t tell it what columns to join on! I think this is because I named the `user_id` column in the `posts` table according to the convention it expects.
|
||||
4. Do the exact same thing for `User` and `Topic` (a topic also `has_many :posts`)
|
||||
|
||||
|
||||
|
||||
And then my code to load every post along with its associated user becomes just one line! Here’s the line:
|
||||
|
||||
```
|
||||
@posts = @topic.posts.order(created_at: :asc).preload(:user)
|
||||
```
|
||||
|
||||
More importantly than it being just one line, instead of doing a separate query to get the user for each post, it gets all the users in 1 query. Apparently there are a bunch of [different ways][3] to do similar things in Rails (preload, eager load, joins, and includes?). I don’t know what all those are yet but maybe I’ll learn that later.
|
||||
|
||||
### a fun Rails feature: scaffolding!
|
||||
|
||||
Rails has this command line tool called `rails` and it does a lot of code generation. For example, I wanted to add a Topic model / controller. Instead of having to go figure out where to add all the code, I could just run:
|
||||
|
||||
```
|
||||
rails generate scaffold Topic title:text
|
||||
```
|
||||
|
||||
and it generated a bunch of code, so that I already had basic endpoints to create / edit / delete Topics. For example, here’s my [topic controller right now][4], most of which I did not write (I only wrote the highlighted 3 lines). I’ll probably delete a lot of it, but it feels kinda nice to have a starting point where I can expand on the parts I want and delete the parts I don’t want.
|
||||
|
||||
### database migrations!
|
||||
|
||||
The `rails` tool can also generate database migrations! For example, I decided I wanted to remove the `title` field from posts.
|
||||
|
||||
Here’s what I had to do:
|
||||
|
||||
```
|
||||
rails generate migration RemoveTitleFromPosts title:string
|
||||
rails db:migrate
|
||||
```
|
||||
|
||||
That’s it – just run a couple of command line incantations! I ran a few of these migrations as I changed my mind about what I wanted my database schema to be and it’s been pretty straightforward so far – it feels pretty magical.
|
||||
|
||||
It got a tiny bit more interesting when I tried to add a `not null` constraint to a column where some of the fields in that column were null – the migration failed. But I could just fix the offending records and easily rerun the migration.
|
||||
|
||||
### that’s all for today!
|
||||
|
||||
tomorrow maybe I’ll put it on the internet if I make more progress.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2020/11/10/day-2--rails-associations---dragging-divs-around/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/furf/jquery-ui-touch-punch
|
||||
[2]: https://guides.rubyonrails.org/association_basics.html
|
||||
[3]: https://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html
|
||||
[4]: https://github.com/jvns/refrigerator-forum/blob/776b3227cfd7004cb1efb00ec7e3f82a511cbdc4/app/controllers/topics_controller.rb#L13-L15
|
@ -1,258 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use Serializers in the Django Python web framework)
|
||||
[#]: via: (https://opensource.com/article/20/11/django-rest-framework-serializers)
|
||||
[#]: author: (Renato Oliveira https://opensource.com/users/renato-oliveira)
|
||||
|
||||
How to use Serializers in the Django Python web framework
|
||||
======
|
||||
Serialization transforms data into a format that can be stored or
|
||||
transmitted and then reconstructs it for use. DRF has the best-known
|
||||
serializers.
|
||||
![Net catching 1s and 0s or data in the clouds][1]
|
||||
|
||||
Serialization is the process of transforming data into a format that can be stored or transmitted and then reconstructing it. It's used all the time when developing applications or storing data in databases, in memory, or converting it into files.
|
||||
|
||||
I recently helped two junior developers at [Labcodes][2] understand serializers, and I thought it would be good to share my approach with Opensource.com readers.
|
||||
|
||||
Suppose you're creating software for an e-commerce site and you have an Order that registers the purchase of a single product, by someone, at a price, on a date:
|
||||
|
||||
|
||||
```
|
||||
class Order:
|
||||
def __init__(self, product, customer, price, date):
|
||||
self.product = product
|
||||
self.customer = customer
|
||||
self.price = price
|
||||
self.date = date
|
||||
```
|
||||
|
||||
Now, imagine you want to store and retrieve order data from a key-value database. Luckily, its interface accepts and return dictionaries, so you need to convert your object into a dictionary:
|
||||
|
||||
|
||||
```
|
||||
def serialize_order(order):
|
||||
return {
|
||||
'product': order.product,
|
||||
'customer': order.customer,
|
||||
'price': order.price,
|
||||
'date': order.date
|
||||
}
|
||||
```
|
||||
|
||||
And if you want to get some data from that database, you can get the dict data and turn that into your Order object:
|
||||
|
||||
|
||||
```
|
||||
def deserialize_order(order_data):
|
||||
return Order(
|
||||
product=order_data['product'],
|
||||
customer=order_data['customer'],
|
||||
price=order_data['price'],
|
||||
date=order_data['date'],
|
||||
)
|
||||
```
|
||||
|
||||
This is pretty straightforward to do with simple data, but when you need to deal with complex objects made of complex attributes, this approach doesn't scale well. You also need to handle the validation of different types of fields, and that's a lot of work to do manually.
|
||||
|
||||
That's where frameworks' serializers are handy. They allow you to create serializers with little boilerplates that will work for your complex cases.
|
||||
|
||||
[Django][3] comes with a serialization module that allows you to "translate" Models into other formats:
|
||||
|
||||
|
||||
```
|
||||
from django.core import serializers
|
||||
|
||||
serializers.serialize('json', Order.objects.all())
|
||||
```
|
||||
|
||||
It covers the most-used cases for web applications, such as JSON, YAML, and XML. But you can also use third-party serializers or create your own. You just need to register it in your settings.py file:
|
||||
|
||||
|
||||
```
|
||||
# settings.py
|
||||
SERIALIZATION_MODULES = {
|
||||
'my_format': appname.serializers.MyFormatSerializer,
|
||||
}
|
||||
```
|
||||
|
||||
To create your own `MyFormatSerializer`, you need to implement the `.serialize()` method and accept a queryset and extra options as params:
|
||||
|
||||
|
||||
```
|
||||
class MyFormatSerializer:
|
||||
def serialize(self, queryset, **options):
|
||||
# serious serialization happening
|
||||
```
|
||||
|
||||
Now you can serialize your queryset to your new format:
|
||||
|
||||
|
||||
```
|
||||
from django.core import serializers
|
||||
|
||||
serializers.serialize('my_format', Order.objects.all())
|
||||
```
|
||||
|
||||
You can use the options parameters to define the behavior of your serializer. For example, if you want to define that you're going to work with nested serialization when dealing with `ForeignKeys` or you just want that data to return its primary keys, you can pass a `flat=True` param as an option and deal with that within your method:
|
||||
|
||||
|
||||
```
|
||||
class MyFormatSerializer:
|
||||
def serializer(self, queryset, **options):
|
||||
if options.get('flat', False):
|
||||
# don't recursively serialize relationships
|
||||
# recursively serialize relationships
|
||||
```
|
||||
|
||||
One way to use Django serialization is with the `loaddata` and `dumpdata` management commands.
|
||||
|
||||
### DRF serializers
|
||||
|
||||
In the Django community, the [Django REST framework][4] (DRF) offers the best-known serializers. Although you can use Django's serializers to build the JSON you'll respond to in your API, the one from the REST framework comes with nice features that help you deal with and easily validate complex data.
|
||||
|
||||
In the Order example, you could create a serializer like this:
|
||||
|
||||
|
||||
```
|
||||
from restframework import serializers
|
||||
|
||||
class OrderSerializer(serializers.Serializer):
|
||||
product = serializers.CharField(max_length=255)
|
||||
customer = serializers.CharField(max_lenght=255)
|
||||
price = serializers.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = serializers.DateField()
|
||||
```
|
||||
|
||||
And easily serialize its data:
|
||||
|
||||
|
||||
```
|
||||
order = Order('pen', 'renato', 10.50, date.today())
|
||||
serializer = OrderSerializer(order)
|
||||
|
||||
serializer.data
|
||||
# {'product': 'pen', 'customer': 'renato', 'price': '10.50', 'date': '2020-08-16'}
|
||||
```
|
||||
|
||||
To be able to return an instance from data, you need to implement two methods—create and update:
|
||||
|
||||
|
||||
```
|
||||
from rest_framework import serializers
|
||||
|
||||
class OrderSerializer(serializers.Serializer):
|
||||
product = serializers.CharField(max_length=255)
|
||||
customer = serializers.CharField(max_length=255)
|
||||
price = serializers.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = serializers.DateField()
|
||||
|
||||
def create(self, validated_data):
|
||||
# perform order creation
|
||||
return order
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
# perform instance update
|
||||
return instance
|
||||
```
|
||||
|
||||
After that, you can create or update instances by calling `is_valid()` to validate the data and `save()` to create or update an instance:
|
||||
|
||||
|
||||
```
|
||||
serializer = OrderSerializer(**data)
|
||||
## to validate data, mandatory before calling save
|
||||
serializer.is_valid()
|
||||
serializer.save()
|
||||
```
|
||||
|
||||
### Model serializers
|
||||
|
||||
When serializing data, you often need to do it from a database, therefore, from your models. A ModelSerializer, like a ModelForm, provides an API to create serializers from your models. Suppose you have an Order model:
|
||||
|
||||
|
||||
```
|
||||
from django.db import models
|
||||
|
||||
class Order(models.Model):
|
||||
product = models.CharField(max_length=255)
|
||||
customer = models.CharField(max_length=255)
|
||||
price = models.DecimalField(max_digits=5, decimal_places=2)
|
||||
date = models.DateField()
|
||||
```
|
||||
|
||||
You can create a serializer for it like this:
|
||||
|
||||
|
||||
```
|
||||
from rest_framework import serializers
|
||||
|
||||
class OrderSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = '__all__'
|
||||
```
|
||||
|
||||
Django automatically includes all model fields in the serializer and creates the `create` and `update` methods.
|
||||
|
||||
### Using serializers in class-based views (CBVs)
|
||||
|
||||
Like Forms with Django's CBVs, serializers integrate well with DRFs. You can set the `serializer_class` attribute so that the serializer will be available to the view:
|
||||
|
||||
|
||||
```
|
||||
from rest_framework import generics
|
||||
|
||||
class OrderListCreateAPIView(generics.ListCreateAPIView):
|
||||
queryset = Order.objects.all()
|
||||
serializer_class = OrderSerializer
|
||||
```
|
||||
|
||||
You can also define the `get_serializer_class()` method:
|
||||
|
||||
|
||||
```
|
||||
from rest_framework import generics
|
||||
|
||||
class OrderListCreateAPIView(generics.ListCreateAPIView):
|
||||
queryset = Order.objects.all()
|
||||
|
||||
def get_serializer_class(self):
|
||||
if is_free_order():
|
||||
return FreeOrderSerializer
|
||||
return OrderSerializer
|
||||
```
|
||||
|
||||
There are other methods in CBVs that interact with serializers. For example, [get_serializer()][5] returns an already-instantiated serializer, while [get_serializer_context()][6] returns the arguments you'll pass to the serializer when creating its instance. For views that create or update data, there are `create` and `update` that validate the data with the `is_valid` method to be saved, and [perform_create][7] and [perform_update][8] that call the serializer's save method.
|
||||
|
||||
### Learn more
|
||||
|
||||
For other resources, see my friend André Ericson's [Classy Django REST Framework][9] website. It is a [Classy Class-Based Views][10] REST Framework version that gives you an in-depth inspection of the classes that compose DRF. Of course, the official [documentation][11] is an awesome resource.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/11/django-rest-framework-serializers
|
||||
|
||||
作者:[Renato Oliveira][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/renato-oliveira
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_analytics_cloud.png?itok=eE4uIoaB (Net catching 1s and 0s or data in the clouds)
|
||||
[2]: http://www.labcodes.com.br
|
||||
[3]: https://www.djangoproject.com/
|
||||
[4]: https://www.django-rest-framework.org/
|
||||
[5]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#get_serializer
|
||||
[6]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#get_serializer_context
|
||||
[7]: http://www.cdrf.co/3.9/rest_framework.generics/CreateAPIView.html#perform_create
|
||||
[8]: http://www.cdrf.co/3.9/rest_framework.generics/RetrieveUpdateAPIView.html#perform_update
|
||||
[9]: http://www.cdrf.co/
|
||||
[10]: https://ccbv.co.uk/
|
||||
[11]: https://www.django-rest-framework.org/api-guide/serializers/#serializers
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (Mjseven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,102 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Keep track of multiple Git remote repositories)
|
||||
[#]: via: (https://opensource.com/article/20/11/multiple-git-repositories)
|
||||
[#]: author: (Peter Portante https://opensource.com/users/portante)
|
||||
|
||||
Keep track of multiple Git remote repositories
|
||||
======
|
||||
Having consistent naming standards is key to keeping local and upstream
|
||||
Git repos straight.
|
||||
![Digital hand surrounding by objects, bike, light bulb, graphs][1]
|
||||
|
||||
Working with remote repositories gets confusing when the names of the remote repositories in your local Git repo are inconsistent.
|
||||
|
||||
One approach to solving this issue is to standardize the use and meaning of two words: `origin`, referring to your personal `example.com/<USER>/*` repos, and `upstream`, referring to the `example.com` repo from which you forked the `origin` repo. In other words, `upstream` refers to the upstream repo where work is publicly submitted, while `origin` refers to your local fork of the upstream repo from which you generate pull requests (PRs), for example.
|
||||
|
||||
Using the [pbench][2] repo as an example, here is a step-by-step approach to set up a new local clone with `origin` and `upstream` defined consistently.
|
||||
|
||||
1. On most Git hosting services, you must fork a project when you want to work on it. When you run your own Git server, that's not necessary, but for a codebase that's open to the public, it's an easy way to transfer diffs among contributors.
|
||||
|
||||
Create a fork of a Git repository. For this example, assume your fork is located at `example.com/<USER>/pbench`.
|
||||
|
||||
2. Next, you must obtain a Uniform Resource Identifier ([URI][3]) for cloning over SSH. On most Git hosting services, such as GitLab or GitHub, it's in a button or panel labeled **Clone** or **Clone over SSH**. Copy the clone URI to your clipboard.
|
||||
|
||||
3. On your development system, clone the repo using the text you copied:
|
||||
|
||||
|
||||
```
|
||||
`$ git clone git@example.com:<USER>/pbench.git`
|
||||
```
|
||||
|
||||
This clones the Git repository with the default name `origin` for your forked copy of the pbench repo.
|
||||
|
||||
4. Change directory to the repo you just cloned:
|
||||
|
||||
|
||||
```
|
||||
`$ cd ~/pbench`
|
||||
```
|
||||
|
||||
5. Next, obtain the SSH URI of the source repo (the one you originally forked). This is probably done the same way as above: Find the **Clone** button or panel and copy the clone address. In software development, this is typically referred to as "upstream" because (in theory) this is where most commits happen, and you intend to let those commits flow downstream into your copy of the repository.
|
||||
|
||||
6. Add the URI to your local copy of the repository. Yes, there will be _two different_ remotes assigned to your local copy of the repository:
|
||||
|
||||
|
||||
```
|
||||
`$ git remote add upstream \ git@example.com:bigproject/pbench.git`
|
||||
```
|
||||
|
||||
7. You now have two named remote repos: `origin` and `upstream`. You can see your remote repos with the remote subcommand:
|
||||
|
||||
|
||||
```
|
||||
`$ git remote -v`
|
||||
```
|
||||
|
||||
Right now, your local `master` branch is tracking the `origin` master, which is not necessarily what you want. You probably want to track the `upstream` version of this branch because upstream is where most development takes place. The idea is that you are adding your changes on top of whatever you get from upstream.
|
||||
|
||||
8. Change your local master branch to track `upstream/master`:
|
||||
|
||||
|
||||
```
|
||||
$ git fetch upstream
|
||||
$ git branch --set-upstream-to=upstream/master master
|
||||
```
|
||||
|
||||
You can do this for any branch you want, not just `master`. For instance, some projects use a `dev` branch for all unstable changes, reserving `master` for code approved for release.
|
||||
|
||||
9. Once you've set your tracking branches, be sure to `rebase` your master to bring it up to date to any new changes made to the upstream repo:
|
||||
|
||||
|
||||
```
|
||||
$ git remote update
|
||||
$ git checkout master
|
||||
$ git rebase
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
This is a great way to keep your Git repositories synchronized between forks. If you want to automate this, read Seth Kenlon's article on [cohosting Git repositories with Ansible][4] to learn how.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/11/multiple-git-repositories
|
||||
|
||||
作者:[Peter Portante][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/portante
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003588_01_rd3os.combacktoschoolseriesk12_rh_021x_0.png?itok=fvorN0e- (Digital hand surrounding by objects, bike, light bulb, graphs)
|
||||
[2]: https://github.com/distributed-system-analysis/pbench
|
||||
[3]: https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
|
||||
[4]: https://opensource.com/article/19/11/how-host-github-gitlab-ansible
|
@ -1,80 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to Go Full Dark Mode With LibreOffice)
|
||||
[#]: via: (https://itsfoss.com/libreoffice-dark-mode/)
|
||||
[#]: author: (Dimitrios Savvopoulos https://itsfoss.com/author/dimitrios/)
|
||||
|
||||
How to Go Full Dark Mode With LibreOffice
|
||||
======
|
||||
|
||||
[LibreOffice][1] is a free and open-source cross-platform office productivity software. If you’re not making the most of it, the [LibreOffice Tips][2] article is a must-read.
|
||||
|
||||
Dark theme is getting popular even among non-programmers. It is less stressing on the eyes specially for extended use of the screen. Some people believe that it makes the texts looks crisp and clear and that helps improve their productivity.
|
||||
|
||||
Some Linux distributions like [Ubuntu come with dark mode][3] these days giving your systems a darker tint. When you turn on the dark mode, some applications will automatically switch to dark mode.
|
||||
|
||||
LibreOffice also does that except the main area where you write:
|
||||
|
||||
![LibreOffice semi dark mode matching with the system theme][4]
|
||||
|
||||
You can change that. If you want to go complete dark mode with LibreOffice, you just have to change a few settings. Let me show you how to do that.
|
||||
|
||||
### How to enable complete dark mode in LibreOffice
|
||||
|
||||
As I mentioned earlier, you need to enable a system-wide dark mode first. This will ensure that the window color (or the title bar) blends well with the in-app dark color.
|
||||
|
||||
Next, open _**any**_ LibreOffice tool from the suite such as **Writer**. Then from the menu, click **Tools -> Options** **->** **Application Colors** and select **Document background & Application** background as **Black** or **Automatic** (whichever works for you).
|
||||
|
||||
![][5]
|
||||
|
||||
In case the icons are not in dark colour, you can change them from menu (as shown in the image below), **Tools -> Options** **->** **View** and my personal choice on MX Linux, is the [Yaru][6] icon style from Ubuntu (if you have a dark version of the icon pack, select that).
|
||||
|
||||
![][7]
|
||||
|
||||
Of course, you can also try some other [icon themes][8] available for Linux distros.
|
||||
|
||||
The end result should look like this:
|
||||
|
||||
![][9]
|
||||
|
||||
#### Additional tip for LibreOffice flatpak package
|
||||
|
||||
If you’re using the [Flatpak package][10] of LibreOffice suite, the header area (or the menu area) of LibreOffice may look white. In that case, you can try navigating to **Tools-> Options-> Personalization** and then select the “**Grey theme**” as shown in the screenshot below.
|
||||
|
||||
![][11]
|
||||
|
||||
It isn’t completely black but it should make things look better. Hope that helps you switch to a dark theme LibreOffice experience!
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Dark themes have slowly started to dominate our desktops, giving a modern taste and reducing the eye strain, especially in low light conditions.
|
||||
|
||||
LibreOffice gives you the freedom to switch your working environment to a fully dark theme or to keep light themed elements. In fact, you get a decent amount of customization options to tweak what you prefer. Have you switched to a dark theme on LibreOffice? Which color combination is your preferred? Let us know in the comments below!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/libreoffice-dark-mode/
|
||||
|
||||
作者:[Dimitrios Savvopoulos][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/dimitrios/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.libreoffice.org
|
||||
[2]: https://itsfoss.com/libreoffice-tips/
|
||||
[3]: https://itsfoss.com/dark-mode-ubuntu/
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/libreOffice-dark-mode.png?resize=799%2C450&ssl=1
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/1-libreoffice-application-colours.png?resize=800%2C551&ssl=1
|
||||
[6]: https://extensions.libreoffice.org/en/extensions/show/yaru-icon-theme
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/2-libreoffice-iconstyle-1.png?resize=800%2C531&ssl=1
|
||||
[8]: https://itsfoss.com/best-icon-themes-ubuntu-16-04/
|
||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/3-libreoffice-dark.png?resize=800%2C612&ssl=1
|
||||
[10]: https://itsfoss.com/what-is-flatpak/
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/libre-office-personalization.png?resize=800%2C636&ssl=1
|
@ -0,0 +1,200 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zhangxiangping)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (An attempt at implementing char-rnn with PyTorch)
|
||||
[#]: via: (https://jvns.ca/blog/2020/11/30/implement-char-rnn-in-pytorch/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
An attempt at implementing char-rnn with PyTorch
|
||||
======
|
||||
|
||||
Hello! I spent a bunch of time in the last couple of weeks implementing a version of [char-rnn][1] with PyTorch. I’d never trained a neural network before so this seemed like a fun way to start.
|
||||
|
||||
The idea here (from [The Unreasonable Effectiveness of Recurrent Neural Networks][1]) is that you can train a character-based recurrent neural network on some text and get surprisingly good results.
|
||||
|
||||
I didn’t quite get the results I was hoping for, but I wanted to share some example code & results in case it’s useful to anyone else getting started with PyTorch and RNNs.
|
||||
|
||||
Here’s the Jupyter notebook with the code: [char-rnn in PyTorch.ipynb][2]. If you click “Open in Colab” at the top, you can open it in Google’s Colab service where at least right now you can get a free GPU to do training on. The whole thing is maybe 75 lines of code, which I’ll attempt to somewhat explain in this blog post.
|
||||
|
||||
### step 1: prepare the data
|
||||
|
||||
First up: we download the data! I used [Hans Christian Anderson’s fairy tales][3] from Project Gutenberg.
|
||||
|
||||
```
|
||||
!wget -O fairy-tales.txt
|
||||
```
|
||||
|
||||
Here’s the code to prepare the data. I’m using the `Vocab` class from fastai, which can turn a bunch of letters into a “vocabulary” and then use that vocabulary to turn letters into numbers.
|
||||
|
||||
Then we’re left with a big array of numbers (`training_set`) that we can use to train a model.
|
||||
|
||||
```
|
||||
from fastai.text import *
|
||||
text = unidecode.unidecode(open('fairy-tales.txt').read())
|
||||
v = Vocab.create((x for x in text), max_vocab=400, min_freq=1)
|
||||
training_set = torch.Tensor(v.numericalize([x for x in text])).type(torch.LongTensor).cuda()
|
||||
num_letters = len(v.itos)
|
||||
```
|
||||
|
||||
### step 2: define a model
|
||||
|
||||
This is a wrapper around PyTorch’s LSTM class. It does 3 main things in addition to just wrapping the LSTM class:
|
||||
|
||||
1. one hot encode the input vectors, so that they’re the right dimension
|
||||
2. add another linear transformation after the LSTM, because the LSTM outputs a vector with size `hidden_size`, and we need a vector that has size `input_size` so that we can turn it into a character
|
||||
3. Save the LSTM hidden vector (which is actually 2 vectors) as an instance variable and run `.detach()` on it after every round. (I struggle to articulate what `.detach()` does, but my understanding is that it kind of “ends” the calculation of the derivative of the model)
|
||||
|
||||
|
||||
|
||||
```
|
||||
class MyLSTM(nn.Module):
|
||||
def __init__(self, input_size, hidden_size):
|
||||
super().__init__()
|
||||
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
|
||||
self.h2o = nn.Linear(hidden_size, input_size)
|
||||
self.input_size=input_size
|
||||
self.hidden = None
|
||||
|
||||
def forward(self, input):
|
||||
input = torch.nn.functional.one_hot(input, num_classes=self.input_size).type(torch.FloatTensor).cuda().unsqueeze(0)
|
||||
if self.hidden is None:
|
||||
l_output, self.hidden = self.lstm(input)
|
||||
else:
|
||||
l_output, self.hidden = self.lstm(input, self.hidden)
|
||||
self.hidden = (self.hidden[0].detach(), self.hidden[1].detach())
|
||||
|
||||
return self.h2o(l_output)
|
||||
```
|
||||
|
||||
This code also does something kind of magical that isn’t obvious at all – if you pass it in a vector of inputs (like [1,2,3,4,5,6]), corresponding to 6 letters, my understanding is that `nn.LSTM` will internally update the hidden vector 6 times using [backpropagation through time][4].
|
||||
|
||||
### step 3: write some training code
|
||||
|
||||
This model won’t just train itself!
|
||||
|
||||
I started out trying to use a training helper class from the `fastai` library (which is a wrapper around PyTorch). I found that kind of confusing because I didn’t understand what it was doing, so I ended up writing my own training code.
|
||||
|
||||
Here’s some code to show basically what 1 round of training looks like (the `epoch()` method). Basically what this is doing is repeatedly:
|
||||
|
||||
1. Give the RNN a string like `and they ought not to teas` (as a vector of numbers, of course)
|
||||
2. Get the prediction for the next letter
|
||||
3. Compute the loss between what the RNN predicted, and the real next letter (`e`, because tease ends in `e`)
|
||||
4. Calculate the gradient (`loss.backward()`)
|
||||
5. Change the weights in the model in the direction of the gradient (`self.optimizer.step()`)
|
||||
|
||||
|
||||
|
||||
```
|
||||
class Trainer():
|
||||
def __init__(self):
|
||||
self.rnn = MyLSTM(input_size, hidden_size).cuda()
|
||||
self.optimizer = torch.optim.Adam(self.rnn.parameters(), amsgrad=True, lr=lr)
|
||||
def epoch(self):
|
||||
i = 0
|
||||
while i < len(training_set) - 40:
|
||||
seq_len = random.randint(10, 40)
|
||||
input, target = training_set[i:i+seq_len],training_set[i+1:i+1+seq_len]
|
||||
i += seq_len
|
||||
# forward pass
|
||||
output = self.rnn(input)
|
||||
loss = F.cross_entropy(output.squeeze()[-1:], target[-1:])
|
||||
# compute gradients and take optimizer step
|
||||
self.optimizer.zero_grad()
|
||||
loss.backward()
|
||||
self.optimizer.step()
|
||||
```
|
||||
|
||||
### let `nn.LSTM` do backpropagation through time, don’t do it myself
|
||||
|
||||
Originally I wrote my own code to pass in 1 letter at a time to the LSTM and then periodically compute the derivative, kind of like this:
|
||||
|
||||
```
|
||||
for i in range(20):
|
||||
input, target = next(iter)
|
||||
output, hidden = self.lstm(input, hidden)
|
||||
loss = F.cross_entropy(output, target)
|
||||
hidden = hidden.detach()
|
||||
self.optimizer.zero_grad()
|
||||
loss.backward()
|
||||
self.optimizer.step()
|
||||
```
|
||||
|
||||
This passes in 20 letters (one at a time), and then takes a training step at the end. This is called [backpropagation through time][4] and Karpathy mentions using this method in his blog post.
|
||||
|
||||
This kind of worked, but my loss would go down for a while and then kind of spike later in training. I still don’t understand why this happened, but when I switched to instead just passing in 20 characters at a time to the LSTM (as the `seq_len` dimension) and letting it do the backpropagation itself, things got a lot better.
|
||||
|
||||
### step 4: train the model!
|
||||
|
||||
I reran this training code over the same data maybe 300 times, until I got bored and it started outputting text that looked vaguely like English. This took about an hour or so.
|
||||
|
||||
In this case I didn’t really care too much about overfitting, but if you were doing this for a Real Reason it would be good to run it on a validation set.
|
||||
|
||||
### step 5: generate some output!
|
||||
|
||||
The last thing we need to do is to generate some output from the model! I wrote some helper methods to generate text from the model (`make_preds` and `next_pred`). It’s mostly just trying to get the dimensions of things right, but here’s the main important bit:
|
||||
|
||||
```
|
||||
output = rnn(input)
|
||||
prediction_vector = F.softmax(output/temperature)
|
||||
letter = v.textify(torch.multinomial(prediction_vector, 1).flatten(), sep='').replace('_', ' ')
|
||||
```
|
||||
|
||||
Basically what’s going on here is that
|
||||
|
||||
1. the RNN outputs a vector of numbers (`output`), one for each letter/punctuation in our alphabet.
|
||||
2. The `output` vector isn’t **yet** a vector of probabilities, so `F.softmax(output/temperature)` turns it into a bunch of probabilities (aka “numbers that add up to 1”). `temperature` kind of controls how much to weight higher probabilities – in the limit if you set temperature=0.0000001, it’ll always pick the letter with the highest probability.
|
||||
3. `torch.multinomial(prediction_vector)` takes the vector of probabilities and uses those probabilites to pick an index in the vector (like 12)
|
||||
4. `v.textify` turns “12” into a letter
|
||||
|
||||
|
||||
|
||||
If we want 300 characters worth of text, we just repeat this process 300 times.
|
||||
|
||||
### the results!
|
||||
|
||||
Here’s some generated output from the model where I set `temperature = 1` in the prediction function. It’s kind of like English, which is pretty impressive given that this model needed to “learn” English from scratch and is totally based on character sequences.
|
||||
|
||||
It doesn’t make any _sense_, but what did we expect really.
|
||||
|
||||
> “An who was you colotal said that have to have been a little crimantable and beamed home the beetle. “I shall be in the head of the green for the sound of the wood. The pastor. “I child hand through the emperor’s sorthes, where the mother was a great deal down the conscious, which are all the gleam of the wood they saw the last great of the emperor’s forments, the house of a large gone there was nothing of the wonded the sound of which she saw in the converse of the beetle. “I shall know happy to him. This stories herself and the sound of the young mons feathery in the green safe.”
|
||||
>
|
||||
> “That was the pastor. The some and hand on the water sound of the beauty be and home to have been consider and tree and the face. The some to the froghesses and stringing to the sea, and the yellow was too intention, he was not a warm to the pastor. The pastor which are the faten to go and the world from the bell, why really the laborer’s back of most handsome that she was a caperven and the confectioned and thoughts were seated to have great made
|
||||
|
||||
Here’s some more generated output at `temperature=0.1`, which weights its character choices closer to “just pick the highest probability character every time”. This makes the output a lot more repetitive:
|
||||
|
||||
> ole the sound of the beauty of the beetle. “She was a great emperor of the sea, and the sun was so warm to the confectioned the beetle. “I shall be so many for the beetle. “I shall be so many for the beetle. “I shall be so standen for the world, and the sun was so warm to the sea, and the sun was so warm to the sea, and the sound of the world from the bell, where the beetle was the sea, and the sound of the world from the bell, where the beetle was the sea, and the sound of the wood flowers and the sound of the wood, and the sound of the world from the bell, where the world from the wood, and the sound of the
|
||||
|
||||
It’s weirdly obsessed with beetles and confectioners, and the sun, and the sea. Seems fine!
|
||||
|
||||
### that’s all!
|
||||
|
||||
my results are nowhere near as good as Karpathy’s so far, maybe due to one of the following:
|
||||
|
||||
1. not enough training data
|
||||
2. I got bored with training after an hour and didn’t have the patience to babysit the Colab notebook for longer
|
||||
3. he used a 2-layer LSTM with more hidden parameters than me, I have 1 layer
|
||||
4. something else entirely
|
||||
|
||||
|
||||
|
||||
But I got some vaguely coherent results! Hooray!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2020/11/30/implement-char-rnn-in-pytorch/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zhangxiangping](https://github.com/zxp93)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://karpathy.github.io/2015/05/21/rnn-effectiveness/
|
||||
[2]: https://gist.github.com/jvns/b6dda36b2fdcc02b833ed5b0c7a09112
|
||||
[3]: https://www.gutenberg.org/cache/epub/27200/pg27200.txt
|
||||
[4]: https://en.wikipedia.org/wiki/Backpropagation_through_time
|
@ -0,0 +1,182 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Getting started with Stratis – up and running)
|
||||
[#]: via: (https://fedoramagazine.org/getting-started-with-stratis-up-and-running/)
|
||||
[#]: author: (Gordon Keegan https://fedoramagazine.org/author/gmkeegan/)
|
||||
|
||||
Getting started with Stratis – up and running
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
[Photo][2] by [Jeremy Lapak][3] on [Unsplash][4]
|
||||
|
||||
When adding storage to a Linux server, system administrators often use commands like _pvcreate_, _vgcreate_, _lvcreate_, and _mkfs_ to integrate the new storage into the system. [Stratis][5] is a command-line tool designed to make managing storage much simpler. It creates, modifies, and destroys pools of storage. It also allocates and deallocates filesystems from the storage pools.
|
||||
|
||||
Instead of an entirely in-kernel approach like ZFS or Btrfs, Stratis uses a hybrid approach with components in both user space and kernel land. It builds on existing block device managers like device mapper and existing filesystems like XFS. Monitoring and control is performed by a user space daemon.
|
||||
|
||||
Stratis tries to avoid some ZFS characteristics like restrictions on adding new hard drives or replacing existing drives with bigger ones. One of its main design goals is to achieve a positive command-line experience.
|
||||
|
||||
### Install Stratis
|
||||
|
||||
Begin by installing the required packages. Several Python-related dependencies will be automatically pulled in. The _stratisd_ package provides the _stratisd_ daemon which creates, manages, and monitors local storage pools. The _stratis-cli_ package provides the _stratis_ command along with several Python libraries.
|
||||
|
||||
```
|
||||
# yum install -y stratisd stratis-cli
|
||||
```
|
||||
|
||||
Next, enable the _stratisd_ service.
|
||||
|
||||
```
|
||||
# systemctl enable --now stratisd
|
||||
```
|
||||
|
||||
Note that the “enable –now” syntax shown above both permanently enables and immediately starts the service.
|
||||
|
||||
After determining what disks/block devices are present and available, the three basic steps to using Stratis are:
|
||||
|
||||
1. Create a pool of the desired disks.
|
||||
2. Create a filesystem in the pool.
|
||||
3. Mount the filesystem.
|
||||
|
||||
|
||||
|
||||
In the following example, four virtual disks are available in a virtual machine. Be sure not to use the root/system disk (/dev/vda in this example)!
|
||||
|
||||
```
|
||||
# sfdisk -s
|
||||
/dev/vda: 31457280
|
||||
/dev/vdb: 5242880
|
||||
/dev/vdc: 5242880
|
||||
/dev/vdd: 5242880
|
||||
/dev/vde: 5242880
|
||||
total: 52428800 blocks
|
||||
```
|
||||
|
||||
### Create a storage pool using Stratis
|
||||
|
||||
```
|
||||
# stratis pool create testpool /dev/vdb /dev/vdc
|
||||
# stratis pool list
|
||||
Name Total Physical Size Total Physical Used
|
||||
testpool 10 GiB 56 MiB
|
||||
```
|
||||
|
||||
After creating the pool, check the status of its block devices:
|
||||
|
||||
```
|
||||
# stratis blockdev list
|
||||
Pool Name Device Node Physical Size State Tier
|
||||
testpool /dev/vdb 5 GiB In-use Data
|
||||
testpool /dev/vdc 5 GiB In-use Data
|
||||
```
|
||||
|
||||
### Create a filesystem using Stratis
|
||||
|
||||
Next, create a filesystem. As mentioned earlier, Stratis uses the existing DM (device mapper) and XFS filesystem technologies to create thinly-provisioned filesystems. By building on these existing technologies, large filesystems can be created and it is possible to add physical storage as storage needs grow.
|
||||
|
||||
```
|
||||
# stratis fs create testpool testfs
|
||||
# stratis fs list
|
||||
Pool Name Name Used Created Device UUID
|
||||
testpool testfs 546 MiB Apr 18 2020 09:15 /stratis/testpool/testfs 095fb4891a5743d0a589217071ff71dc
|
||||
```
|
||||
|
||||
Note that “fs” in the example above can optionally be written out as “filesystem”.
|
||||
|
||||
### Mount the filesystem
|
||||
|
||||
Next, create a mount point and mount the filesystem.
|
||||
|
||||
```
|
||||
# mkdir /testdir
|
||||
# mount /stratis/testpool/testfs /testdir
|
||||
# df -h | egrep 'stratis|Filesystem'
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/stratis-1-3e8e[truncated]71dc 1.0T 7.2G 1017G 1% /testdir
|
||||
```
|
||||
|
||||
The actual space used by a filesystem is shown using the _stratis fs list_ command demonstrated previously. Notice how the _testdir_ filesystem has a virtual size of **1.0T**. If the data in a filesystem approaches its virtual size, and there is available space in the storage pool, Stratis will automatically grow the filesystem. Note that beginning with Fedora 34, the form of device path will be _/dev/stratis/<pool-name>/<filesystem-name>_.
|
||||
|
||||
### Add the filesystem to fstab
|
||||
|
||||
To configure automatic mounting of the filesystem at boot time, run following commands:
|
||||
|
||||
```
|
||||
# UUID=`lsblk -n -o uuid /stratis/testpool/testfs`
|
||||
# echo "UUID=${UUID} /testdir xfs defaults 0 0" >> /etc/fstab
|
||||
```
|
||||
|
||||
After updating fstab, verify that the entry is correct by unmounting and mounting the filesystem:
|
||||
|
||||
```
|
||||
# umount /testdir
|
||||
# mount /testdir
|
||||
# df -h | egrep 'stratis|Filesystem'
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/stratis-1-3e8e[truncated]71dc 1.0T 7.2G 1017G 1% /testdir
|
||||
```
|
||||
|
||||
### Adding cache devices with Stratis
|
||||
|
||||
Suppose _/dev/vdd_ is an available SSD (solid state disk). To configure it as a cache device and check its status, use the following commands:
|
||||
|
||||
```
|
||||
# stratis pool add-cache testpool /dev/vdd
|
||||
# stratis blockdev
|
||||
Pool Name Device Node Physical Size State Tier
|
||||
testpool /dev/vdb 5 GiB In-use Data
|
||||
testpool /dev/vdc 5 GiB In-use Data
|
||||
testpool /dev/vdd 5 GiB In-use Cache
|
||||
```
|
||||
|
||||
### Growing the storage pool
|
||||
|
||||
Suppose the _testfs_ filesystem is close to using all the storage capacity of _testpool_. You could add an additional disk/block device to the pool with commands similar to the following:
|
||||
|
||||
```
|
||||
# stratis pool add-data testpool /dev/vde
|
||||
# stratis blockdev
|
||||
Pool Name Device Node Physical Size State Tier
|
||||
testpool /dev/vdb 5 GiB In-use Data
|
||||
testpool /dev/vdc 5 GiB In-use Data
|
||||
testpool /dev/vdd 5 GiB In-use Cache
|
||||
testpool /dev/vde 5 GiB In-use Data
|
||||
```
|
||||
|
||||
After adding the device, verify that the pool shows the added capacity:
|
||||
|
||||
```
|
||||
# stratis pool
|
||||
Name Total Physical Size Total Physical Used
|
||||
testpool 15 GiB 606 MiB
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
Stratis is a tool designed to make managing storage much simpler. Creating a filesystem with enterprise functionalities like thin-provisioning, snapshots, volume management, and caching can be accomplished quickly and easily with just a few basic commands.
|
||||
|
||||
See also [Getting Started with Stratis Encryption][6].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/getting-started-with-stratis-up-and-running/
|
||||
|
||||
作者:[Gordon Keegan][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/gmkeegan/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/11/stratis-up-and-running-816x345.jpg
|
||||
[2]: https://unsplash.com/photos/CVvFVQ_-oUg
|
||||
[3]: https://unsplash.com/@jeremy_justin?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://unsplash.com/s/photos/runner?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[5]: https://stratis-storage.github.io/
|
||||
[6]: https://fedoramagazine.org/getting-started-with-stratis-encryption/
|
@ -0,0 +1,157 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Create universal blockchain smart contracts)
|
||||
[#]: via: (https://opensource.com/article/20/12/blockchain-smart-contracts)
|
||||
[#]: author: (Gage Mondok https://opensource.com/users/matt-coolidge)
|
||||
|
||||
Create universal blockchain smart contracts
|
||||
======
|
||||
Chainlink connects blockchain data with external, "real-world" data
|
||||
using decentralized oracles.
|
||||
![cubes coming together to create a larger cube][1]
|
||||
|
||||
Blockchain [smart contracts][2] have the ability to access off-chain data by integrating [decentralized oracles][3]. Before diving into how to use them, it's important to understand why smart contracts matter in the big picture and why they need oracles for data access.
|
||||
|
||||
Transactions happen every day, as they have for tens of thousands of years. They're generally governed by an agreement or contract. This may be driven by a vendor's terms of service, regulatory frameworks, or some combination of both. Parameters for these agreements are not always clear or transparent, and they are ultimately governed by a brand (whether that's a person or a company) and its willingness to act upon terms agreed upon in advance.
|
||||
|
||||
Contracts, like the rest of the world, are going digital. The rise of blockchain technology has introduced smart contracts, a more tamper-proof, transparent, and fair system for governing such agreements. Smart contracts are governed by math, not brands. They automatically enforce the parameters of a contract once they're executed, creating a more equitable structure for all parties.
|
||||
|
||||
The challenge with smart contracts is that they generally depend on their ability to bridge real-world data with blockchains (or data from one blockchain to another) so that the smart contract can recognize quality, assess reliable data, and trigger agreed-upon outcomes once terms are met. Traditionally, this has been an overly complex and difficult process, which limited broader adoption.
|
||||
|
||||
### About Chainlink
|
||||
|
||||
[Chainlink][4] is an open source abstraction layer that provides a framework to easily connect any blockchain with any external (or separate blockchain) API. You can think of Chainlink as the blockchain equivalent of the transport layer in TCP/IP, ensuring data is reliably transmitted in and out. Chainlink was designed to be the standard data layer for smart contracts, unlocking their true capability to affect the external world, and turning them into externally aware, universal smart contracts.
|
||||
|
||||
Smart contracts have the power to revolutionize how trust and automation are handled in business, but their restriction in scope to events on the blockchain has severely limited their potential. A majority of what developers want to interact with exists in the "real world," such as pricing data, shipping events, world events, etc. To create universal smart contracts, which are externally aware and thus can handle a wide, universal set of jobs with the world's data at its fingertips, the Chainlink network gives [Solidity][5] and other blockchain developers a framework of decentralized oracles to build with.
|
||||
|
||||
You can use these oracles to retrieve data for your decentralized application (dApp) in real-time on the Ethereum mainnet.
|
||||
|
||||
#### Chainlink adapters
|
||||
|
||||
[Adapters][6] are the default data manipulation functions that every Chainlink node supports by default. The nodes are the decentralized oracles in this case. They fulfill the data requests, and the Chainlink network is composed of an ever-growing number of them. Nodes are run by a multitude of independent operators. Through adapters, all developers have a standard interface for making data requests, and node operators have a standard for serving that data. These adapters include functionality such as HTTP GET, HTTP POST, Compare, Copy, etc. Adapters are a dApp's connection to the external world's data.
|
||||
|
||||
For example, here are the parameters for the [HttpGet][7] adapter:
|
||||
|
||||
* **get**: Takes a string containing the API URL to make a GET request to
|
||||
* **headers**: Takes an object containing keys as strings and values as arrays of strings
|
||||
* **queryParams**: Takes a string or array of strings for the URL's query parameters
|
||||
* **extPath**: Takes a slash-delimited string or array of strings to be appended to the job's URL
|
||||
|
||||
|
||||
|
||||
#### Chainlink requests
|
||||
|
||||
For a universal smart contract to interact with these adapters, you need another functionality, requests. All contracts that inherit from [ChainlinkClient][8] can create a Chainlink.Request struct that allows developers to form a request to a Chainlink decentralized oracle. This request should add the desired adapter parameters to the struct according to the request you want to make. Submitting this request requires some basic fields, such as the address of the node you want to use as your oracle, the jobId, and the agreed-upon fee. In addition to those default fields, you can add your desired adapter parameters to the request struct:
|
||||
|
||||
|
||||
```
|
||||
// Set the URL to perform the GET request on
|
||||
request.add("get", "[https://min-api.cryptocompare.com/data/price?fsym=ETH\&tsyms=USD][9]");
|
||||
```
|
||||
|
||||
With this struct, requests are flexible and can be formulated to fit various situations involving getting, posting, and manipulating data from any API because the requests can contain any of the adapter functions. What makes this system decentralized is that Chainlink's oracle network consists of many of these nodes, and developers are free to choose which and how many they want to request from based on their needs. This enables redundant failover and error checking via multiple sources, as high-reliability dApps often require.
|
||||
|
||||
For more information on constructing a request and the functions needed to submit it and receive a response within a ChainlinkClient contract, see Chainlink's full [HTTP GET request example][10].
|
||||
|
||||
For common requests, a node operator may already have an existing oracle job preconfigured, and in this case, the request is much simpler. Rather than building a custom request struct and adding the necessary adapters, the default request struct is all you need to create. No additional adapter parameters are needed; the set of decentralized oracles you choose will know how to respond based on the jobId provided when creating the request struct.
|
||||
|
||||
This example comes from the full [CoinGecko Consumer API][11]:
|
||||
|
||||
|
||||
```
|
||||
Chainlink.[Request][12] memory req = buildChainlinkRequest(jobId, address(this), this.fulfillEthereumPrice.selector);
|
||||
sendChainlinkRequestTo(oracle, req, fee);
|
||||
```
|
||||
|
||||
You can use a decentralized oracle data service, such as [Chainlink Market][13], to search through existing oracles and the jobs they support in order to find the jobId you require.
|
||||
|
||||
### External adapters
|
||||
|
||||
But what if you have a complex use case for your smart contract that isn't covered by the default adapter functions? What if you need to perform some advanced data manipulation? Maybe it's not raw data you want to submit to your contract but rather metadata generated by statistical analysis of multiple data points. Maybe you can manipulate the data on-chain with the default adapters but want to reduce gas costs. Perhaps you don't want your API request on-chain due to using a credentialed source, and you don't want to specify those credentials on-chain or in the oracle job spec. This is where [external adapters][14] come in.
|
||||
|
||||
![Chainlink External Adapter for IoT Devices][15]
|
||||
|
||||
(Chainlink, ©2020)
|
||||
|
||||
External adapters are the "whatever data you need; we can handle it" of Chainlink. When we say universal smart contracts, we really mean _universal_. Since external adapters are pieces of code that exist off-chain with the Chainlink oracle node, they can be written in any language of your choice and perform whatever functionality you can think up—so long as the data input and output adhere to the adapter's JSON specification. External adapters act as the interface between the Chainlink decentralized oracle network and external data, letting the node operators know how to request and receive the JSON response that is then consumed on-chain.
|
||||
|
||||
Defining this interface specification off-chain through an external adapter opens up vast possibilities: You can now store your API credentials off-chain per your personal security standards, data can be programmed in any way in the language of your choice, and all of this happens without using any Ethereum gas fees to fund an on-chain transaction. In a sense, external adapters are like another layer of a decentralized oracle, packaging up data outside the blockchain with speed and at low cost and putting it into one tidy JSON format to be verifiably committed on-chain by the Chainlink oracle node.
|
||||
|
||||
External adapters are a large part of what makes Chainlink such a versatile decentralized oracle network. Contract developers are free to implement these adapters as needed, or they can choose from [existing adapters][16] on the Chainlink Market. If you are a smart contract developer looking to create an external adapter, Chainlink merely requires you to specify the JSON interfaces for the data request and the return data; between those two interfaces is where developers are free to create and manipulate the data to fit their use case. As an oracle node operator, to support the external adapter and handle the additional requests, you must [create a bridge][17] for it in your node user interface and add the adapter's bridge name to your supported tasks.
|
||||
|
||||
![Create a new bridge in Chainlink][18]
|
||||
|
||||
(ChainLink, ©2020)
|
||||
|
||||
|
||||
```
|
||||
{
|
||||
"initiators": [
|
||||
{ "type": "runLog" }
|
||||
],
|
||||
"tasks": [
|
||||
{ "type": "randomNumber" },
|
||||
{ "type": "copy",
|
||||
"params": {"copyPath": ["details", "current"]}},
|
||||
{ "type": "multiply",
|
||||
"params": {"times": 100 }},
|
||||
{ "type": "ethuint256" },
|
||||
{ "type": "ethtx" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can access a full example of creating an external adapter on Chainlink's [building external adapters][19] page.
|
||||
|
||||
Chainlink is striving to give blockchain and smart contract developers the tools to empower universal smart contracts with real-world data, exactly how they need it. Chainlink's design, incorporating direct calls to any API through default adapters and extensible external adapters, gives developers a flexible platform to create as they see fit, with any data they might need. This opens up smart contracts to a literal world of data and the new use cases this empowers.
|
||||
|
||||
### Start building with Chainlink
|
||||
|
||||
If you're a smart contract developer looking to increase your smart contracts' utility with external data, try out this Chainlink [example walkthrough][20] to deploy a universal smart contract that interacts with off-chain data.
|
||||
|
||||
Chainlink is open source under the [MIT License][21], so if you're developing a product that could benefit from Chainlink decentralized oracles or would like to assist in developing the Chainlink Network, visit the [developer documentation][22] or join the technical discussion on [Discord][23]. You can also learn more on Chainlink's [website][4], [Twitter][24], [Reddit][25], [YouTube][26], [Telegram][27], and [GitHub][28].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/blockchain-smart-contracts
|
||||
|
||||
作者:[Gage Mondok][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/matt-coolidge
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cube_innovation_process_block_container.png?itok=vkPYmSRQ (cubes coming together to create a larger cube)
|
||||
[2]: https://blog.chain.link/what-is-a-smart-contract-and-why-it-is-a-superior-form-of-digital-agreement/
|
||||
[3]: https://blog.chain.link/what-is-the-blockchain-oracle-problem/
|
||||
[4]: https://chain.link/
|
||||
[5]: https://github.com/ethereum/solidity
|
||||
[6]: https://docs.chain.link/docs/adapters
|
||||
[7]: https://docs.chain.link/docs/adapters#httpget
|
||||
[8]: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/ChainlinkClient.sol
|
||||
[9]: https://min-api.cryptocompare.com/data/price?fsym=ETH\&tsyms=USD
|
||||
[10]: https://docs.chain.link/docs/make-a-http-get-request
|
||||
[11]: https://docs.chain.link/docs/existing-job-request
|
||||
[12]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+request
|
||||
[13]: https://market.link/
|
||||
[14]: https://docs.chain.link/docs/external-adapters
|
||||
[15]: https://opensource.com/sites/default/files/chainlink-external-adapter.png (Chainlink External Adapters enable smart contracts to easily integrate with specialized APIs)
|
||||
[16]: https://market.link/search/adapters
|
||||
[17]: https://docs.chain.link/docs/node-operators#config
|
||||
[18]: https://opensource.com/sites/default/files/uploads/chainlink_newbridge.png (Create a new bridge in Chainlink)
|
||||
[19]: https://docs.chain.link/docs/developers
|
||||
[20]: https://docs.chain.link/docs/example-walkthrough
|
||||
[21]: https://github.com/smartcontractkit/chainlink/blob/develop/LICENSE
|
||||
[22]: https://docs.chain.link/
|
||||
[23]: https://discordapp.com/invite/aSK4zew
|
||||
[24]: https://twitter.com/chainlink
|
||||
[25]: https://www.reddit.com/r/Chainlink/
|
||||
[26]: https://www.youtube.com/channel/UCnjkrlqaWEBSnKZQ71gdyFA
|
||||
[27]: https://t.me/chainlinkofficial
|
||||
[28]: https://github.com/smartcontractkit/chainlink
|
@ -0,0 +1,125 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 collaboration tips for using an open source alternative to Google Docs)
|
||||
[#]: via: (https://opensource.com/article/20/12/onlyoffice-docs)
|
||||
[#]: author: (Nadya Knyazeva https://opensource.com/users/hellonadya)
|
||||
|
||||
5 collaboration tips for using an open source alternative to Google Docs
|
||||
======
|
||||
Collaborative writing and editing is a breeze when you put these
|
||||
ONLYOFFICE features to work.
|
||||
![Filing cabinet for organization][1]
|
||||
|
||||
ONLYOFFICE Docs is a self-hosted open source alternative to Microsoft Office and Google Docs for collaborating on documents, spreadsheets, and presentations in real time.
|
||||
|
||||
The following are the five most important ways [ONLYOFFICE Docs][2] helps organize my collaborative work.
|
||||
|
||||
### 1\. Integrate with document storage
|
||||
|
||||
ONLYOFFICE Docs is highly flexible in how you can store documents. By default, you can use ONLYOFFICE Docs within an ONLYOFFICE Workspace. This provides a productivity solution for managing documents and projects. It's the clear way to use ONLYOFFICE Docs because it's included; when you install one, you get the other.
|
||||
|
||||
However, the full ONLYOFFICE suite can be integrated with ownCloud, Nextcloud, and other popular sync and share platforms. Helpful [connectors][3] are available in your sharing platform's official app store or on GitHub.
|
||||
|
||||
Finally, since ONLYOFFICE is open source, web app developers are free to integrate ONLYOFFICE Docs into their applications using the [ONLYOFFICE API][4].
|
||||
|
||||
### 2\. Manage document permissions
|
||||
|
||||
In ONLYOFFFICE Docs, you can differentiate what your teammates can do when they open shared documents. You can grant them permission to view, edit, or share files or perform specific actions—leave comments, suggest changes in review mode, fill in determined fields, etc. Differentiating document permissions can help structure and secure your collaboration.
|
||||
|
||||
![ONLYOFFICE sharing options][5]
|
||||
|
||||
(Nadya Knyazeva, [CC BY-SA 4.0][6])
|
||||
|
||||
The permissions you have available depend on your document management system. In ONLYOFFICE Workspace and ownCloud, you can share files with all the permissions listed above, plus you'll get an additional permission for spreadsheets (Custom Filter in ONLYOFFICE or Modify Filter in ownCloud). The filtering permission allows you to decide whether filters applied by one user should affect only that person or everyone. If you're integrating with Nextcloud or, for example, Seafile, you get fewer permission options.
|
||||
|
||||
If you are integrating the suite and want to add more permissions, your app must allow registering new sharing attributes (such as the ability to restrict downloading, printing, or copying document content to the clipboard), as described in [the API documentation][7].
|
||||
|
||||
### 3\. True collaboration
|
||||
|
||||
The collaborative work toolset is basically the same for all environments. You have comments to add notes, suggestions, or questions for people working on a document together. ONLYOFFICE has this, of course, but it strives to provide a few extra features whenever possible. For instance, in ONLYOFFICE Workspace, you can quickly add mentions by typing + or @ followed by a user's name to draw a specific person's attention to your comment.
|
||||
|
||||
![ONLYOFFICE comments][8]
|
||||
|
||||
(Nadya Knyazeva, [CC BY-SA 4.0][6])
|
||||
|
||||
There's also a chat feature to quickly discuss something with teammates without switching to a messaging app (be aware that the chat history clears when you close a document).
|
||||
|
||||
Track changes enables reviewing documents by suggesting changes. All the changes made in this mode are highlighted, and the owner and users with full editing access can accept or reject them or preview the document with all the changes accepted or rejected.
|
||||
|
||||
What's important about collaborative work in ONLYOFFICE Docs is that users working simultaneously on the same docs can set individual preferences (e.g., enable track changes or spell checking, display non-printing characters, zoom the doc in and out, and so on) without disturbing each other.
|
||||
|
||||
### 4\. Version control
|
||||
|
||||
Versioning is so important that entire industries have developed around the process. For developers, writing without Git-style revision control can be unsettling. For content creators, emailing revisions back and forth to one another gets messy and confusing.
|
||||
|
||||
ONLYOFFICE Docs allows viewing a document's version history in the editor. Changes and the author who made them are highlighted in different colors. This feature's availability is determined by the doc management system you use; version history is available for ONLYOFFICE Workspace, Nextcloud, and ownCloud integration.
|
||||
|
||||
![ONLYOFFICE version history in Nextcloud][9]
|
||||
|
||||
(Nadya Knyazeva, [CC BY-SA 4.0][6])
|
||||
|
||||
### 5\. Change real-time co-editing mode
|
||||
|
||||
There are two ways to co-edit a document in real-time in ONLYOFFICE Docs. They are called Fast and Strict modes, and they're available regardless of how you integrate ONLYOFFICE into your toolchain.
|
||||
|
||||
Fast mode allows you to see your co-authors' changes as they are typing. Your changes are also shown to others immediately.
|
||||
|
||||
In Strict mode, you lock the document you are working on, and no one can see what you are typing until you click Save. You can see what parts of the document are locked by co-authors, but you can not see what they are doing until they save.
|
||||
|
||||
When collaborating on a document in one of these modes, the Ctrl+Z (undo) command affects only your work, so your co-authors' actions are unaffected.
|
||||
|
||||
### Bonus: Security options
|
||||
|
||||
Depending on your environment, you'll find different options to protect collaboration on documents.
|
||||
|
||||
ONLYOFFICE Workspace offers the standard security toolset, with HTTPS, backups, two-factor authentication, secure sign-on, and an option to encrypt data at rest. One feature that, according to ONLYOFFICE, has no counterpart is called _Private Rooms_.
|
||||
|
||||
A Private Room is a folder that can be accessed only through the desktop app. Each office file created and stored there is encrypted using the AES-265 algorithm. Everything you type—every letter, every number, every symbol—is encrypted immediately, even if you're collaborating in real time.
|
||||
|
||||
![ONLYOFFICE Private Rooms][10]
|
||||
|
||||
(Nadya Knyazeva, [CC BY-SA 4.0][6])
|
||||
|
||||
ONLYOFFICE Docs also uses JSON Web Tokens (JWT) for security. The editors request an encrypted signature to check who can access the document and what they can do with it. Currently, JWT is implemented for ONLYOFFICE Workspace and for Nextcloud, ownCloud, Alfresco, Confluence, HumHub, and Nuxeo integrations, in addition to their built-in security tools.
|
||||
|
||||
In a Nextcloud integration, you can also insert watermarks to protect sensitive docs. Watermarks are enabled by an admin and cannot be removed from a document.
|
||||
|
||||
![ONLYOFFICE Watermark in Nextcloud][11]
|
||||
|
||||
(Nadya Knyazeva, [CC BY-SA 4.0][6])
|
||||
|
||||
### So many features
|
||||
|
||||
There are many more features in ONLYOFFICE that will fit into one article. If you're looking for an open source alternative to Microsoft or Google collaboration tools, ONLYOFFICE is the most powerful option I know of. Give it a try and let me know in the comments what you think of ONLYOFFICE Docs as a collaboration tool.
|
||||
|
||||
Take a look at five great open source alternatives to Google Docs.
|
||||
|
||||
Sandstorm's Jade Wang shares some of her favorite open source web apps that are self-hosted...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/onlyoffice-docs
|
||||
|
||||
作者:[Nadya Knyazeva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hellonadya
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/files_documents_organize_letter.png?itok=GTtiiabr (Filing cabinet for organization)
|
||||
[2]: https://www.onlyoffice.com/office-suite.aspx
|
||||
[3]: https://www.onlyoffice.com/all-connectors.aspx
|
||||
[4]: https://api.onlyoffice.com/editors/basic
|
||||
[5]: https://opensource.com/sites/default/files/uploads/1._sharing_window.png (ONLYOFFICE sharing options)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://api.onlyoffice.com/editors/config/document/permissions
|
||||
[8]: https://opensource.com/sites/default/files/uploads/2._comments.png (ONLYOFFICE comments)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/3._version_history_in_nextcloud.png (ONLYOFFICE version history in Nextcloud)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/4_privateroom.png (ONLYOFFICE Private Rooms)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/5._watermark.png (ONLYOFFICE Watermark in Nextcloud)
|
@ -0,0 +1,246 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Set up OpenStack on a Raspberry Pi cluster)
|
||||
[#]: via: (https://opensource.com/article/20/12/openstack-raspberry-pi)
|
||||
[#]: author: (AJ Canlas https://opensource.com/users/ajscanlas)
|
||||
|
||||
Set up OpenStack on a Raspberry Pi cluster
|
||||
======
|
||||
Since Arm processors are "first-class citizens" in OpenStack, and
|
||||
Raspberry Pis are built on Arm, why not combine them?
|
||||
![Raspberries with pi symbol overlay][1]
|
||||
|
||||
In the year since the Raspberry Pi 4 was released, I've seen many tutorials (like [this][2] and [this][3]) and [articles][4] on how well the 4GB model works with container platforms such as Kubernetes (K8s), Lightweight Kubernetes (K3s), and Docker Swarm. As I was doing research, I read that Arm processors are "first-class citizens" in OpenStack. Since Raspberry Pi is built on Arm, I decided to test this theory by installing OpenStack on a Raspberry Pi cluster.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
There are a few things I need to consider for this project:
|
||||
|
||||
1. Whether to use Ubuntu 64-bit or CentOS 64-bit for Raspberry Pi to boot headless; [Raspberry Pi OS][5] will not suffice, even as a Debian derivative, because there are no OpenStack packages for it.
|
||||
2. I need the latest version of OpenStack that will run in my distribution because I don't think the latest versions have an AArch64 image.
|
||||
3. I doubt that there is any documentation for automating a ground-up installation, so I will use a step-by-step process.
|
||||
|
||||
|
||||
|
||||
Materials used:
|
||||
|
||||
1. Four Raspberry Pi 4Bs, 4GB model (8GB recommended)
|
||||
2. Four 32GB MicroSD cards
|
||||
3. Four Raspberry Pi cases with fans and heatsinks (very important)
|
||||
4. Four Raspberry Official Power supply
|
||||
|
||||
|
||||
|
||||
### Configure the base operating system
|
||||
|
||||
I used the CentOS AArch64 image; as I suspected, there is not a CentOS 8 image available for Raspberry Pi, so I used CentOS 7 AArch64 with this [prebuilt image][6]. It didn't work when I tried installing it with `dd`, but it worked like a charm when I used balenaEtcher.
|
||||
|
||||
![balenaEtcher][7]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
After burning the images on the SD cards, I plugged the Raspberry Pis into my router to check their IP addresses so I could remotely access them using SSH. I configured their WiFi and hostnames using `nmtui` to access them without any cables attached (except for their power source, of course). The default user is `root`, and the default password is `centos`.
|
||||
|
||||
![SSH console in CentOS 7 AArch64][9]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
I updated the operating system:
|
||||
|
||||
|
||||
```
|
||||
`[root@rpi4b4-0 ~]# yum update -y`
|
||||
```
|
||||
|
||||
I repeated this process on all my Raspberry Pis then rebooted them.
|
||||
|
||||
### Install OpenStack
|
||||
|
||||
The latest OpenStack releases (Ussuri and Victoria) require CentOS 8, so I used Train, as it's the most recent version that uses CentOS 7.
|
||||
|
||||
![Confirming OpenStack Train's availability][10]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
I used the OpenStack Foundation's installation steps, but I encountered some issues with it. To make it easier for others to install OpenStack on CentOS 7, I compiled the following links and tips.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
1. Network Time Protocol (NTP)
|
||||
1. [Controller node installation][11]
|
||||
2. [Compute node installation][12]
|
||||
3. [Verify operation][13]
|
||||
2. OpenStack packages: [Run the Train version of the installation][14] (this link includes all versions)
|
||||
3. SQL database: [Controller node installation][15]
|
||||
4. Message queue: [Controller node installation][16]
|
||||
5. Memcached: [Controller node installation][17]
|
||||
6. Etcd: [Controller node installation][17]
|
||||
|
||||
|
||||
|
||||
#### OpenStack services
|
||||
|
||||
1. Identity service (Keystone)
|
||||
1. [Controller node installation][18]
|
||||
|
||||
2. [Verify operation][19]
|
||||
|
||||
![Keystone verification][20]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
2. Imaging service (Glance)
|
||||
1. [Controller node installation][21]
|
||||
|
||||
2. [Verify operation][22]
|
||||
TIP: Instead of downloading the CirrOS image mentioned in the documents, make sure to use the [AArch64 CirrOS image][23] for Raspberry Pis.
|
||||
|
||||
![Glance verification][24]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
3. Placement service (Placement)
|
||||
1. [Controller node installation][25]
|
||||
|
||||
2. [Verify operation][26]
|
||||
|
||||
![Placement verification][27]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
4. Compute service (Nova)
|
||||
1. [Controller node installation][28]
|
||||
|
||||
2. [Compute node installation][29]
|
||||
|
||||
3. [Verify operation][30]
|
||||
TIP: In the last part of the verify operation, `nova-status upgrade check` fails due to a packaging error. To fix it, edit the following file in the controller: [code]
|
||||
|
||||
[root@rpi4b4-0 ~]# vim /etc/httpd/conf.d/00-placement-api.conf
|
||||
(…)
|
||||
<Directory /usr/bin>
|
||||
<IfVersion >= 2.4>
|
||||
Require all granted
|
||||
</IfVersion>
|
||||
<IfVersion < 2.4>
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</IfVersion>
|
||||
</Directory>
|
||||
|
||||
```
|
||||
If you run `nova-status upgrade check` now, it will work.
|
||||
|
||||
![Nova verification][31]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
|
||||
|
||||
5. Networking service (Neutron)
|
||||
1. [Controller node installation][32]
|
||||
|
||||
2. [Controller for Option 2: Self-service network installation][33]
|
||||
To enable the `br_netfiler` module: [code]
|
||||
|
||||
[root@rpi4b4-0 ~]# modprobe br_netfilter
|
||||
[root@rpi4b4-0 ~]# echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf
|
||||
[root@rpi4b4-0 ~]# lsmod|grep br_netfilter
|
||||
```
|
||||
|
||||
3. [Compute node installation][34]
|
||||
|
||||
4. [Compute for Option 2: Self-service network installation][35]
|
||||
To enable the `br_netfiler` module: [code]
|
||||
|
||||
[root@rpi4b4-X ~]# modprobe br_netfilter
|
||||
[root@rpi4b4-X ~]# echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf
|
||||
[root@rpi4b4-X ~]# lsmod|grep br_netfilter
|
||||
|
||||
```
|
||||
5. [Verify operation][36]
|
||||
|
||||
6. [Verify operation for Option 2: Self-service network installation][37]
|
||||
|
||||
![Neutron verification][38]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
6. Dashboarding service (Horizon)
|
||||
1. [Controller node installation][39]
|
||||
TIP: Upon restarting the httpd service, you will get a 404 error. To resolve it, add this line to the end of the `/etc/openstack-dashboard/local_settings`: [code]`WEBROOT = '/dashboard'`[/code] Then restart httpd as usual: [code]`[root@rpi4b4-X ~]# systemctl restart httpd.service`
|
||||
```
|
||||
|
||||
2. [Verify operation][40]
|
||||
|
||||
![Horizon verification][41]
|
||||
|
||||
(Aaron John Canlas, [CC BY-SA 4.0][8])
|
||||
|
||||
|
||||
|
||||
|
||||
### How well does it work?
|
||||
|
||||
This was a fun and successful experiment. In terms of performance, it's quite slow considering that my controller only has four cores and 4GB RAM, but it's useful for managing multiple computers in one dashboard. My next step will be to try this with a [TripleO][42] deployment and a [Ceph][43] storage cluster to enable live migration. I might try using the Raspberry Pi's Ethernet if I have a larger cluster and workload in mind; for now, [Grafana][44] is working fine for internet monitoring.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/openstack-raspberry-pi
|
||||
|
||||
作者:[AJ Canlas][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ajscanlas
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life-raspberrypi_0.png?itok=Kczz87J2 (Raspberries with pi symbol overlay)
|
||||
[2]: https://opensource.com/article/20/6/kubernetes-raspberry-pi
|
||||
[3]: https://opensource.com/article/20/3/kubernetes-raspberry-pi-k3s
|
||||
[4]: https://opensource.com/article/20/8/kubernetes-raspberry-pi
|
||||
[5]: https://www.raspberrypi.org/software/
|
||||
[6]: http://mirror.centos.org/altarch/
|
||||
[7]: https://opensource.com/sites/default/files/uploads/balenaetcher.png (balenaEtcher)
|
||||
[8]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[9]: https://opensource.com/sites/default/files/uploads/ssh_console.png (SSH console in CentOS 7 AArch64)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/openstack_train.png (Confirming OpenStack Train's availability)
|
||||
[11]: https://docs.openstack.org/install-guide/environment-ntp-controller.html
|
||||
[12]: https://docs.openstack.org/install-guide/environment-ntp-other.html
|
||||
[13]: https://docs.openstack.org/install-guide/environment-ntp-verify.html
|
||||
[14]: https://docs.openstack.org/install-guide/environment-packages-rdo.html
|
||||
[15]: https://docs.openstack.org/install-guide/environment-sql-database-rdo.html#install-and-configure-components
|
||||
[16]: https://docs.openstack.org/install-guide/environment-messaging-rdo.html
|
||||
[17]: https://docs.openstack.org/install-guide/environment-memcached-rdo.html
|
||||
[18]: https://docs.openstack.org/keystone/train/install/keystone-install-rdo.html
|
||||
[19]: https://docs.openstack.org/keystone/train/install/keystone-verify-rdo.html
|
||||
[20]: https://opensource.com/sites/default/files/uploads/keystone_verification.png (Keystone verification)
|
||||
[21]: https://docs.openstack.org/glance/train/install/install-rdo.html
|
||||
[22]: https://docs.openstack.org/glance/train/install/verify.html
|
||||
[23]: http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-aarch64-disk.img
|
||||
[24]: https://opensource.com/sites/default/files/uploads/glance_verification.png (Glance verification)
|
||||
[25]: https://docs.openstack.org/placement/train/install/install-rdo.html
|
||||
[26]: https://docs.openstack.org/placement/train/install/verify.html
|
||||
[27]: https://opensource.com/sites/default/files/uploads/placement_verification.png (Placement verification)
|
||||
[28]: https://docs.openstack.org/nova/train/install/controller-install-rdo.html
|
||||
[29]: https://docs.openstack.org/nova/train/install/compute-install-rdo.html
|
||||
[30]: https://docs.openstack.org/nova/train/install/verify.html
|
||||
[31]: https://opensource.com/sites/default/files/uploads/nova_verification.png (Nova verification)
|
||||
[32]: https://docs.openstack.org/neutron/train/install/controller-install-rdo.html
|
||||
[33]: https://docs.openstack.org/neutron/train/install/controller-install-option2-rdo.html
|
||||
[34]: https://docs.openstack.org/neutron/train/install/compute-install-rdo.html
|
||||
[35]: https://docs.openstack.org/neutron/train/install/compute-install-option2-rdo.html
|
||||
[36]: https://docs.openstack.org/neutron/train/install/verify.html
|
||||
[37]: https://docs.openstack.org/neutron/train/install/verify-option2.html
|
||||
[38]: https://opensource.com/sites/default/files/uploads/neutron_verification.png (Neutron verification)
|
||||
[39]: https://docs.openstack.org/horizon/train/install/install-rdo.html
|
||||
[40]: https://docs.openstack.org/horizon/train/install/verify-rdo.html
|
||||
[41]: https://opensource.com/sites/default/files/uploads/horizon_verification.png (Horizon verification)
|
||||
[42]: https://docs.openstack.org/tripleo-docs/latest/index.html
|
||||
[43]: https://en.wikipedia.org/wiki/Ceph_(software)
|
||||
[44]: https://grafana.com/
|
372
sources/tech/20201202 Vagrant beyond the basics.md
Normal file
372
sources/tech/20201202 Vagrant beyond the basics.md
Normal file
@ -0,0 +1,372 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Vagrant beyond the basics)
|
||||
[#]: via: (https://fedoramagazine.org/vagrant-beyond-basics/)
|
||||
[#]: author: (Andy Mott https://fedoramagazine.org/author/amott/)
|
||||
|
||||
Vagrant beyond the basics
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Photo by [Kelli McClintock][2] on [Unsplash][3]
|
||||
|
||||
There are, like most things in the Unix/Linux world, many ways of doing things with Vagrant, but here are some examples of ways to grow your Vagrantfile portfolio and increase your knowledge and use.
|
||||
|
||||
If you have not yet installed vagrant you can follow the first part of this series.
|
||||
|
||||
> [Installing and running Vagrant using qemu-kvm][4]
|
||||
|
||||
### Some Vagrantfile basics
|
||||
|
||||
All Vagrantfiles start with “**Vagrant.configure(“2”) do |config|**” and finish with a corresponding “**end**”:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
...
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
The “2” represents the version of Vagrant, and is currently either 1 or 2. Unless you need to use the older version simply stick with the latest.
|
||||
|
||||
The config structure is broken down into namespaces:
|
||||
|
||||
**config.vm** – modify the configuration of the machine(s) that Vagrant manages.
|
||||
|
||||
**config.ssh** – for configuring how Vagrant will access your machine over SSH.
|
||||
|
||||
**config.winrm** – configuring how Vagrant will access your Windows guest over WinRM.
|
||||
|
||||
**config.winssh** – the WinSSH communicator is built specifically for the Windows native port of OpenSSH.
|
||||
|
||||
**config.vagrant** – modify the behavior of Vagrant itself.
|
||||
|
||||
Each line in a namespace begins with the word ‘config’:
|
||||
|
||||
**config.vm.box = “fedora/32-cloud-base”
|
||||
config.vm.network “private_network”**
|
||||
|
||||
There are many options here, and a read of the documentation pages is strongly recommended. They can be found at <https://www.vagrantup.com/docs/vagrantfile>
|
||||
|
||||
Also in this section you can configure provider-specific options. In this case the provider is libvirt, and the specific config looks like this:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 1
|
||||
libvirt.memory = 512
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
In the example above, all libvirt VMs will be created with a single CPU and 512Mb of memory unless specifically overridden.
|
||||
|
||||
The VM namespace is where you define all machines you want this Vagrantfile to build. Notice that this is still a part of the config section, and lines should therefore begin with ‘config’. All sections or parts of sections have an ‘end’ statement to close them off.
|
||||
|
||||
### Creating multiple machines at once
|
||||
|
||||
Depending on what you need to achieve, this can be a simple loop or multiple machine definitions. To create any number of machines in a series, with the same settings but perhaps different names and/or IP addresses, you can just provide a range as shown here:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
(1..5).each do |i|
|
||||
config.vm.define "server#{i}" do |server|
|
||||
server.vm.hostname = "server#{i}.example.com"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
This will create 5 servers, named server1, server2, server3 etc.
|
||||
|
||||
Of note, using Ruby style “**for i in 1..3 do**” doesn’t work despite Vagrantfile syntax actually being Ruby, so use the method from the example above.
|
||||
|
||||
If you need servers with different hostnames, different hardware etc then you’ll need to specify them individually, or at least in groups if the situation lends itself to that. Let’s say you need to create a typical web/db/load balancer infrastructure, with 2 web servers, a single database server and a load balancer for the web traffic. Ignoring the specific software setup for this, to simply create the virtual machines ready for provisioning you could use something like this:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
# Load Balancer
|
||||
config.vm.define "loadbal", primary: true do |loadbal|
|
||||
loadbal.vm.hostname = "loadbal"
|
||||
end
|
||||
|
||||
# Database
|
||||
config.vm.define "db", primary: true do |db|
|
||||
db.vm.hostname = "db"
|
||||
end
|
||||
|
||||
# Web Servers x2
|
||||
(1..2).each do |i|
|
||||
config.vm.define "web#{i}" do |web|
|
||||
web.vm.hostname = "web#{i}"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
This uses a combination of multiple machine calls and a small loop to build 4 VMs with a single ‘vagrant up’ command.
|
||||
|
||||
### Networking
|
||||
|
||||
Vagrant generally creates its own network for VM access, and you use this with ‘vagrant ssh’. If you create more than one VM then you must use the VM name to identify which one you wish to connect to – **vagrant ssh** _**vmname**_.
|
||||
|
||||
There are a number of configuration options available which allow you to interact with your VMs in various ways.
|
||||
|
||||
The vagrant-libvirt plugin creates a network for the guests to use. This is automated and will always be present even if you define your own networks. The network is named “vagrant-libvirt” and can be seen either in the Virtual Networks tab of virt-manager’s connection details or by issuing a **sudo virsh net-list** command.
|
||||
|
||||
If you use dhcp for your guests, you can find the individual IP addresses with the virsh net-dhcp-list command: **sudo virsh net-dhcp-leases vagrant-libvirt**
|
||||
|
||||
#### Port Forwarding
|
||||
|
||||
The simplest change to default networking is port forwarding. This uses a simple format like most Vagrant config: **config.vm.network “forwarded_port”, guest: 80, host: 8080**
|
||||
|
||||
This listens to port 8080 on your local machine and forwards connections to port 80 on the Vagrant machine. If you need to use a UDP port, simply add **, protocol: “udp”** to the end of that line (notice that comma which should come immediately after the second port number).
|
||||
|
||||
Obviously for more complex configurations this might not be ideal, as you need to specify every single port you want to forward. If you then add multiple machines the complexity can really become too much.
|
||||
|
||||
In addition to this, anyone on your network can access these ports if they know your IP address, so that’s something you should be aware of.
|
||||
|
||||
#### Public Network
|
||||
|
||||
This creates a network card for the Vagrant VM which connects to your host network, and will therefore be visible to all machines on that network. As Vagrant is not designed to be secure, you should be aware of any vulnerabilities and take steps to protect against them.
|
||||
|
||||
To configure a public network, add **config.vm.network “public_network”** to your Vagrantfile. This will use DHCP to obtain a network address.
|
||||
|
||||
If you wish to assign a static IP address, you can add one to the end of the network declaration: **config.vm.network “public_network”, ip: “192.168.0.1”**
|
||||
|
||||
If you’re creating multiple guests you can put the network configuration in the vm namespace, and even allocate IPs based on iteration too:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "centos/8"
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.qemu_use_session = false
|
||||
end
|
||||
|
||||
# Servers x2
|
||||
(1..2).each do |i|
|
||||
config.vm.define "server#{i}" do |server|
|
||||
server.vm.hostname = "server#{i}"
|
||||
server.vm.network "public_network", ip: "192.168.122.20#{i}"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
#### Private Network
|
||||
|
||||
This works very much like the Public Network option, only the network is only available to the host machine and the Vagrant guests. The syntax is almost identical too: **config.vm.network “private_network”, type: “dhcp”**
|
||||
|
||||
To use a static IP address, simply add it**:**
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.network "private_network", ip: "192.168.50.4"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
This will create a new network in libvirt, usually named something like “vagrant-private-dhcp” – you can see this with the command **sudo virsh net-list** while the VM is running. This network is created and destroyed along with the vagrant guests.
|
||||
|
||||
Again, the network config can be specified for all guests, or per guest as shown in the public network example above.
|
||||
|
||||
### Provisioning
|
||||
|
||||
Once you have your VMs defined, you can obviously then do whatever you want with them, but as soon as you issue a ‘vagrant destroy’ command any changes will be lost. This is where automated provisioning comes in.
|
||||
|
||||
You can use several methods to provision your machines, from simple file copies to shell scripts, Ansible, Chef and Puppet. Many of the main methods can be used, but I’ll cover the simple ones here – if you need to use something else please read the documentation as it’s all covered.
|
||||
|
||||
#### File uploads
|
||||
|
||||
To copy a file to the Vagrant guest, add a line to the Vagrantfile like this:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.provision "file", source: "~/myfile", destination: "myfile"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
You can copy directories too:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.provision "file", source: "~/path/to/host/folder", destination: "$HOME/remote/newfolder"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
The directory structure should already exist on the Vagrant host, and will be copied in its entirety, including subdirectories and files.
|
||||
|
||||
Note: If you add a trailing slash to the destination path, the source path will be placed under this so make sure you only do this if you want that outcome. For example, if the above destination was **“$HOME/remote/newfolder/”,** then the result would see “$HOME/remote/newfolder/folder” created with the contents of the source placed here.
|
||||
|
||||
#### Shell commands
|
||||
|
||||
You can include individual commands, inline scripts or external scripts to perform provisioning tasks.
|
||||
|
||||
A single command would take this form, and any valid command line command can be used here: **config.vm.provision “shell”, inline: “sudo dnf update -y”**
|
||||
|
||||
An inline script is less common, and declared at the top of the Vagrantfile then called during provisioning:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
$script = &lt;&lt;-SCRIPT
|
||||
echo I am provisioning...
|
||||
date > /etc/vagrant_provisioned_at
|
||||
SCRIPT
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.provision "shell", inline: $script
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
More common is the external shell script, which gives more flexibility and makes code more modular. Vagrant uploads the file to the guest then executes it. Simply call the script in the provisioning line:
|
||||
|
||||
**config.vm.provision “shell”, path: “script.sh”**
|
||||
|
||||
The file need not be local to the Vagrant host either:
|
||||
|
||||
**config.vm.provision “shell”, path: “<https://example.com/provisioner.sh”>**
|
||||
|
||||
#### Ansible
|
||||
|
||||
To use Ansible to provision your VMs you must have it installed on the Vagrant host; see <https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-rhel-centos-or-fedora>.
|
||||
|
||||
You specify an Ansible playbook to provision your VM in the following way:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.provision "ansible" do |ansible|
|
||||
ansible.playbook = "playbook.yml"
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
This then calls the playbook, which will run as any externally-run ansible playbook would.
|
||||
|
||||
If you’re building multiple VMs with your Vagrantfile then it’s likely you want different configurations for some of them, and in this case you should provision within the definition of each VM, as shown here:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
# Web Servers x2
|
||||
(1..2).each do |i|
|
||||
config.vm.define "web#{i}" do |web|
|
||||
web.vm.hostname = "web#{i}"
|
||||
web.vm.provision "ansible" do |ansible|
|
||||
ansible.playbook = "web.yml"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Ansible provisioners come in two formats – ansible and ansible_local. The ansible provisioner requires that Ansible is installed on the Vagrant host, and will connect remotely to your guest VMs to provision them. This means all necessary ssh authentication must be in place for it to work. The ansible_local provisioner executes playbooks directly on the guest VMs, which therefore requires Ansible be installed on each of the guests you want to provision. Vagrant will try to install Ansible on the guests in order to do this, (This can be controlled with the **install** option, but is enabled by default). On RHEL-style systems like Fedora, Ansible is installed from the EPEL repository. Simply use either ansible or ansible_local in the **config_vm_provision** command to choose the style you need.
|
||||
|
||||
### Synced Folders
|
||||
|
||||
Vagrant allows you to sync folders between your Vagrant host and your guests, allowing access to configuration files, data etc. By default, the folder containing the Vagrant file is shared and mounted under /vagrant on each guest.
|
||||
|
||||
To configure additional synced folders, use the **config.vm.synced.folder** command:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.synced_folder "src/", "/srv/website"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
The two parameters are the source folder on the Vagrant host and the mount directory on the guest. The destination folder will be created if it does not exist, recursively if necessary.
|
||||
|
||||
Options for synced folders allow you to configure them better, including the option to disable them completely. Other options allow you to specify a group owner of the folder (group), the folder owner (owner), plus mount options. There are others but these are the main ones.
|
||||
|
||||
You can disable the default share with the following command:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.synced_folder ".", "/vagrant", disabled: true
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
Other options are configured as follows:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.synced_folder "src/", "/srv/website",
|
||||
owner: "apache", group: "apache"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
#### NFS synced folders
|
||||
|
||||
When using Vagrant on a Linux host, synced folders use NFS (with the exception of the default share which uses rsync; see below) so you must have NFS installed on the Vagrant host, and the guests also need NFS support installation. To use NFS with non-Linux hosts, simply specify the folder type as ‘nfs’:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.synced_folder ".", "/vagrant", type: "nfs"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
#### RSync synced folders
|
||||
|
||||
These are the easiest to use as they usually work without any intervention on a Linux host. This is a one-way sync from host to guest performed at startup (**vagrant up**) or after a **vagrant reload** command is issued. The default share of the Vagrant project directory is done with rsync. To configure a synced folder with rsync, specify the type as ‘rsync’:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
config.vm.synced_folder ".", "/vagrant", type: "rsync"
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/vagrant-beyond-basics/
|
||||
|
||||
作者:[Andy Mott][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/amott/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/11/vagrant_beyond_basics-816x345.png
|
||||
[2]: https://unsplash.com/@kelli_mcclintock?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/s/photos/box?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/vagrant-qemukvm-fedora-devops-sysadmin/
|
95
sources/tech/20201202 Why I love Emacs.md
Normal file
95
sources/tech/20201202 Why I love Emacs.md
Normal file
@ -0,0 +1,95 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Why I love Emacs)
|
||||
[#]: via: (https://opensource.com/article/20/12/emacs)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Why I love Emacs
|
||||
======
|
||||
Emacs isn't a mere text editor; it places you in control and allows you
|
||||
to solve nearly any problem you encounter.
|
||||
![Emoji keyboard][1]
|
||||
|
||||
I'm a habitual [Emacs][2] user. I didn't choose Emacs as much as it chose me. Back when I was first learning about Unix, I stumbled upon a little-known feature in a strange application called Emacs, which was apparently hidden away on my computer. Legend had it (and was proven true) that if you typed `emacs` into a terminal, pressed **Alt**+**X**, and typed `tetris`, you could play a falling-blocks game.
|
||||
|
||||
![Tetris in Emacs][3]
|
||||
|
||||
That was my introduction to GNU Emacs. While it was frivolous, it was also an accurate indication of what Emacs is all about—the idea that users can reprogram their (virtual) worlds and do _whatever_ they want with an application. Playing Tetris in your text editor is probably not your primary goal on an everyday basis, but it goes to show that Emacs is, proudly, a programming platform. In fact, you might think of it as a kind of precursor to [Jupyter][4], combining a powerful programming language (called `elisp`, to be exact) with its own live environment. As a consequence, Emacs is flexible as a text editor, customizable, and powerful.
|
||||
|
||||
Elisp (and Common Lisp, by extension) aren't necessarily the easiest languages to start out on, if you're used to Bash or Python or similar languages. But LISP dialects are powerful, and because Emacs is a LISP interpreter, you can build applications, whether they're Emacs plugins or prototypes of something you want to develop into a stand-alone project. The wildly popular [org-mode project][5] is just one example: it's an Emacs plugin as well as a markdown syntax with mobile apps to interpret and extend its capabilities. There are many examples of similarly useful applications-within-Emacs, including an email client, a PDF viewer, web browser, a shell, and a file manager.
|
||||
|
||||
### Two interfaces
|
||||
|
||||
GNU Emacs has at least two user interfaces: a graphical user interface (GUI) and a terminal user interface (TUI). This sometimes surprises people because Emacs is often pitted against Vi, which runs in a terminal (although gVim provides a GUI for a modern Vi implementation). If you want to run GNU Emacs as a terminal application, you can launch it with the `-nw` option:
|
||||
|
||||
|
||||
```
|
||||
`$ emacs -nw`
|
||||
```
|
||||
|
||||
With a GUI, you can just launch Emacs from your application menu or a terminal.
|
||||
|
||||
You might think that a GUI renders Emacs less effective, as if "real text editors run in a terminal," but a GUI can make Emacs easier to learn because its GUI follows some typical conventions (a menu bar, adjustable widgets, mouse interaction, and so on).
|
||||
|
||||
In fact, if you run Emacs as a GUI application, you can probably get through the day without noticing you're in Emacs at all. Most of the usual conventions apply, as long as you use the GUI. For instance, you can select text with your mouse, navigate to the **Edit** menu, select **Copy**, and then place your cursor elsewhere and select **Paste**. To save a document, you can go to **File** and **Save** or **Save As**. You can press **Ctrl** and scroll up to make your screen font larger, you can use the scroll bar to navigate through your document, and so on.
|
||||
|
||||
Getting to know Emacs in its GUI form is a great way to flatten the learning curve.
|
||||
|
||||
### Emacs keyboard shortcuts
|
||||
|
||||
GNU Emacs is infamous for complex keyboard combinations. They're not only unfamiliar (**Alt**+**W** to copy? **Ctrl**+**Y** to paste?), they're also notated with arcane terminology ("Alt" is called "Meta"), and sometimes they come in pairs (**Ctrl**+**X** followed by **Ctrl**+**S** to save) and other times alone (**Ctrl**+**S** to search). Why would anyone willfully choose to use this?
|
||||
|
||||
Well, some don't. But those who do are fans of how these combinations easily flow into the rhythm of everyday typing (and often have the **Caps Lock** key serve as a **Ctrl** key). Those who prefer something different, however, have several options.
|
||||
|
||||
* The `evil` mode lets you use Vim keybindings in Emacs. It's that simple: You get to keep the key combinations you've committed to muscle memory, and you inherit the most powerful text editor available.
|
||||
* Common User Access (CUA) keys keep all of the usual Emacs key combinations but the most jarring ones—copy, cut, paste, and undo—are all mapped to their modern bindings (**Ctrl**+**C**, **Ctrl**+**X**, **Ctrl**+**V**, and **Ctrl**+**Z**, respectively).
|
||||
* The `global-set-key` function, part of the programming side of Emacs, allows you to define your own keyboard shortcuts. Traditionally, user-defined shortcuts start with **Ctrl**+**C**, but nothing is stopping you from inventing your own scheme. Emacs isn't precious of its own identity. You're welcome to bend it to your will.
|
||||
|
||||
|
||||
|
||||
### Learn Emacs
|
||||
|
||||
It takes time to get very good with Emacs. For me, that meant printing out a [cheat sheet][6] and keeping it next to my keyboard all day, every day. When I forgot a key combo, I looked it up on my cheat sheet. If it wasn't on my cheat sheet, I learned the keyboard combo, either by executing the function and noting how Emacs told me I could access it quicker or by using `describe-function`:
|
||||
|
||||
|
||||
```
|
||||
M-x describe-function: save-buffer
|
||||
|
||||
save-buffer is an interactive compiled Lisp function in ‘files.el’.
|
||||
|
||||
It is bound to C-x C-s, <menu-bar> <file> <save-buffer>.
|
||||
[...]
|
||||
```
|
||||
|
||||
As you use it, you learn it. And the more you learn about it, the more empowered you become to improve it and make it your own.
|
||||
|
||||
### Try Emacs
|
||||
|
||||
It's a common joke to say that Emacs is an operating system with a text editor included. Maybe that's meant to insinuate Emacs is bloated and overly complex, and there's certainly an argument that a text editor shouldn't require `libpoppler` according to its default configuration (you can compile Emacs without it).
|
||||
|
||||
But there's a greater truth lurking behind this joke, and it reveals a lot about what makes Emacs so fun. It doesn't make sense to compare Emacs to other text editors, like Vim, Nano, or even [VSCodium][7], because the really important part of Emacs isn't the idea that you can type stuff into a window and save it. That's basic functionality that even Bash provides. The true significance of Emacs is how it places you in control and how, through Emacs Lisp ([Elisp][8]), nearly any problem can be solved.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/emacs
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/emoji-keyboard.jpg?itok=JplrSZ9c (Emoji keyboard)
|
||||
[2]: https://en.wikipedia.org/wiki/Emacs
|
||||
[3]: https://opensource.com/sites/default/files/tetris.png (Tetris in Emacs)
|
||||
[4]: https://opensource.com/article/20/11/surprising-jupyter
|
||||
[5]: https://opensource.com/article/19/1/productivity-tool-org-mode
|
||||
[6]: https://opensource.com/downloads/emacs-cheat-sheet
|
||||
[7]: https://opensource.com/article/20/6/open-source-alternatives-vs-code
|
||||
[8]: https://www.gnu.org/software/emacs/manual/html_node/elisp/
|
@ -0,0 +1,98 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get the most out of the Vi text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/vi-text-editor)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Get the most out of the Vi text editor
|
||||
======
|
||||
Vi is the quintessential Unix text editor. Get to know it—or any of its
|
||||
incarnations, Vim, Neovim, gVim, nvi, or Elvis, for Linux, macOS,
|
||||
Windows, or BSD.
|
||||
![Business woman on laptop sitting in front of window][1]
|
||||
|
||||
Whether you know it as Vim, Neovim, gVim, nvi, or even Elvis, the quintessential Unix editor is easily Vi. Included in probably every Linux and BSD distribution, Vi is a lightweight and minimalist text editor that many users love for its simple and succinct keyboard shortcuts and dual-mode design.
|
||||
|
||||
The original Vi editor was an application written by Bill Joy, creator of the [C shell][2]. Modern incarnations of Vi have [added many features][3], including multiple levels of undo, better navigation while in insert mode, line folding, syntax highlighting, plugin support, and much more. Vim is regarded as the most popular modern implementation, and most people actually mean Vim when they refer to Vi.
|
||||
|
||||
All incarnations hearken back to the same goal, though, so this article looks at Vi in a generic sense. The implementation on your computer may differ slightly, but you can still benefit from editing text the Vi way.
|
||||
|
||||
### Install Vi
|
||||
|
||||
If you're running Linux, macOS, or BSD, then you already have the `vi` command installed. If you're on Windows, you can [download Vim and gVim][4].
|
||||
|
||||
![gVim][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
On [NetBSD][7], nvi is a common alternative to Vi, while Slackware provides [Elvis][8] (and Vim), and the popular [Neovim][9] fork aims to help users extend Vim with [Lua][10].
|
||||
|
||||
### Launch Vi
|
||||
|
||||
Start Vi or Vim with the `vi` command in a terminal. If a `.vimrc` file is not found on your system, then Vim starts in Vi-compatibility mode (this can also be forced with the `-C` option). If you want to use gVim to have a graphical user interface (GUI), you can start it from your desktop's application menu.
|
||||
|
||||
If you're a new user just learning Vi, using a graphical user interface can be a nice way to provide yourself a buffer between how you might _expect_ a text editor to behave and how Vi was designed to behave. The GUI version has a menu bar, some mouse integration, a toolbar, and other features to help you find the basic functions you probably take for granted in a typical text editor but don't know how to do in Vi yet.
|
||||
|
||||
### How to use Vi
|
||||
|
||||
Probably the easiest way to learn Vi is with `vimtutor`, an interactive tutorial packaged with Vim. To start the tutorial, launch `vimtutor` and read through the instructions, trying each exercise. As the tutorial says, getting good with Vi is less about memorizing what key does what and more about establishing muscle memory to invoke common actions as you type.
|
||||
|
||||
#### Escape
|
||||
|
||||
One of the first things you learn about Vi is the importance of the **Esc** key. **Esc** is what activates _command mode_, and it doesn't take long to learn that whenever you're in doubt in Vi, just press **Esc**. Any key you press while in command mode is not entered into the text document you're working on; instead, it is interpreted by Vi as a command. For instance, to move your cursor left, you press the **H** key on your keyboard. If you're in _insert_ mode, then pressing **H** types the letter H, just as you'd expect. But in _command_ mode, pressing **H** moves left, **L** moves right, **J** moves down, and **K** moves up.
|
||||
|
||||
The separation between command mode and insert mode is a sharp contrast to the way any other text editor works, and for that reason, it's probably Vi's most significant differentiator. Interestingly, though, it's theoretically not so different from the way you probably already work. After all, when you take your hands off the keyboard to select text with a mouse, you're essentially placing yourself into a kind of command mode. With Vi, instead of moving your hands off the keyboard to move the mouse and press function keys or Ctrl, you put the _editor_ into a special mode of operation, such that it reassigns your key presses to commands instead of text input.
|
||||
|
||||
#### Extend Vi
|
||||
|
||||
Before Vim version 8.0, Vi was very much "just" a text editor. There were plugins for it, but installing them was a manual process that many users never thought to do. Luckily, Vim version 8 and higher offer support for plugin management, making it trivial to install and load plugins.
|
||||
|
||||
Installing plugins for Vim can be done with the `vim-plug` function. For instance, to install the Vi file browser [NERDTree][11]:
|
||||
|
||||
|
||||
```
|
||||
`:PlugInstall NERDTree`
|
||||
```
|
||||
|
||||
You can also update plugins:
|
||||
|
||||
|
||||
```
|
||||
`:PlugUpdate NERDTree`
|
||||
```
|
||||
|
||||
For more information on installing plugins and themes, both with `vim-plug` and manually, read my article [_How to install Vim plugins_][12].
|
||||
|
||||
### Vi as default
|
||||
|
||||
Vi isn't just popular; it's a [POSIX][13] standard. It's an application every sysadmin should know how to use, even if they don't intend to use it on an everyday basis. It's also a fast and simple editor, so once you get good at it, it may be the editor you've long been searching for.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/vi-text-editor
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||
[2]: https://opensource.com/article/20/8/tcsh
|
||||
[3]: https://vimhelp.org/vi_diff.txt.html#vi-differences
|
||||
[4]: https://www.vim.org/download.php
|
||||
[5]: https://opensource.com/sites/default/files/uploads/gvim.jpg (gVim)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://opensource.com/article/19/3/netbsd-raspberry-pi
|
||||
[8]: https://github.com/mbert/elvis
|
||||
[9]: http://neovim.io
|
||||
[10]: https://opensource.com/article/20/2/lua-cheat-sheet
|
||||
[11]: https://www.vim.org/scripts/script.php?script_id=1658
|
||||
[12]: https://opensource.com/article/20/2/how-install-vim-plugins
|
||||
[13]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
@ -0,0 +1,88 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Support your work-life balance with this open source productivity tool)
|
||||
[#]: via: (https://opensource.com/article/20/12/super-productivity)
|
||||
[#]: author: (Johannes Millan https://opensource.com/users/johannesjo)
|
||||
|
||||
Support your work-life balance with this open source productivity tool
|
||||
======
|
||||
Super Productivity empowers its users to adopt a healthy work-life
|
||||
balance so they can get more done.
|
||||
![Ceramic mug of tea or coffee with flowers and a book in front of a window][1]
|
||||
|
||||
[Super Productivity][2] is a to-do app for people that spend a lot of their time working from a computer. Its philosophy is that disciplined, focused work and cutting yourself some slack benefit from each other, rather than being on opposite sides of the spectrum.
|
||||
|
||||
The app offers everything you would expect from a modern to-do app. It adds various little (optional) helpers to nudge you in the right direction to establish good work routines—whether you're working way too much without taking a break or leaning too hard on your dirty little procrastination habits and not getting done what you need to do.
|
||||
|
||||
In its newest iteration, the free, open source task-management app allows you to sync your data privately via WebDAV with Nextcloud or ownCloud in addition to its existing support for Google Drive and Dropbox. The task list's design has been revised from the ground up, and users can now choose custom images as backgrounds. There is also a long list of bug fixes and minor improvements in its [GitHub changelog][3].
|
||||
|
||||
![Super Productivity time tracking][4]
|
||||
|
||||
(Johannes Millan, [CC BY-SA 4.0][5])
|
||||
|
||||
### Track, plan, and organize
|
||||
|
||||
Super Productivity offers various options for managing tasks, such as tags, projects, and scheduling. It also has some optional productivity helpers like a Pomodoro timer, a standing-desk timer, and a break reminder.
|
||||
|
||||
The app asks you what to do with your time when you have been away from the computer for a while.
|
||||
|
||||
![Idle time dialog][6]
|
||||
|
||||
(Johannes Millan, [CC BY-SA 4.0][5])
|
||||
|
||||
Little helpers remind you to keep good working habits.
|
||||
|
||||
![Break reminder][7]
|
||||
|
||||
(Johannes Millan, [CC BY-SA 4.0][5])
|
||||
|
||||
### Integrate with Jira, GitHub, and GitLab
|
||||
|
||||
If you're working in the tech sector, you may appreciate the option to import tasks from Jira, GitLab, or GitHub. Once they're imported, the app notifies you about changes or comments, and if you work in Jira, it allows you to log your time spent directly there.
|
||||
|
||||
![Import and track issues from Jira, GitHub, and GitLab][8]
|
||||
|
||||
(Johannes Millan, [CC BY-SA 4.0][5])
|
||||
|
||||
### Make it your own
|
||||
|
||||
On top of being very customizable, Super Productivity prides itself on having a friendly community and being open to new ideas and contributions. If you have suggestions or feedback, the project's [GitHub page][9] is a good place to start. You can also make [feature suggestions and bug reports][10] or access the [discussion board][11] for broader conversations and questions.
|
||||
|
||||
In addition to allowing you to color-code your projects and tags, there is also a light theme.
|
||||
|
||||
![Super Productivity's light theme][12]
|
||||
|
||||
(Johannes Millan, [CC BY-SA 4.0][5])
|
||||
|
||||
Super Productivity is completely free and open source, published under the [MIT License][13]. It is available for Windows, macOS, Linux, and Android, and as a [web app][14].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/super-productivity
|
||||
|
||||
作者:[Johannes Millan][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/johannesjo
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tea-cup-mug-flowers-book-window.jpg?itok=JqThhl51 (Ceramic mug of tea or coffee with flowers and a book in front of a window)
|
||||
[2]: https://super-productivity.com/
|
||||
[3]: https://github.com/johannesjo/super-productivity/blob/master/CHANGELOG.md
|
||||
[4]: https://opensource.com/sites/default/files/uploads/track.png (Super Productivity time tracking)
|
||||
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/idle.png (Idle time dialog)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/break-reminder.png (Break reminder)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/issue-integration.png (Import and track issues from Jira, GitHub, and GitLab)
|
||||
[9]: https://github.com/johannesjo/super-productivity
|
||||
[10]: https://github.com/johannesjo/super-productivity/issues/new/choose
|
||||
[11]: https://github.com/johannesjo/super-productivity/discussions
|
||||
[12]: https://opensource.com/sites/default/files/uploads/light-theme.png (Super Productivity's light theme)
|
||||
[13]: https://github.com/johannesjo/super-productivity/blob/master/LICENSE
|
||||
[14]: https://app.super-productivity.com
|
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Watch Live TV on Linux With Hypnotix: A New IPTV Application Being Developed by Linux Mint Team)
|
||||
[#]: via: (https://itsfoss.com/hypnotix-iptv-app/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Watch Live TV on Linux With Hypnotix: A New IPTV Application Being Developed by Linux Mint Team
|
||||
======
|
||||
|
||||
The rise of streaming services like [Netflix][1] made people speculate about the dim future of TV channels. While the newer generation might not watch TV anymore, TV channels are not out of fashion, yet.
|
||||
|
||||
Many streaming services like [Hulu][2] and Hotstar include TV channels in their offering. TV channels are also utilizing live streaming to broadcast their content to viewers on the internet.
|
||||
|
||||
Another way to watch live TV is by using IPTV. There are a number of TV channels available via IPTV so that viewers can use internet to watch the live broadcast. Some channels are available for free while some might require subscription.
|
||||
|
||||
There have been a few [applications on Linux to watch IPTV channels but most have been discontinued][3]. Linux Mint team [announced][4] that they are working on a new app that will allow you to watch TV channels via IPTV on your Linux system.
|
||||
|
||||
### Hypnotix: New IPTV application under development
|
||||
|
||||
![][5]
|
||||
|
||||
[Hypnotix][6] is an IPTV streaming application with support for live TV, movies and series. It supports IPTV providers using M3U URL, Xtream API or [local M3U playlist][7].
|
||||
|
||||
If none of the above make sense to you, don’t worry. Hypnotix comes with FreeIPTV preconfigured. [FreeIPTV][8] is a project that has M3U for over 2,000 TV channels that are legally free to watch.
|
||||
|
||||
Which means that you can get a huge list of freely available TV channels from all over the world.
|
||||
|
||||
![][9]
|
||||
|
||||
You can click on the country or region of your choice. It will show you the list of channels in the left sidebar. Clicking on a channel will start playing the content in the right sidebar.
|
||||
|
||||
![][10]
|
||||
|
||||
You can also go full screen with F or F11 keyboard shortcut or use the button in the application.
|
||||
|
||||
There is also provision to handle VOD (Video on Demand) library but I couldn’t figure out a way to use it.
|
||||
|
||||
Here are a few things to keep in mind:
|
||||
|
||||
* Viewing experience depends on your internet speed and the TV channels’ servers.
|
||||
* Some TV channels might not work even if they are listed in the application.
|
||||
* You may go back a few seconds or minutes but this depends upon the cache.
|
||||
* You may also pause the live streaming and it will maintain a cache so that you can resume later. I don’t know how big the cache could be.
|
||||
* There is no way to control the video streaming quality as you do on YouTube and other video streaming websites.
|
||||
* You won’t get running program’s detail in the player.
|
||||
* This is TV broadcast so you get to see the same ads that are broadcasted during program breaks.
|
||||
|
||||
|
||||
|
||||
![Streaming is cached][11]
|
||||
|
||||
### Installing Hypnotix on Linux
|
||||
|
||||
_**Hypnotix is still in beta phase of development**_. The .deb file for the beta version is available for testing. On Ubuntu and Debian-based distributions, you can [install it from the DEB file][12].
|
||||
|
||||
[Download .DEB file for Hypnotix (Beta Version)][13]
|
||||
|
||||
At the time of writing this article, no other package is available for Hypnotix. This means Fedora and Arch users will have to wait.
|
||||
|
||||
### More features to come
|
||||
|
||||
Linux Mint development team plans to add more features in the future:
|
||||
|
||||
* EPG support (Live TV Program)
|
||||
* PVR: pausing, time-shifting, recording, etc.
|
||||
* Custom categories: To list channels in appropriate categories
|
||||
* Favorites: so that you don’t have to search for your favorite channels all the time.
|
||||
* Hiding unused content
|
||||
|
||||
|
||||
|
||||
I like Linux Mint team. Unlike many other distributions, they are not just Ubuntu or Arch repackages with different theme and wallpapers. They put effort in developing not only the distribution but also applications like Hypnotix, Warpinator etc for their users. Other distribution maintainers should learn from Mint team.
|
||||
|
||||
Hypnotix provides a way to watch the IPTV channels with a simple and easy to use interface. Personally, I don’t watch TV but I know many people do. Are you one of them? If yes, do you look forward to using it? Do share your views in the comment section.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/hypnotix-iptv-app/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.netflix.com/
|
||||
[2]: https://www.hulu.com/
|
||||
[3]: https://itsfoss.com/watch-tv-channels-on-ubuntu-or-linux-mint/
|
||||
[4]: https://blog.linuxmint.com/?p=3983
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/Hypnotix-iptv-app-linux-mint.png?resize=800%2C464&ssl=1
|
||||
[6]: https://github.com/linuxmint/hypnotix
|
||||
[7]: https://itsfoss.com/create-m3u-playlist-linux/
|
||||
[8]: https://github.com/Free-IPTV/Countries
|
||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/Hypnotix-free-tv-channel-lists.png?resize=800%2C441&ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/12/live-tv-linux.png?resize=910%2C528&ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/hypnotix-cache.jpg?resize=800%2C444&ssl=1
|
||||
[12]: https://itsfoss.com/install-deb-files-ubuntu/
|
||||
[13]: https://github.com/linuxmint/hypnotix/releases
|
@ -0,0 +1,226 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (9 Open Source Forum Software That You Can Deploy on Your Linux Servers)
|
||||
[#]: via: (https://itsfoss.com/open-source-forum-software/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
9 Open Source Forum Software That You Can Deploy on Your Linux Servers
|
||||
======
|
||||
|
||||
_**Looking to have a community forum or customer support portal? Here are some of the best open source forum software you can deploy on your servers.**_
|
||||
|
||||
Just like our [It’s FOSS Community][1] forum, it is important to always build a platform where like-minded people can discuss, interact, and seek support.
|
||||
|
||||
A forum gives users (or customers) a space to reach out for something that they cannot easily find on the Internet for the most part.
|
||||
|
||||
If you are an enterprise, you may hire a team of developers and build your own forum the way you want but that adds a lot of cost to your budget.
|
||||
|
||||
Fortunately, there are several impressive open source forum software that you can deploy on your server and you’re good to go! You will save a lot of money in the process and still get what you need.
|
||||
|
||||
Here, I have compiled a list of best open source forum software that you can install on your Linux server.
|
||||
|
||||
### Best open source forum software to build a community portal
|
||||
|
||||
![][2]
|
||||
|
||||
In case you haven’t built a website yet, you might want to take a look at [some open-source website creation tools][3] before you deploy a forum.
|
||||
|
||||
_**Note:** The list is in no particular order of ranking._
|
||||
|
||||
#### 1\. Discourse (modern and popular)
|
||||
|
||||
![][4]
|
||||
|
||||
Discourse is the most popular modern forum software that people deploy to set up their discussion platforms. In fact, our [It’s FOSS community][1] forum utilizes the Discourse platform.
|
||||
|
||||
It offers most of the essential features that I’m aware of which includes email notifications, moderation tools, style customization options, third-part integrations like Slack/WordPress, and more.
|
||||
|
||||
It is completely free to self-host and you can find the project on [GitHub][5] as well. If you do not need the hassle of deploying it on a self-managed server, you can always choose to opt for [managed services offered by Discourse][6] itself (which will be certainly expensive).
|
||||
|
||||
[Discourse][7]
|
||||
|
||||
#### 2\. Talkyard (inspired by Discourse and StackOverflow)
|
||||
|
||||
![][8]
|
||||
|
||||
Talkyard is completely free to use and an open-source project. It looks close to Discourse but there are distinctions if you inspect it.
|
||||
|
||||
You get most of the key features from StackOverflow here along with all essential features that you would expect on a forum platform. It may not be a popular forum solution but if you want something similar to Discourse along with some interesting features, this is worth trying out.
|
||||
|
||||
You can explore more about it in their [GitHub page][9].
|
||||
|
||||
[Talkyard][10]
|
||||
|
||||
#### 3\. NodeBB (Modern and full of features)
|
||||
|
||||
![][11]
|
||||
|
||||
NodeBB is an open-source forum software based on [Node.js][12]. It aims to be simple, elegant, and fast as well. Primarily, it is geared towards organizations and enterprises with managed hosting plans available. But, you can choose to host it yourself as well.
|
||||
|
||||
You get a real-time native analytics feature along with chat and notification support as well. It also offers an API, if you want to integrate it with any of your existing product. It also supports moderation tools and tools to fight spam.
|
||||
|
||||
You get some 3rd party integration support out of the box like WordPress, Mailchimp, etc.
|
||||
|
||||
Explore more about it in their [GitHub page][13] or the official website.
|
||||
|
||||
[NodeBB][14]
|
||||
|
||||
#### 4\. Vanilla Forums (enterprise focused)
|
||||
|
||||
![][15]
|
||||
|
||||
Vanilla Forums is primarily an enterprise focused forum software with essential features to brand your platform, offer a Q/A for customers, and also gives the ability to vote on posts.
|
||||
|
||||
The user experience is geared with a modern look and is being used by the likes of EA, Adobe, and some other big shot companies.
|
||||
|
||||
Of course, if you want to try the cloud-based Vanilla Forums (managed by a team of professionals) along with the access to some premium features, feel free to request a Demo. In either case, you can opt for the community edition, which is free to use with most of the latest features with the responsibility of hosting it yourself and managing it.
|
||||
|
||||
You can explore more about it on their official website and [GitHub page][16].
|
||||
|
||||
[Vanilla Forums][17]
|
||||
|
||||
**Recommended Read:**
|
||||
|
||||
![][18]
|
||||
|
||||
#### [Best Open Source eCommerce Platforms to Build Online Shopping Websites][19]
|
||||
|
||||
Want to create an online shopping website? Here are some open source ecommerce platforms you can deploy on your own Linux server.
|
||||
|
||||
#### 5\. bbPress (from WordPress)
|
||||
|
||||
![][20]
|
||||
|
||||
bbPress is a solid forum software built by the creators of WordPress. It aims to provide a simple and snappy forum experience.
|
||||
|
||||
The user interface would seem old-school but it is easy to use and offers the basic functionalities that you would normally look for in a forum software. The moderation tools are simple and easy to set up. You can extend the functionality using plugins available and choose from several themes available to tweak the look and feel of your forum.
|
||||
|
||||
If you just want a simple forum platform with no fancy features, bbPress should be perfect. You can also check out their [GitHub page][21] for more information.
|
||||
|
||||
[bbPress][22]
|
||||
|
||||
#### 6\. phpBB (classic forum software)
|
||||
|
||||
![][23]
|
||||
|
||||
If you want a traditional forum design and just want the basic functionalities, phpBB software is a good choice. Of course, you may not get the best user experience or the features, but it is functional and quite effective as a traditional-design forum plaform.
|
||||
|
||||
Especially, for users comfortable with the traditional approach, it will be a simple and effective solution.
|
||||
|
||||
Not just limited to the simplicity, but also it is way easier to set up with an average hosting provider. You get a 1-click installation feature on every shared hosting platform, so you do not need a lot of technical knowledge to set it up as well.
|
||||
|
||||
You can explore more about it in their official website or the [GitHub page][24].
|
||||
|
||||
[phpBB][25]
|
||||
|
||||
#### 7\. Simple Machines Forum (another classic)
|
||||
|
||||
![][26]
|
||||
|
||||
Similar to php BB, Simple Machines forum is yet another basic (or simple) implementation of a forum platform. You may not be able to customize the look and feel by a long extent (not easily at least) but the default look is clean and offers a good user experience.
|
||||
|
||||
Personally, I like it better than php BB, but you can head to their [official website][27] to explore more about it. Also, you can easily install Simple Machines Forum on any shared hosting service using the 1-click installation method.
|
||||
|
||||
[Simple Machines Forum][27]
|
||||
|
||||
#### 8\. FluxBB (old school)
|
||||
|
||||
![][28]
|
||||
|
||||
FluxBB is yet another simple and lightweight open source forum. When compared to some others, it may not be super actively maintained but if you just want to deploy a basic forum with a few users, you can easily give this a try.
|
||||
|
||||
You can explore more about it in their official website and the [GitHub page][29].
|
||||
|
||||
[FluxBB][30]
|
||||
|
||||
#### 9\. MyBB (less popular but worth a look)
|
||||
|
||||
![][31]
|
||||
|
||||
MyBB is a unique open-source forum software that offers a wide range of styles and includes essential features you’ll need.
|
||||
|
||||
Starting from plugin support and moderation tools, you get everything necessary needed to manage a big community. It also supports private messaging to individual users similar to Discourse and similar forum software.
|
||||
|
||||
It may not be a popular option but it checks out for most of the use-cases and it completely free. You might want to support and explore the project on [GitHub][32] as well.
|
||||
|
||||
[MyBB][33]
|
||||
|
||||
#### Bonus: Flarum (in beta)
|
||||
|
||||
![][34]
|
||||
|
||||
If you want something simpler and unique, have a look at Flarum. It is a lightweight forum software which aims to be mobile-first while offering a fast experience.
|
||||
|
||||
It supports some third-party integrations and you can extend the functionality using extensions as well. Personally, it looks beautiful to me. I haven’t got a chance to try it you can take a look at its [documentation][35] and it is safe to assume that it features all the necessary features for a forum.
|
||||
|
||||
It is worth noting that Flarum is fairly new so it is still in beta. You might want to deploy it on your test server first before taking a leap of faith on your production environment. Do check out their [GitHub page][36] for more details.
|
||||
|
||||
[Flarum][37]
|
||||
|
||||
Can’t self-host? Let us help you
|
||||
|
||||
Deploying open source applications and managing Linux servers takes some expertise and time. If you lack either but still want to have your own instance of open source software, we can help you out.
|
||||
With our new project, [High on Cloud][38], you can leave the deployment and server management part to us while you work on growing your community forum.
|
||||
|
||||
### Wrapping Up
|
||||
|
||||
Most of the open source forum software offer pretty much the same features for basic use-case. If you are looking for something specific, you might want to explore their documentations.
|
||||
|
||||
Personally, I recommend Discourse. It is popular, modern looking and has a significant user base.
|
||||
|
||||
What do you think is the best open source forum software? Did I miss any of your favorites? Let me know in the comments below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/open-source-forum-software/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.community/
|
||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/open-source-forum-software.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/open-source-cms/
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/itsfoss-community-discourse.jpg?resize=800%2C561&ssl=1
|
||||
[5]: https://github.com/discourse/discourse
|
||||
[6]: https://discourse.org/buy
|
||||
[7]: https://www.discourse.org/
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/talkyard-forum.jpg?resize=800%2C598&ssl=1
|
||||
[9]: https://github.com/debiki/talkyard
|
||||
[10]: https://www.talkyard.io/
|
||||
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/nodebb.jpg?resize=800%2C369&ssl=1
|
||||
[12]: https://nodejs.org/en/
|
||||
[13]: https://github.com/NodeBB/NodeBB
|
||||
[14]: https://nodebb.org/
|
||||
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/vanilla-forums.png?resize=800%2C433&ssl=1
|
||||
[16]: https://github.com/Vanilla
|
||||
[17]: https://vanillaforums.com/en/
|
||||
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/open-source-eCommerce.png?fit=800%2C450&ssl=1
|
||||
[19]: https://itsfoss.com/open-source-ecommerce/
|
||||
[20]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/bbpress.jpg?resize=800%2C552&ssl=1
|
||||
[21]: https://github.com/bbpress
|
||||
[22]: https://bbpress.org/
|
||||
[23]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/phpBB.png?resize=798%2C600&ssl=1
|
||||
[24]: https://github.com/phpbb/phpbb
|
||||
[25]: https://www.phpbb.com/
|
||||
[26]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/simplemachines.jpg?resize=800%2C343&ssl=1
|
||||
[27]: https://www.simplemachines.org/
|
||||
[28]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/FluxBB.jpg?resize=800%2C542&ssl=1
|
||||
[29]: https://github.com/fluxbb/fluxbb/
|
||||
[30]: https://fluxbb.org/
|
||||
[31]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/mybb-example.png?resize=800%2C461&ssl=1
|
||||
[32]: https://github.com/mybb/mybb
|
||||
[33]: https://mybb.com/
|
||||
[34]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/flarum-screenshot.png?resize=800%2C503&ssl=1
|
||||
[35]: https://docs.flarum.org/
|
||||
[36]: https://github.com/flarum
|
||||
[37]: https://flarum.org/
|
||||
[38]: https://highoncloud.com/
|
@ -0,0 +1,124 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Setting a standard for digital public goods)
|
||||
[#]: via: (https://opensource.com/article/20/12/digital-public-goods)
|
||||
[#]: author: (Lucy https://opensource.com/users/lucyeoh)
|
||||
|
||||
Setting a standard for digital public goods
|
||||
======
|
||||
Nine-indicator standard aims to promote open source software, data, AI
|
||||
models, standards, and content for a more equitable world.
|
||||
![Two diverse hands holding a globe][1]
|
||||
|
||||
In June 2020, the Secretary-General of the United Nations published a "[Roadmap for Digital Cooperation][2]." In this report, he expanded on recommendations made a year before, calling on all actors, including the Member States, the United Nations system, the private sector, and others, to promote digital public goods. He says to realize the benefits of increased internet connectivity, open source projects in the form of digital public goods must be at the center.
|
||||
|
||||
While the term "digital public good" appears as early as April 2017, this report offers the first broadly accepted definition of digital public goods:
|
||||
|
||||
> "Open source software, open data, open AI models, open standards, and open content that adhere to privacy and other applicable international and domestic laws, standards and best practices, and do no harm."
|
||||
|
||||
The Digital Public Goods Alliance (DGPA) translated that definition into a [nine-indicator open standard][3] that we hope will serve as a comprehensive, shared definition to promote the discovery, development, use of, and investment in digital public goods for a more equitable world.
|
||||
|
||||
The DPG standard was developed from the original 51-indicator standard used by the DPGA in the preliminary review of [Early Grade Reading][4] projects and refined through contributions from many experts. The standard is itself an open source project. The core version [lives on GitHub][5] and is open to contributions, revisions, and suggestions from anyone. Proposed revisions are regularly reviewed in alignment with the standard's [governance principles][6], and we invite anyone who uses and benefits from the standard to join our growing [list of endorsers][7].
|
||||
|
||||
The Digital Public Goods Alliance envisions engaging a growing community of contributors and stakeholders around the [Digital Public Goods Standard][3]. Our ambition is to balance responsiveness to feedback with stability and predictability for the standard so that it can be a reliable framework that supports development, recognition, and advocacy for digital public goods.
|
||||
|
||||
### Digital Public Goods Standard
|
||||
|
||||
Below is the DPG Standard's full list of indicators and requirements in v.1.1.2. These must be met in order for a nominated project (software, data, AI model, standard, and/or piece of content) to be considered a digital public good.
|
||||
|
||||
**Indicator**
|
||||
|
||||
**Requirement**
|
||||
|
||||
1\. Relevance to Sustainable Development Goals
|
||||
|
||||
All projects must indicate the [Sustainable Development Goals][8] (SDGs) that they are relevant to and provide supporting links/documentation to support this relevance.
|
||||
|
||||
2\. Use of approved open source license
|
||||
|
||||
Projects must demonstrate the use of an approved open source license. For open source software, we only accept [OSI approved licenses][9]. For open content, we require the use of a [Creative Commons license][10], while we encourage projects to use a license which allows for both derivatives and commercial reuse ([CC-BY][11] and [CC-BY-SA][12]), or dedicate content to the public domain ([CC0][13]); we also accept licenses which do not allow for commercial reuse ([CC BY-NC][14] and [CC BY-NC-SA][15]). For data, we require an [Open Data Commons approved license][16]. You can find [the full license list here][17].
|
||||
|
||||
3\. Documentation of ownership
|
||||
|
||||
Ownership of everything that the project produces must be clearly defined and documented, i.e., through copyright, trademark, or other publicly available information.
|
||||
|
||||
4\. Mandatory dependencies
|
||||
|
||||
If the open source project has mandatory dependencies that create more restrictions than the original license, the projects must be able to demonstrate independence from the closed component and/or indicate the existence of functional, open alternatives.
|
||||
|
||||
5\. Documentation
|
||||
|
||||
The project must have some documentation of the source code, use cases, and/or functional requirements. For content, this should indicate any relevant compatible apps, software, hardware required to access the content, and instructions about how to use it. For software projects, this should be present as technical documentation that would allow a technical person unfamiliar with the project to launch and run the software. For data projects, this should be present as documentation that describes all the fields in the set and provides context on how the data was collected and how it should be interpreted.
|
||||
|
||||
6\. Mechanism for extracting data
|
||||
|
||||
If this project has non personally identifiable information, there must be a mechanism for extracting or importing non personally identifiable information (PII) data from the system in a non-proprietary format.
|
||||
|
||||
_Note that evidence for requirements 7 through 9 can only be given by someone authorized to speak on behalf of the project. We collect title, name, and contact information to confirm this authority._
|
||||
|
||||
7\. Adherence to privacy and applicable laws
|
||||
|
||||
The project must state that, to the best of its knowledge, it complies with relevant privacy laws and all applicable international and domestic laws.
|
||||
|
||||
8\. Adherence to standards and best practices
|
||||
|
||||
Projects must demonstrate some adherence to standards, best practices, and/or principles, i.e., the principles for digital development.
|
||||
|
||||
9\. Do no harm
|
||||
|
||||
All projects must demonstrate that they have taken steps to ensure that the project anticipates, prevents, and does no harm.
|
||||
|
||||
9a. Data privacy and security
|
||||
|
||||
Projects that collect data must identify the types of data collected and stored and demonstrate that the project ensures the privacy and security of this data and has taken steps to prevent adverse impacts resulting from its collection, storage, and distribution.
|
||||
|
||||
9b. Inappropriate and illegal content
|
||||
|
||||
Projects that collect, store, or distribute content must have policies identifying inappropriate and illegal content such as child sexual abuse materials and mechanisms for detecting, moderating, and removing inappropriate/illegal content.
|
||||
|
||||
9c. Protection from harassment
|
||||
|
||||
If the project facilitates interactions with or between users or contributors, there must be a mechanism for users and contributors to protect themselves against grief, abuse, and harassment. The project must have a mechanism to address the safety and security of underage users.
|
||||
|
||||
If you know of a project that you believe meets these standards and should be considered a digital public good, please [submit it][18]. We also welcome your feedback on the standard in the comments below.
|
||||
|
||||
* * *
|
||||
|
||||
_This article is adapted with permission from the post "Setting a standard for digital public goods," which originally appeared on the Digital Public Goods Alliance_ [_blog_][19] _and_ [_Medium_][20] _channel._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/digital-public-goods
|
||||
|
||||
作者:[Lucy][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/lucyeoh
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/world_hands_diversity.png?itok=zm4EDxgE (Two diverse hands holding a globe)
|
||||
[2]: https://www.un.org/en/content/digital-cooperation-roadmap/
|
||||
[3]: https://digitalpublicgoods.net/standard/
|
||||
[4]: https://medium.com/digital-public-goods/announcing-the-first-vetted-digital-public-goods-for-foundational-literacy-and-early-grade-reading-1f5c371a50d3
|
||||
[5]: https://github.com/DPGAlliance/DPG-Standard/blob/master/standard.md
|
||||
[6]: https://github.com/DPGAlliance/DPG-Standard/blob/master/governance.md
|
||||
[7]: https://github.com/DPGAlliance/DPG-Standard/blob/master/endorsement.md
|
||||
[8]: https://sdgs.un.org/goals
|
||||
[9]: https://opensource.org/licenses
|
||||
[10]: https://creativecommons.org/licenses/
|
||||
[11]: https://creativecommons.org/licenses/by/4.0/
|
||||
[12]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[13]: https://creativecommons.org/choose/zero/
|
||||
[14]: https://creativecommons.org/licenses/by-nc/4.0/
|
||||
[15]: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
[16]: https://opendefinition.org/licenses/
|
||||
[17]: https://github.com/unicef/publicgoods-candidates/blob/master/docs/licenses.md
|
||||
[18]: https://forms.gle/8w4pXRUqUV2oKAHi9
|
||||
[19]: https://digitalpublicgoods.net/blog/setting-a-standard-for-digital-public-goods/
|
||||
[20]: https://medium.com/digital-public-goods/setting-a-standard-for-digital-public-goods-a1f28b3d1ed5
|
@ -0,0 +1,90 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Try this Linux text editor for Emacs fans)
|
||||
[#]: via: (https://opensource.com/article/20/12/jove-emacs)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Try this Linux text editor for Emacs fans
|
||||
======
|
||||
If you're looking for a fast, easy Emacs editor without a long list of
|
||||
dependencies, give Jove a try.
|
||||
![Text editor on a browser, in blue][1]
|
||||
|
||||
GNU Emacs is a very famous editor, but not everyone knows that emacs is a _tradition_ of text editors rather than just one specific application.
|
||||
|
||||
The term "emacs" is actually a portmanteau of "Editor Macros," and the first one was programmed in 1976 as a set of macros for the TECO editor. GNU Emacs was developed as an interpretation of this style of visual text editor, and it was notably released as free, hackable, and redistributable software (called "free software" by the [Free Software Foundation][2], although the term "free" in this context means "liberated" rather than "gratis").
|
||||
|
||||
Other versions have been developed over the years, including [Jove][3], an acronym for "Jonathan Payne's Own Version of Emacs." Jove is a small (it's only 250K) and minimalistic version of Emacs that can prove useful when you find GNU Emacs too bloated for what you need.
|
||||
|
||||
### Install Jove
|
||||
|
||||
Fedora and Debian both have packages available for Jove, so it's easy to install on Linux. For instance, on Fedora:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dnf install jove`
|
||||
```
|
||||
|
||||
You can also compile it yourself from [its source code][3]. You must have development tools and libraries installed (such as LLVM on macOS or [MinGW][4] on Windows).
|
||||
|
||||
|
||||
```
|
||||
$ wget <ftp://ftp.cs.toronto.edu/pub/moraes/jove/jove-X.Y.Z.tgz>
|
||||
$ tar xvf jove*z
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
### Launch Jove
|
||||
|
||||
Jove is a terminal-based application (there is legacy code to provide a rudimentary GUI, but the library it's based on isn't 64-bit capable). If you're new to Jove or emacs, then you can learn about both from the `teachjove` tutorial. Start the tutorial by typing `teachjove` into a terminal:
|
||||
|
||||
|
||||
```
|
||||
`$ teachjove`
|
||||
```
|
||||
|
||||
The tutorial is an interactive and guided tour introducing you to the _emacs way_ of entering and manipulating text. This is the easiest way to get started with Jove—and with emacs in general.
|
||||
|
||||
After you've done the tutorial, you can launch Jove by just typing `jove` into a terminal.
|
||||
|
||||
![Jove][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
### Use Jove
|
||||
|
||||
As you might expect, most of what you do in Jove is type text. That's essentially the same regardless of what editor you're using. Working with that text, though, is where things get interesting. For instance, you might find that navigation in Jove feels integrated with other actions you perform because they're built around the **Ctrl** and **Alt** keys, like Copy, Paste, or Select. You can use the **Arrow** keys if you prefer, but try navigating with key combinations like **Ctrl**+**F** (forward) and **Ctrl**+**B** (back), or **Ctrl**+**P** (previous line) and **Ctrl**+**N** (next line). You might find that the unfamiliarity of these key combos is offset by how useful it is to be able to move your cursor around the same way you move text. It's a unified user experience that can help you optimize the way you work with text, whether you deal in prose or code.
|
||||
|
||||
Key combinations in Jove, as in GNU Emacs, invoke functions or commands. You can list all available commands with **Alt**+**?**, and you can press the **Space bar** to scroll through the list. This gives you some idea of what you can make your cursor do in the application or how you can make the application behave.
|
||||
|
||||
To get more information about any command, type **Alt**+**X** and **describe-command** followed by a command's name, and then press **Enter**. At the top of the Jove screen, you get basic information about the command and any key combinations assigned to it.
|
||||
|
||||
For a list of all key combinations, type **Alt**+**X**, then **describe-bindings**, and press **Enter**.
|
||||
|
||||
### Simple Emacs
|
||||
|
||||
Jove is a small, almost minimal emacs. It doesn't have all the functions and modes that GNU Emacs has, but in a way, that's its strength. Jove is a fast, easy editor to compile, start, and use, without a long list of dependencies. Thanks to Jove, you can set `EDITOR` and `VISUAL` to something in the emacs tradition and still get the responsiveness and speed of something like Vi or Nano.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/jove-emacs
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_blue_text_editor_web.png?itok=lcf-m6N7 (Text editor on a browser, in blue)
|
||||
[2]: http://fsf.org
|
||||
[3]: ftp://ftp.cs.toronto.edu/pub/moraes/jove
|
||||
[4]: https://opensource.com/article/20/8/gnu-windows-mingw
|
||||
[5]: https://opensource.com/sites/default/files/uploads/jove.jpg (Jove)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
@ -0,0 +1,117 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Experience the useful features of the Xedit text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/xedit)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Experience the useful features of the Xedit text editor
|
||||
======
|
||||
Xedit, part of the X11 graphic server, isn't much to look at but has
|
||||
enough hidden features to make it a serious text editor.
|
||||
![Computer screen with files or windows open][1]
|
||||
|
||||
The X11 graphic server, distributed by [X.org][2], has a few token applications that show how to program with its provided tools. These range from the [TWM][3] desktop to the silly but hypnotic Xeyes. It also includes a text editor called Xedit, a seemingly simple application with enough hidden features to make it a serious editor.
|
||||
|
||||
### Install Xedit
|
||||
|
||||
If you're on Linux or BSD, you can install Xedit from your distribution's software repository or ports tree. It sometimes appears in a package called X11-apps bundled with other X11 apps.
|
||||
|
||||
On macOS, you can install [XQuartz][4], which provides Xedit, Xeyes, and a few other small applications (along with an X11 graphics server).
|
||||
|
||||
### Launch Xedit
|
||||
|
||||
You can launch Xedit from your application menu, if it's listed. Some distributions treat it more as a command than a GUI app, even though it is definitely a GUI app, so it may not be listed in your application menu. In that case, you can launch Xedit from the terminal. If you type `xedit &` to launch the application, it launches an empty Xedit editor ready for text. If you enter the launch command along with an existing file's name, Xedit starts with the file loaded into its buffer:
|
||||
|
||||
|
||||
```
|
||||
`$ xedit example.txt &`
|
||||
```
|
||||
|
||||
![Xedit][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
### Load a file
|
||||
|
||||
From an open Xedit instance, you can load a file by typing the file's path in the top text field. Click the **Load** button (to the left of the text field) to read the file into the Xedit window.
|
||||
|
||||
![Load Xedit][7]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
You can have several files open at once. When one file is loaded, it takes focus and appears in your main Xedit buffer (the big text field in the main window) and shuffles any existing file into a hidden buffer.
|
||||
|
||||
You can navigate between buffers using a key combo familiar to Emacs users but sometimes confusing to others: First, press **Ctrl+X**. Release those keys, and then press **Ctrl+B**.
|
||||
|
||||
### Key combos
|
||||
|
||||
It feels strange at first to perform actions that require _two_ keyboard shortcuts in a row, but after a while, you get used to it. In fact, as a frequent Emacs user, I find the compound key combinations comfortingly rhythmic. I was surprised and pleased to find that some of my favorite shortcuts were valid in Xedit.
|
||||
|
||||
It turns out that Xedit borrows keyboard shortcuts from several sources of inspiration. If you're an Emacs user, you'll find that the most common combinations are valid in Xedit. For instance, **C-x** **C-f** (that's **Ctrl+X** followed **Ctrl+F**) takes you to the top text field to load a file, and **C-x** **C-s** (**Ctrl+X** followed by **Ctrl+S**) saves a file. Surprisingly, **C-x** **3** even splits the window vertically, while **C-x** **2** splits it horizontally, and **C-x** **0** or **1** removes the split.
|
||||
|
||||
Edit commands familiar to Emacs or Bash users also apply:
|
||||
|
||||
* **Ctrl+A** moves to the beginning of a line.
|
||||
* **Ctrl+E** moves to the end of a line.
|
||||
* **Alt+B** moves back a word.
|
||||
* **Ctrl+B** moves back a character.
|
||||
* **Ctrl+F** moves forward a character.
|
||||
* **Alt+F** moves forward a word.
|
||||
* **Ctrl+D** deletes the next character.
|
||||
|
||||
|
||||
|
||||
There are many more, and they're listed on the Xedit man page.
|
||||
|
||||
### Use line-editing mode
|
||||
|
||||
Xedit also includes a line editor, similar to **ex**, which ought to be familiar to [Vi][8] and `ed` or even `sed` users. To enter line-editing mode, press the **Esc** key. This places you in the top text field but in a command mode. Edit commands use the syntax: _line number_ followed by a _command_ and _parameters_.
|
||||
|
||||
Say you have this text file:
|
||||
|
||||
|
||||
```
|
||||
ed is the standard Unix text editor.
|
||||
This is line number two.
|
||||
```
|
||||
|
||||
You decide you want to change `ed` to `Xedit` in line 1. In Xedit, move to line 1, press **Esc**, and then type `.,s/ed/Xedit/`.
|
||||
|
||||
|
||||
```
|
||||
Xedit is the standard Unix text editor.
|
||||
This is line number two.
|
||||
```
|
||||
|
||||
Without moving your cursor to the next line, you could change `two` to `the second`: Press **Esc** and then type `2,s/two/the second/`.
|
||||
|
||||
Possible commands and valid parameters are listed in Xedit's man page.
|
||||
|
||||
### Simple but robust
|
||||
|
||||
Xedit isn't much to look at. It's simple, it has no menus to speak of, but it borrows some popular conveniences from some of the best Unix editors. The next time you're looking for a new editor, try Xedit.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/xedit
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_screen_windows_files.png?itok=kLTeQUbY (Computer screen with files or windows open)
|
||||
[2]: https://www.x.org/wiki/
|
||||
[3]: https://opensource.com/article/19/12/twm-linux-desktop
|
||||
[4]: http://xquartz.org
|
||||
[5]: https://opensource.com/sites/default/files/uploads/xedit.jpeg (Xedit)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://opensource.com/sites/default/files/uploads/xedit-load.jpg (Load Xedit)
|
||||
[8]: https://opensource.com/article/20/12/vi-text-editor
|
@ -0,0 +1,272 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Add storage to your Fedora system with LVM)
|
||||
[#]: via: (https://fedoramagazine.org/add-storage-to-your-fedora-system-with-lvm/)
|
||||
[#]: author: (Tim Bosse https://fedoramagazine.org/author/maztaim/)
|
||||
|
||||
Add storage to your Fedora system with LVM
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Sometimes there is a need to add another disk to your system. This is where Logical Volume Management (LVM) comes in handy. The cool thing about LVM is that it’s fairly flexible. There are several ways to add a disk. This article describes one way to do it.
|
||||
|
||||
### Heads up!
|
||||
|
||||
This article does not cover the process of physically installing a new disk drive into your system. Consult your system and disk documentation on how to do that properly.
|
||||
|
||||
**Important:** Always make sure you have backups of important data. The steps described in this article will destroy data if it already exists on the new disk.
|
||||
|
||||
### Good to know
|
||||
|
||||
This article doesn’t cover every LVM feature deeply; the focus is on adding a disk. But basically, LVM has _volume groups_, made up of one or more partitions and/or disks. You add the partitions or disks as _physical volumes_. A volume group can be broken down into many _logical volumes_. Logical volumes can be used as any other storage for filesystems, ramdisks, etc. More information can be found [here][2].
|
||||
|
||||
Think of the _physical volumes_ as forming a pool of storage (a _volume group_) from which you then carve out _logical volumes_ for your system to use directly.
|
||||
|
||||
### Preparation
|
||||
|
||||
Make sure you can see the disk you want to add. Use _lsblk_ prior to adding the disk to see what storage is already available or in use.
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
zram0 251:0 0 989M 0 disk [SWAP]
|
||||
vda 252:0 0 20G 0 disk
|
||||
├─vda1 252:1 0 1G 0 part /boot
|
||||
└─vda2 252:2 0 19G 0 part
|
||||
└─fedora_fedora-root 253:0 0 19G 0 lvm /
|
||||
```
|
||||
|
||||
This article uses a virtual machine with virtual storage. Therefore the device names start with _vda_ for the first disk, _vdb_ for the second, and so on. The name of your device may be different. Many systems will see physical disks as _sda_ for the first disk, _sdb_ for the second, and so on.
|
||||
|
||||
Once the new disk has been connected and your system is back up and running, use _lsblk_ again to see the new block device.
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
zram0 251:0 0 989M 0 disk [SWAP]
|
||||
vda 252:0 0 20G 0 disk
|
||||
├─vda1 252:1 0 1G 0 part /boot
|
||||
└─vda2 252:2 0 19G 0 part
|
||||
└─fedora_fedora-root 253:0 0 19G 0 lvm /
|
||||
vdb 252:16 0 10G 0 disk
|
||||
```
|
||||
|
||||
There is now a new device named _vdb_. The location for the device is _/dev/vdb_.
|
||||
|
||||
```
|
||||
$ ls -l /dev/vdb
|
||||
brw-rw----. 1 root disk 252, 16 Nov 24 12:56 /dev/vdb
|
||||
```
|
||||
|
||||
We can see the disk, but we cannot use it with LVM yet. If you run _blkid_ you should not see it listed. For this and following commands, you’ll need to ensure your system is [configured so you can use _sudo_][3]:
|
||||
|
||||
```
|
||||
$ sudo blkid
|
||||
/dev/vda1: UUID="4847cb4d-6666-47e3-9e3b-12d83b2d2448" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="830679b8-01"
|
||||
/dev/vda2: UUID="k5eWpP-6MXw-foh5-Vbgg-JMZ1-VEf9-ARaGNd" TYPE="LVM2_member" PARTUUID="830679b8-02"
|
||||
/dev/mapper/fedora_fedora-root: UUID="f8ab802f-8c5f-4766-af33-90e78573f3cc" BLOCK_SIZE="4096" TYPE="ext4"
|
||||
/dev/zram0: UUID="fc6d7a48-2bd5-4066-9bcf-f062b61f6a60" TYPE="swap"
|
||||
```
|
||||
|
||||
### Add the disk to LVM
|
||||
|
||||
Initialize the disk using _pvcreate_. You need to pass the full path to the device. In this example it is _/dev/vdb_; on your system it may be _/dev/sdb_ or another device name.
|
||||
|
||||
```
|
||||
$ sudo pvcreate /dev/vdb
|
||||
Physical volume "/dev/vdb" successfully created.
|
||||
```
|
||||
|
||||
You should see the disk has been initialized as an LVM2_member when you run _blkid_:
|
||||
|
||||
```
|
||||
$ sudo blkid
|
||||
/dev/vda1: UUID="4847cb4d-6666-47e3-9e3b-12d83b2d2448" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="830679b8-01"
|
||||
/dev/vda2: UUID="k5eWpP-6MXw-foh5-Vbgg-JMZ1-VEf9-ARaGNd" TYPE="LVM2_member" PARTUUID="830679b8-02"
|
||||
/dev/mapper/fedora_fedora-root: UUID="f8ab802f-8c5f-4766-af33-90e78573f3cc" BLOCK_SIZE="4096" TYPE="ext4"
|
||||
/dev/zram0: UUID="fc6d7a48-2bd5-4066-9bcf-f062b61f6a60" TYPE="swap"
|
||||
/dev/vdb: UUID="4uUUuI-lMQY-WyS5-lo0W-lqjW-Qvqw-RqeroE" TYPE="LVM2_member"
|
||||
```
|
||||
|
||||
You can list all physical volumes currently available using _pvs_:
|
||||
|
||||
```
|
||||
$ sudo pvs
|
||||
PV VG Fmt Attr PSize PFree
|
||||
/dev/vda2 fedora_fedora lvm2 a-- <19.00g 0
|
||||
/dev/vdb lvm2 --- 10.00g 10.00g
|
||||
```
|
||||
|
||||
_/dev/vdb_ is listed as a PV (phsyical volume), but it isn’t assigned to a VG (Volume Group) yet.
|
||||
|
||||
### Add the pysical volume to a volume group
|
||||
|
||||
You can find a list of available volume groups using _vgs_:
|
||||
|
||||
```
|
||||
$ sudo vgs
|
||||
VG #PV #LV #SN Attr VSize VFree
|
||||
fedora_fedora 1 1 0 wz--n- 19.00g 0
|
||||
```
|
||||
|
||||
In this example, there is only one volume group available. Next, add the physical volume to _fedora_fedora_:
|
||||
|
||||
```
|
||||
$ sudo vgextend fedora_fedora /dev/vdb
|
||||
Volume group "fedora_fedora" successfully extended
|
||||
```
|
||||
|
||||
You should now see the physical volume is added to the volume group:
|
||||
|
||||
```
|
||||
$ sudo pvs
|
||||
PV VG Fmt Attr PSize PFree
|
||||
/dev/vda2 fedora_fedora lvm2 a– <19.00g 0
|
||||
/dev/vdb fedora_fedora lvm2 a– <10.00g <10.00g
|
||||
```
|
||||
|
||||
Look at the volume groups:
|
||||
|
||||
```
|
||||
$ sudo vgs
|
||||
VG #PV #LV #SN Attr VSize VFree
|
||||
fedora_fedora 2 1 0 wz–n- 28.99g <10.00g
|
||||
```
|
||||
|
||||
You can get a detailed list of the specific volume group and physical volumes as well:
|
||||
|
||||
```
|
||||
$ sudo vgdisplay fedora_fedora
|
||||
--- Volume group ---
|
||||
VG Name fedora_fedora
|
||||
System ID
|
||||
Format lvm2
|
||||
Metadata Areas 2
|
||||
Metadata Sequence No 3
|
||||
VG Access read/write
|
||||
VG Status resizable
|
||||
MAX LV 0
|
||||
Cur LV 1
|
||||
Open LV 1
|
||||
Max PV 0
|
||||
Cur PV 2
|
||||
Act PV 2
|
||||
VG Size 28.99 GiB
|
||||
PE Size 4.00 MiB
|
||||
Total PE 7422
|
||||
Alloc PE / Size 4863 / 19.00 GiB
|
||||
Free PE / Size 2559 / 10.00 GiB
|
||||
VG UUID C5dL2s-dirA-SQ15-TfQU-T3yt-l83E-oI6pkp
|
||||
```
|
||||
|
||||
Look at the PV:
|
||||
|
||||
```
|
||||
$ sudo pvdisplay /dev/vdb
|
||||
--- Physical volume ---
|
||||
PV Name /dev/vdb
|
||||
VG Name fedora_fedora
|
||||
PV Size 10.00 GiB / not usable 4.00 MiB
|
||||
Allocatable yes
|
||||
PE Size 4.00 MiB
|
||||
Total PE 2559
|
||||
Free PE 2559
|
||||
Allocated PE 0
|
||||
PV UUID 4uUUuI-lMQY-WyS5-lo0W-lqjW-Qvqw-RqeroE
|
||||
```
|
||||
|
||||
Now that we have added the disk, we can allocate space to logical volumes (LVs):
|
||||
|
||||
```
|
||||
$ sudo lvs
|
||||
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
|
||||
root fedora_fedora -wi-ao---- 19.00g
|
||||
```
|
||||
|
||||
Look at the logical volumes. Here’s a detailed look at the root LV:
|
||||
|
||||
```
|
||||
$ sudo lvdisplay fedora_fedora/root
|
||||
--- Logical volume ---
|
||||
LV Path /dev/fedora_fedora/root
|
||||
LV Name root
|
||||
VG Name fedora_fedora
|
||||
LV UUID yqc9cw-AvOw-G1Ni-bCT3-3HAa-qnw3-qUSHGM
|
||||
LV Write Access read/write
|
||||
LV Creation host, time fedora, 2020-11-24 11:44:36 -0500
|
||||
LV Status available
|
||||
LV Size 19.00 GiB
|
||||
Current LE 4863
|
||||
Segments 1
|
||||
Allocation inherit
|
||||
Read ahead sectors auto
|
||||
- currently set to 256
|
||||
Block device 253:0
|
||||
```
|
||||
|
||||
Look at the size of the root filesystem and compare it to the logical volume size.
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 19G 1.4G 17G 8% /
|
||||
```
|
||||
|
||||
The logical volume and the filesystem both agree the size is 19G. Let’s add 5G to the root logical volume:
|
||||
|
||||
```
|
||||
$ sudo lvresize -L +5G fedora_fedora/root
|
||||
Size of logical volume fedora_fedora/root changed from 19.00 GiB (4863 extents) to 24.00 GiB (6143 extents).
|
||||
Logical volume fedora_fedora/root successfully resized.
|
||||
```
|
||||
|
||||
We now have 24G available to the logical volume. Look at the _/_ filesystem.
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 19G 1.4G 17G 8% /
|
||||
```
|
||||
|
||||
We are still showing only 19G free. This is because the logical volume is not the same as the filesytem. To use the new space added to the logical volume, resize the filesystem.
|
||||
|
||||
```
|
||||
$ sudo resize2fs /dev/fedora_fedora/root
|
||||
resize2fs 1.45.6 (20-Mar-2020)
|
||||
Filesystem at /dev/fedora_fedora/root is mounted on /; on-line resizing required
|
||||
old_desc_blocks = 3, new_desc_blocks = 3
|
||||
The filesystem on /dev/fedora_fedora/root is now 6290432 (4k) blocks long.
|
||||
```
|
||||
|
||||
Look at the size of the filesystem.
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 24G 1.4G 21G 7% /
|
||||
```
|
||||
|
||||
As you can see, the root file system _(/)_ has taken all of the space available on the logical volume and no reboot was needed.
|
||||
|
||||
You have now initialized a disk as a physical volume, and extended the volume group with the new physical volume. After that you increased the size of the logical volume, and resized the filesystem to use the new space from the logical volume.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/add-storage-to-your-fedora-system-with-lvm/
|
||||
|
||||
作者:[Tim Bosse][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/maztaim/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/11/lvm-add-disk-816x345.jpg
|
||||
[2]: https://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)
|
||||
[3]: https://fedoramagazine.org/howto-use-sudo/
|
@ -0,0 +1,70 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Always on Top: An Often Ignored But Handy Feature in Linux Desktop)
|
||||
[#]: via: (https://itsfoss.com/always-on-top/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Always on Top: An Often Ignored But Handy Feature in Linux Desktop
|
||||
======
|
||||
|
||||
“Always on Top” is one of those features that people are either not aware of or they simply ignore it.
|
||||
|
||||
And this surprises me. Because for me, it is one of the features that I simply love to use on Linux desktop.
|
||||
|
||||
If you are not aware of it already, (almost) all applications have this “Always on Top” option. Usually, when you open a new application, it gets the focus and occupies the screen above all other running applications.
|
||||
|
||||
With the “Always on Top” option selected, the application window will always be visible, no matter what other application you open.
|
||||
|
||||
This comes handy for me in situations where I have to use terminal and read something together. I can keep the terminal in “Always on Top” mode so that it remains visible while I browse the internet or interact with team members through Rocket Chat.
|
||||
|
||||
### Using “Always on Top” feature in Linux
|
||||
|
||||
This cannot be simpler than this. All you have to do is to right-click on the top bar of the application. In here, select the Always on Top option. That’s it.
|
||||
|
||||
![Right click on the application bar and select the option][1]
|
||||
|
||||
Keep in mind that the position of the application is not fixed. You can move the application to any corner of the screen. It will remain visible on the top of all opened applications.
|
||||
|
||||
To disable the “Always on Top” mode, you have to select it one more time.
|
||||
|
||||
![Same steps: Right click on the application bar and select the Always on Top option][2]
|
||||
|
||||
Do note that you won’t see the “Always on Top” option if your application is in full-window mode.
|
||||
|
||||
I know switching between applications is a matter of Alt+Tab keys but when you have several applications running, switching apps will require more than two keystrokes.
|
||||
|
||||
This feature should be available in most desktop environments. If you don’t see it, please [check which desktop environment you are using][3] and let me know. I’ll update the article with the information.
|
||||
|
||||
### Do you like the “Always on Top” feature
|
||||
|
||||
This is like the “Picture in Picture” [feature that modern web browsers like Firefox are providing][4] these days. Linux had it way before.
|
||||
|
||||
I know this is a tiny thing and perhaps did not warrant an entire article. But I also have a feeling that in the world full of [Poirots][5], there will be some [Hastings][6] and for them, this will be a revelation.
|
||||
|
||||
So, are you Hercule Poirot (already using this feature) or Captain Hastings (didn’t know about it)? Or perhaps you are [Chief Inspector Japp][7] (knew about this feature but never bothered to use it).
|
||||
|
||||
I couldn’t help using Agatha Christie jargon. If you are not a fan, just ignore it :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/always-on-top/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/12/set-always-on-top-linux.png?resize=800%2C450&ssl=1
|
||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/disable-always-on-top.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/find-desktop-environment/
|
||||
[4]: https://itsfoss.com/firefox-useful-features/
|
||||
[5]: https://agathachristie.fandom.com/wiki/Hercule_Poirot
|
||||
[6]: https://agathachristie.fandom.com/wiki/Arthur_Hastings
|
||||
[7]: https://agathachristie.fandom.com/wiki/James_Japp
|
@ -0,0 +1,182 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Manage multiple service instances with systemctl)
|
||||
[#]: via: (https://opensource.com/article/20/12/multiple-service-instances-systemctl)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss)
|
||||
|
||||
Manage multiple service instances with systemctl
|
||||
======
|
||||
Running several instances of a service on a single host gets easier with
|
||||
a systemd hack.
|
||||
![People work on a computer server with devices][1]
|
||||
|
||||
Services, services, services. A service is a huge part of computing. You're reading this article on a service. Your computer is running services. The internet is filled with them.
|
||||
|
||||
### About systemctl
|
||||
|
||||
On Linux, the standard way of running and managing services is through the systemd utility and the command `systemctl`. Its usage is fairly simple: you just need to know the name of the service you want to manage, then you can use this command to start or stop the service, check its status, or do other functions:
|
||||
|
||||
|
||||
```
|
||||
# systemctl start httpd
|
||||
|
||||
# systemctl stop httpd
|
||||
|
||||
# systemctl status httpd
|
||||
```
|
||||
|
||||
### Unit files
|
||||
|
||||
A service is defined in a file called a unit file. They are generally located in the directory `/usr/lib/systemd/system`. Here's a sample list:
|
||||
|
||||
|
||||
```
|
||||
# ls /usr/lib/systemd/system
|
||||
auditd.service multi-user.target sys-kernel-debug.mount
|
||||
[autovt@.service][2] multi-user.target.wants sys-kernel-tracing.mount
|
||||
basic.target NetworkManager-dispatcher.service syslog.socket
|
||||
basic.target.wants NetworkManager.service syslog.target.wants
|
||||
blk-availability.service NetworkManager-wait-online.service
|
||||
```
|
||||
|
||||
Sometimes you need to run more than one instance of a service on a single host. For example, if you are maintaining websites for several clients, security regulations demand that each client has its own individual instance. This means you need to run a new Apache HTTP service for each, but having a lot of services can be tough to manage. If you have 10 different customers, you would have to create 10 separate unit files to manage them. Fortunately, there is a better way to handle multiple instances of a service.
|
||||
|
||||
### The @ symbol
|
||||
|
||||
Notice that some of the unit files have an @ symbol in their name. This symbol has an interesting significance. As a matter of fact, after installing Apache HTTP Server, you may notice several service unit files, including one that has the @ symbol in its name—`httpd@.service`.
|
||||
|
||||
I will show you how this can make a system administrator's life a little easier, using the Apache HTTP Server for this example:
|
||||
|
||||
|
||||
```
|
||||
# dnf -y install httpd
|
||||
|
||||
# cd /usr/lib/systemd/system
|
||||
# ls -d http*
|
||||
httpd.service [httpd@.service][3] httpd.service.d httpd.socket httpd.socket.d
|
||||
```
|
||||
|
||||
The @ symbol indicates that a substitution will be made. Systemd will take whatever you type after it and replace the variable `%i` inside the service unit file. The variable can be seen in this excerpt of the `httpd@.service` file:
|
||||
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=The Apache HTTP Server
|
||||
After=network.target remote-fs.target nss-lookup.target
|
||||
Documentation=man:[httpd@.service][3](8)
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
Environment=LANG=C
|
||||
Environment=HTTPD_INSTANCE=%i
|
||||
ExecStartPre=/bin/mkdir -m 710 -p /run/httpd/instance-%i
|
||||
ExecStartPre=/bin/chown root.apache /run/httpd/instance-%i
|
||||
ExecStartPre=/bin/mkdir -m 700 -p /var/lib/httpd/instance-%i
|
||||
ExecStartPre=/bin/chown apache.apache /var/lib/httpd/instance-%i
|
||||
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND -f conf/%i.conf
|
||||
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful -f conf/%i.conf
|
||||
```
|
||||
|
||||
Note that the default httpd unit file, `httpd.service`, does not have the @ symbol in its name and looks different. It is used for a single basic default instance of the Apache HTTP server.
|
||||
|
||||
### Run multiple instances
|
||||
|
||||
To run multiple instances using this special unit file, each one needs a unique name. Suppose you have two clients, The Little Bank and The Big Bank. Name the instances littlebank and bigbank. To manage one, just append its name after the @ symbol. Start each instance with the appropriate command:
|
||||
|
||||
* littlebank: `systemctl start httpd@littlebank`
|
||||
* bigbank: `systemctl start httpd@bigbank`
|
||||
|
||||
|
||||
|
||||
Keep in mind that most services need certain configurations to avoid conflicts between different instances. I will not cover all of them here, but Apache needs several things, including unique listen port numbers, PID files, and document roots.
|
||||
|
||||
I'll demonstrate by trying to start the littlebank instance. I expect it to fail, but it will provide a useful status message:
|
||||
|
||||
|
||||
```
|
||||
# systemctl start httpd@littlebank
|
||||
|
||||
# systemctl status httpd@littlebank
|
||||
● [httpd@littlebank.service][4] \- The Apache HTTP Server
|
||||
Loaded: loaded (/usr/lib/systemd/system/httpd@.service; disabled; vendor preset: disabled)
|
||||
Active: failed (Result: exit-code) since Tue 2020-11-10 11:41:20 EST; 1min 58s ago
|
||||
Docs: man:[httpd@.service][3](8)
|
||||
Process: 2205 ExecStartPre=/bin/mkdir -m 710 -p /run/httpd/instance-littlebank (code=exited, status=0/SUCCESS)
|
||||
Process: 2207 ExecStartPre=/bin/chown root.apache /run/httpd/instance-littlebank (code=exited, status=0/SUCCESS)
|
||||
Process: 2208 ExecStartPre=/bin/mkdir -m 700 -p /var/lib/httpd/instance-littlebank (code=exited, status=0/SUCCESS)
|
||||
Process: 2209 ExecStartPre=/bin/chown apache.apache /var/lib/httpd/instance-littlebank (code=exited, status=0/SUCCESS)
|
||||
Process: 2210 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND -f conf/littlebank.conf (code=exited, status=1/FAILURE)
|
||||
Main PID: 2210 (code=exited, status=1/FAILURE)
|
||||
CPU: 26ms
|
||||
|
||||
Nov 10 11:41:20 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
|
||||
Nov 10 11:41:20 localhost.localdomain httpd[2210]: httpd: Could not open configuration file /etc/httpd/conf/littlebank.conf>
|
||||
Nov 10 11:41:20 localhost.localdomain systemd[1]: [httpd@littlebank.service][4]: Main process exited, code=exited, status=1/FAIL>
|
||||
Nov 10 11:41:20 localhost.localdomain systemd[1]: [httpd@littlebank.service][4]: Failed with result 'exit-code'.
|
||||
Nov 10 11:41:20 localhost.localdomain systemd[1]: Failed to start The Apache HTTP Server.
|
||||
```
|
||||
|
||||
You can see that systemd correctly substitutes the instance name in place of the `%i` variable in the unit file. However, Apache fails to start because it could not open a configuration file. So, now I'll set up the instances to include creating the necessary configuration files (`littlebank.conf` and `bigbank.conf`) in `/etc/httpd/conf/`:
|
||||
|
||||
|
||||
```
|
||||
# ls /etc/httpd/conf
|
||||
bigbank.conf httpd.conf littlebank.conf
|
||||
```
|
||||
|
||||
Now you can manage each instance with `systemctl`. Issue `start` and `status` commands to each. I've shortened the output to the most relevant details:
|
||||
|
||||
|
||||
```
|
||||
# systemctl start httpd@bigbank
|
||||
# systemctl start httpd@littlebank
|
||||
|
||||
# systemctl status httpd@bigbank
|
||||
● [httpd@bigbank.service][5] \- The Apache HTTP Server
|
||||
Loaded: loaded (/usr/lib/systemd/system/httpd@.service; disabled; vendor preset: disabled)
|
||||
Active: active (running) since Tue 2020-11-10 12:26:06 EST; 56min ago
|
||||
|
||||
# systemctl status httpd@littlebank
|
||||
● [httpd@littlebank.service][4] \- The Apache HTTP Server
|
||||
Loaded: loaded (/usr/lib/systemd/system/httpd@.service; disabled; vendor preset: disabled)
|
||||
Active: active (running) since Tue 2020-11-10 12:25:58 EST; 55min ago
|
||||
```
|
||||
|
||||
Here is the process view of these instances. There is more than one because Apache is forking server processes, which it normally does:
|
||||
|
||||
|
||||
```
|
||||
# pgrep -a httpd
|
||||
2834 /usr/sbin/httpd -DFOREGROUND -f conf/littlebank.conf
|
||||
2835 /usr/sbin/httpd -DFOREGROUND -f conf/littlebank.conf
|
||||
2836 /usr/sbin/httpd -DFOREGROUND -f conf/littlebank.conf
|
||||
3061 /usr/sbin/httpd -DFOREGROUND -f conf/bigbank.conf
|
||||
3062 /usr/sbin/httpd -DFOREGROUND -f conf/bigbank.conf
|
||||
3064 /usr/sbin/httpd -DFOREGROUND -f conf/bigbank.conf
|
||||
```
|
||||
|
||||
### Put it to use
|
||||
|
||||
This small systemd feature is very useful when you need many instances of a service. I hope you will be able to put it to good use in your work.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/multiple-service-instances-systemctl
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/alanfdoss
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_linux11x_cc.png?itok=XMDOouJR (People work on a computer server with devices)
|
||||
[2]: mailto:autovt@.service
|
||||
[3]: mailto:httpd@.service
|
||||
[4]: mailto:httpd@littlebank.service
|
||||
[5]: mailto:httpd@bigbank.service
|
@ -0,0 +1,150 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Set up Home Assistant to manage your open source smart home)
|
||||
[#]: via: (https://opensource.com/article/20/12/home-assistant)
|
||||
[#]: author: (Steve Ovens https://opensource.com/users/stratusss)
|
||||
|
||||
Set up Home Assistant to manage your open source smart home
|
||||
======
|
||||
Learn how to install and configure Home Assistant in the fourth article
|
||||
in this series on home automation.
|
||||
![Working from home at a laptop][1]
|
||||
|
||||
In the [first article][2] in this series, I introduced [Home Assistant][3] and why you might be interested in it. In short, Home Assistant is an automation hub for some of the most common smart devices on the market today. It enables centralized coordination of disparate hardware. By using it, you no longer have to choose suboptimal tech from a single vendor to manage your smart home from a single app. It also means you will no longer struggle with a hundred different apps that all function slightly differently to manage all your devices. One program to rule them all… or at least that's the dream.
|
||||
|
||||
In the second and third articles, I looked at some of the decisions to make when developing home automation, namely [local vs. cloud control][4], and whether to choose [Zigbee, Z-Wave, or WiFi][5], just to hit the high points. This fourth article will be much more hands-on than the previous ones by walking you through setting up a virtual machine (VM) with the Home Assistant-provided image.
|
||||
|
||||
### Set up the VM
|
||||
|
||||
I won't cover all of the methods available for installing Home Assistant (HA). I run HA in a virtualized environment, and the [official installation page][6] provides VMDK, VHDX, VDI, QCOW2, and OVA downloads. I have a [libvirt][7]-based homelab, so I chose the QCOW2 image.
|
||||
|
||||
Regardless of which hypervisor you use, you need to make sure that the boot type is set to UEFI instead of the traditional BIOS. In Arch Linux or Fedora, you need to install the package `edk2-ovmf` to have the option available in [Virt-Manager][8]. In Ubuntu, the package is called `ovmf`. After the package is installed, restart libvirt.
|
||||
|
||||
When you create your VM, select the HA image you downloaded. You can accept the default options that Virt-Manager selects _until the confirmation screen_. Make sure you check the box that says **Customize configuration before install**.
|
||||
|
||||
![Customize configuration before install option][9]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
When you do this, make sure to change the firmware to UEFI:
|
||||
|
||||
![Change the firmware to UEFI][11]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
**Important note:** You cannot change the firmware type after the VM has been created. If you choose BIOS, the VM will not boot!
|
||||
|
||||
If you need to expand the amount of disk available to HA's VM, shut down the VM and run:
|
||||
|
||||
|
||||
```
|
||||
qemu-img resize hassos_ova-4.13.qcow2 +40G
|
||||
```
|
||||
|
||||
Upon boot, the new space will be automatically allocated to the appropriate partitions.
|
||||
|
||||
The first boot can take a significant amount of time, as HA pulls down the latest versions of software from the internet and prepares them for initial launch and configuration. To be on the safe side, walk away for 10 minutes or so before attempting to pull up the webpage for the first time. In my experience, it often requires less than five minutes, but 10 minutes is a good amount of time for the system to spin up and settle.
|
||||
|
||||
### First-time setup
|
||||
|
||||
You should now be able to access the HA interface by pointing a browser to `http://homeassistant.local:8123`. However, this relies on your router to support automatic DNS registration. You can also access the webpage via its IP. In my case, that's `http://192.168.122.90:8123`.
|
||||
|
||||
![Home Assistant initial setup screen][12]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
Enter your username and password for the administrative HA account. Then it will prompt you to select a location.
|
||||
|
||||
![Home Assistant location setup][13]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
As you can see, your location is used for "sun-based automations." This means it uses your longitude and latitude to determine sunrise and sunset times and your time zone. If, for example, you have an automation that says, "turn on desk light 20 minutes before sunrise and turn off an hour after sunrise," HA uses this location information to determine what time to activate the lights. Unfortunately, you have to use the graphical map to set this information, and it may not function properly without an active internet connection.
|
||||
|
||||
After you have completed this, you will see a confirmation screen.
|
||||
|
||||
![Home Assistant configuration complete][14]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
Rather than setting up devices here, I prefer to click **Finish** and use the full UI to configure my devices. This is optional, of course. This screen may prepopulate some integrations, depending upon whether HA has automatically discovered devices on your network.
|
||||
|
||||
### Initial user settings
|
||||
|
||||
After you finish the initial configuration, you will see the Overview page. HA's default interface is called [Lovelace][15]. It is a powerful [YAML][16]-described interface. This means that even if you can't choose certain user interface (UI) elements in the graphic interface, you can open the built-in YAML editor and add them yourself.
|
||||
|
||||
Lovelace's default view has a single card that displays the weather based on the location you entered. Click your username (_stratus_ in this example) in the bottom-left panel.
|
||||
|
||||
![Home Assistant user profile][17]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
This brings up another screen with several options. Find **Advanced Mode** and make sure it is toggled on.
|
||||
|
||||
![Home Assistant user profile options][18]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
This setting is toggled _per user_, so if you have other administrative users, only this one (e.g., _stratus_) will have advanced settings turned on. There are quite a few options exposed when toggling **Advanced Mode**, but the one you want is the ability to run a syntax check against the HA configuration files. To see this in action, navigate to **Server Controls** by clicking on the **Configuration** option in the bottom-left panel, and then click on **Server Controls**.
|
||||
|
||||
![Home Assistant server controls][19]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
Clicking on the **Check Configuration** button will check all the HA configuration files for syntax errors. If it finds no errors, you will see a message in green that says **Configuration Valid!**
|
||||
|
||||
![Home Assistant configuration valid][20]
|
||||
|
||||
(Steve Ovens, [CC BY-SA 4.0][10])
|
||||
|
||||
### Looking ahead
|
||||
|
||||
Now that HA is set up and configured, you are ready to start really digging into it. In future articles, I will explain how to:
|
||||
|
||||
* Install and configure add-ons
|
||||
* Create snapshots and run HA updates
|
||||
* Install the Home Assistant Community Store (HACS)
|
||||
* Configure entities via the built-in options
|
||||
* Work with MQTT
|
||||
* Create automation flows with NodeRed
|
||||
|
||||
|
||||
|
||||
And much more. If there's something else you want to learn, please share it in the comments. While I am not a Home Assistant expert, I will do my best to answer your questions about it.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/home-assistant
|
||||
|
||||
作者:[Steve Ovens][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/stratusss
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||
[2]: https://opensource.com/article/20/11/home-assistant
|
||||
[3]: https://www.home-assistant.io/
|
||||
[4]: https://opensource.com/article/20/11/cloud-vs-local-home-automation
|
||||
[5]: https://opensource.com/article/20/11/home-automation-part-3
|
||||
[6]: https://www.home-assistant.io/hassio/installation/
|
||||
[7]: https://libvirt.org/
|
||||
[8]: https://virt-manager.org/
|
||||
[9]: https://opensource.com/sites/default/files/uploads/libvirt_customize1.png (Customize configuration before install option)
|
||||
[10]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[11]: https://opensource.com/sites/default/files/uploads/libvirt_customize2.png (Change the firmware to UEFI)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/ha-setup1-welcome.png (Home Assistant initial setup screen)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/ha-setup2-location.png (Home Assistant location setup)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/ha-setup3-finish.png (Home Assistant configuration complete)
|
||||
[15]: https://www.home-assistant.io/lovelace/
|
||||
[16]: https://en.wikipedia.org/wiki/YAML
|
||||
[17]: https://opensource.com/sites/default/files/uploads/ha-setup3-user-profile.png (Home Assistant user profile)
|
||||
[18]: https://opensource.com/sites/default/files/uploads/ha-setup4-user-advanced.png (Home Assistant user profile options)
|
||||
[19]: https://opensource.com/sites/default/files/uploads/ha-setup5-server-controls.png (Home Assistant server controls)
|
||||
[20]: https://opensource.com/sites/default/files/uploads/ha-setup6-check_config.png (Home Assistant configuration valid)
|
@ -0,0 +1,81 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (3 ways Kubernetes optimizes your IT budget)
|
||||
[#]: via: (https://opensource.com/article/20/12/it-budget-kubernetes)
|
||||
[#]: author: (John Allen https://opensource.com/users/johnallen)
|
||||
|
||||
3 ways Kubernetes optimizes your IT budget
|
||||
======
|
||||
Automation is not only good for IT, it's also beneficial to your
|
||||
company's bottom line.
|
||||
![A dollar sign in a network][1]
|
||||
|
||||
Businesses all over the world are facing extraordinary challenges, and adapting to new ways of work is essential to their survival and progress. The importance of IT workers and systems can't be overstated; with companies looking for innovative ways to adjust, often with reduced resources, automation is increasingly central to day-to-day operations.
|
||||
|
||||
Many of these companies have turned to [Kubernetes][2] to ensure their products and services provide the best possible experience to users. Kubernetes is a container orchestration tool developed by Google. It's been open source since 2014, and over the past few years, a lot of tech success stories (including Netflix and hugely popular online games) have been built on using its tools to coordinate applications.
|
||||
|
||||
![Kubernetes microservices architecture][3]
|
||||
|
||||
Kubernetes' microservice architecture enhances performance by breaking complex apps into components. (John Allen, [CC BY-SA 4.0][4])
|
||||
|
||||
The Kubernetes system's essential role is to make hosting an application with containers manageable. Traditional monolith systems put an app's entire code in one place. In contrast, containers split that code into smaller microservices that perform specific tasks (e.g., controlling volume or processing a payment).
|
||||
|
||||
That might sound like a huge increase in workload, with thousands of containers needing separate maintenance. But Kubernetes enables a regular team of engineers to manage an enormous number of containers.
|
||||
|
||||
If you want to understand the system in detail, [_A beginner's guide to Kubernetes container orchestration_][5] details the what, how, and why of Kubernetes, and it is well worth checking out. From a purely budgeting perspective, though, there are some major benefits to Kubernetes that could maximize your IT resources.
|
||||
|
||||
### Automation
|
||||
|
||||
One of Kubernetes' key benefits is [automation][6], and this is closely linked to the system's utility as an orchestration tool. It can automate individual tasks, thereby streamlining your IT resources by reducing the need for human intervention, but orchestration is required to coordinate those tasks into an overall process.
|
||||
|
||||
Even if each task is perfectly automated, the overall process won't be effective unless those tasks are performed correctly _together_. Essentially, Kubernetes is the conductor that ensures the whole process works.
|
||||
|
||||
Since applications are based on consistently performing the same tasks as part of an overall process, automating each task—as well as the orchestration of those tasks—builds reliability into your infrastructure. This infrastructure is the basis of a good user experience and, therefore, of a strong product.
|
||||
|
||||
By automating much of the day-to-day running of your application, you can focus your IT budget on areas that maximize your return on investment and fund innovations to grow your business.
|
||||
|
||||
### Performance
|
||||
|
||||
Whether your product is a hugely popular online video game or part of the new wave of omnichannel contact center solutions, you need a guaranteed level of performance. The Kubernetes architecture is the key to its popularity, with several important features built in to ensure the performance of even the most complex processes.
|
||||
|
||||
![Kubernetes interface][7]
|
||||
|
||||
Kubernetes' interface makes monitoring performance easier. (John Allen, [CC BY-SA 4.0][4])
|
||||
|
||||
For example, good call-center software needs to run a huge number of processes to maximize customers' potential to reach their desired outcome. Guaranteeing the performance of each one of these elements is essential. Distributing the software's tasks among containers isolates each task. This means there is less that can go wrong, which simplifies the process of fixing errors or updating software. Compartmentalizing tasks, rather than running a monolith, puts less strain on your servers, thereby improving your hardware's efficiency.
|
||||
|
||||
In addition to reducing your IT budget by decreasing time spent on maintenance, this leads to a better user experience. This, in turn, has the potential to produce greater uptake and increased profitability.
|
||||
|
||||
### Maintenance
|
||||
|
||||
If your business relies on users' ability to interact with your application, you will understand the dread of being down for maintenance. Kubernetes can help eliminate many of the issues that lead to reduced availability. Monolith architecture maintenance requires an entire system to be taken down, fixed, tested, and re-deployed, which costs time and money and frustrates users. A microservices architecture allows issues to be isolated and resolved without downtime, meaning your app is always ready for use.
|
||||
|
||||
The mutability of Kubernetes means it can adapt to a variety of infrastructures across physical, virtual, cloud, and hybrid environments. The maintenance involved with building for Kubernetes (or transferring from monolith to container) adapts to the experience of developers looking to find the most effective solution.
|
||||
|
||||
With more and more people working from home, enabling workers to coordinate remotely on complex projects is essential. Videoconferencing and providing virtual phone numbers are highly effective ways of ensuring smooth project management. Knowing you're working within a system that can deal with a huge number of problems and provide practical solutions is also invaluable. Because Kubernetes is open source, it also benefits from shared knowledge that lets you implement performance-enhancing features as they are developed.
|
||||
|
||||
Naturally, implementing new infrastructure will incur upfront costs. However, the long-term benefits mean it's worth considering Kubernetes. Not only can your company optimize its existing budget and services, but you can also explore innovative new ways of growing. Switching to Kubernetes sooner rather than later may lead to improved performance, automated IT processes, lower maintenance, and happier users.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/it-budget-kubernetes
|
||||
|
||||
作者:[John Allen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/johnallen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_whitehurst_money.png?itok=ls-SOzM0 (A dollar sign in a network)
|
||||
[2]: https://kubernetes.io/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/kubernetesarchitecture.jpg (Kubernetes microservices architecture)
|
||||
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[5]: https://opensource.com/article/20/6/container-orchestration
|
||||
[6]: https://opensource.com/article/20/11/orchestration-vs-automation
|
||||
[7]: https://opensource.com/sites/default/files/uploads/kubernetesui.jpg (Kubernetes interface)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user