mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-31 23:30:11 +08:00
commit
daff642c11
262
published/20190221 Testing Bash with BATS.md
Normal file
262
published/20190221 Testing Bash with BATS.md
Normal file
@ -0,0 +1,262 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (stevenzdg988)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13194-1.html)
|
||||
[#]: subject: (Testing Bash with BATS)
|
||||
[#]: via: (https://opensource.com/article/19/2/testing-bash-bats)
|
||||
[#]: author: (Darin London https://opensource.com/users/dmlond)
|
||||
|
||||
利用 BATS 测试 Bash 脚本和库
|
||||
======
|
||||
|
||||
> Bash 自动测试系统可以使 Bash 代码也通过 Java、Ruby 和 Python 开发人员所使用的同类测试过程。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/11/214705wcjm3vjpn9g69gl3.jpg)
|
||||
|
||||
用 Java、Ruby 和 Python 等语言编写应用程序的软件开发人员拥有复杂的库,可以帮助他们随着时间的推移保持软件的完整性。他们可以创建测试,以在结构化环境中通过执行一系列动作来运行应用程序,以确保其软件所有的方面均按预期工作。
|
||||
|
||||
当这些测试在持续集成(CI)系统中自动进行时,它们的功能就更加强大了,每次推送到源代码库都会触发测试,并且在测试失败时会立即通知开发人员。这种快速反馈提高了开发人员对其应用程序功能完整性的信心。
|
||||
|
||||
<ruby>Bash 自动测试系统<rt>Bash Automated Testing System</rt></ruby>([BATS][1])使编写 Bash 脚本和库的开发人员能够将 Java、Ruby、Python 和其他开发人员所使用的相同惯例应用于其 Bash 代码中。
|
||||
|
||||
### 安装 BATS
|
||||
|
||||
BATS GitHub 页面包含了安装指令。有两个 BATS 辅助库提供更强大的断言或允许覆写 BATS 使用的 Test Anything Protocol([TAP][2])输出格式。这些库可以安装在一个标准位置,并被所有的脚本引用。更方便的做法是,将 BATS 及其辅助库的完整版本包含在 Git 仓库中,用于要测试的每组脚本或库。这可以通过 [git 子模块][3] 系统来完成。
|
||||
|
||||
以下命令会将 BATS 及其辅助库安装到 Git 知识库中的 `test` 目录中。
|
||||
|
||||
```
|
||||
git submodule init
|
||||
git submodule add https://github.com/sstephenson/bats test/libs/bats
|
||||
git submodule add https://github.com/ztombol/bats-assert test/libs/bats-assert
|
||||
git submodule add https://github.com/ztombol/bats-support test/libs/bats-support
|
||||
git add .
|
||||
git commit -m 'installed bats'
|
||||
```
|
||||
|
||||
要克隆 Git 仓库并同时安装其子模块,请在 `git clone` 时使用
|
||||
`--recurse-submodules` 标记。
|
||||
|
||||
每个 BATS 测试脚本必须由 `bats` 可执行文件执行。如果你将 BATS 安装到源代码仓库的 `test/libs` 目录中,则可以使用以下命令调用测试:
|
||||
|
||||
```
|
||||
./test/libs/bats/bin/bats <测试脚本的路径>
|
||||
```
|
||||
|
||||
或者,将以下内容添加到每个 BATS 测试脚本的开头:
|
||||
|
||||
```
|
||||
#!/usr/bin/env ./test/libs/bats/bin/bats
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
```
|
||||
|
||||
并且执行命令 `chmod +x <测试脚本的路径>`。 这将 a、使它们可与安装在 `./test/libs/bats` 中的 BATS 一同执行,并且 b、包含这些辅助库。BATS 测试脚本通常存储在 `test` 目录中,并以要测试的脚本命名,扩展名为 `.bats`。例如,一个测试 `bin/build` 的 BATS 脚本应称为 `test/build.bats`。
|
||||
|
||||
你还可以通过向 BATS 传递正则表达式来运行一整套 BATS 测试文件,例如 `./test/lib/bats/bin/bats test/*.bats`。
|
||||
|
||||
### 为 BATS 覆盖率而组织库和脚本
|
||||
|
||||
Bash 脚本和库必须以一种有效地方式将其内部工作原理暴露给 BATS 进行组织。通常,在调用或执行时库函数和运行诸多命令的 Shell 脚本不适合进行有效的 BATS 测试。
|
||||
|
||||
例如,[build.sh][4] 是许多人都会编写的典型脚本。本质上是一大堆代码。有些人甚至可能将这堆代码放入库中的函数中。但是,在 BATS 测试中运行一大堆代码,并在单独的测试用例中覆盖它可能遇到的所有故障类型是不可能的。测试这堆代码并有足够的覆盖率的唯一方法就是把它分解成许多小的、可重用的、最重要的是可独立测试的函数。
|
||||
|
||||
向库添加更多的函数很简单。额外的好处是其中一些函数本身可以变得出奇的有用。将库函数分解为许多较小的函数后,你可以在 BATS 测试中<ruby>援引<rt>source</er></ruby>这些库,并像测试任何其他命令一样运行这些函数。
|
||||
|
||||
Bash 脚本也必须分解为多个函数,执行脚本时,脚本的主要部分应调用这些函数。此外,还有一个非常有用的技巧,可以让你更容易地用 BATS 测试 Bash 脚本:将脚本主要部分中执行的所有代码都移到一个函数中,称为 `run_main`。然后,将以下内容添加到脚本的末尾:
|
||||
|
||||
```
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]
|
||||
then
|
||||
run_main
|
||||
fi
|
||||
```
|
||||
|
||||
这段额外的代码做了一些特别的事情。它使脚本在作为脚本执行时与使用<ruby>援引<rt>source</er></ruby>进入环境时的行为有所不同。通过援引并测试单个函数,这个技巧使得脚本的测试方式和库的测试方式变得一样。例如,[这是重构的 build.sh,以获得更好的 BATS 可测试性][5]。
|
||||
|
||||
### 编写和运行测试
|
||||
|
||||
如上所述,BATS 是一个 TAP 兼容的测试框架,其语法和输出对于使用过其他 TAP 兼容测试套件(例如 JUnit、RSpec 或 Jest)的用户来说将是熟悉的。它的测试被组织成单个测试脚本。测试脚本被组织成一个或多个描述性 `@test` 块中,它们描述了被测试应用程序的单元。每个 `@test` 块将运行一系列命令,这些命令准备测试环境、运行要测试的命令,并对被测试命令的退出和输出进行断言。许多断言函数是通过 `bats`、`bats-assert` 和 `bats-support` 库导入的,这些库在 BATS 测试脚本的开头加载到环境中。下面是一个典型的 BATS 测试块:
|
||||
|
||||
```
|
||||
@test "requires CI_COMMIT_REF_SLUG environment variable" {
|
||||
unset CI_COMMIT_REF_SLUG
|
||||
assert_empty "${CI_COMMIT_REF_SLUG}"
|
||||
run some_command
|
||||
assert_failure
|
||||
assert_output --partial "CI_COMMIT_REF_SLUG"
|
||||
}
|
||||
```
|
||||
|
||||
如果 BATS 脚本包含 `setup`(安装)和/或 `teardown`(拆卸) 函数,则 BATS 将在每个测试块运行之前和之后自动执行它们。这样就可以创建环境变量、测试文件以及执行一个或所有测试所需的其他操作,然后在每次测试运行后将其拆卸。[Build.bats][6] 是对我们新格式化的 `build.sh` 脚本的完整 BATS 测试。(此测试中的 `mock_docker` 命令将在以下关于模拟/打标的部分中进行说明。)
|
||||
|
||||
当测试脚本运行时,BATS 使用 `exec`(执行)来将每个 `@test` 块作为单独的子进程运行。这样就可以在一个 `@test` 中导出环境变量甚至函数,而不会影响其他 `@test` 或污染你当前的 Shell 会话。测试运行的输出是一种标准格式,可以被人理解,并且可以由 TAP 使用端以编程方式进行解析或操作。下面是 `CI_COMMIT_REF_SLUG` 测试块失败时的输出示例:
|
||||
|
||||
```
|
||||
✗ requires CI_COMMIT_REF_SLUG environment variable
|
||||
(from function `assert_output' in file test/libs/bats-assert/src/assert.bash, line 231,
|
||||
in test file test/ci_deploy.bats, line 26)
|
||||
`assert_output --partial "CI_COMMIT_REF_SLUG"' failed
|
||||
|
||||
-- output does not contain substring --
|
||||
substring (1 lines):
|
||||
CI_COMMIT_REF_SLUG
|
||||
output (3 lines):
|
||||
./bin/deploy.sh: join_string_by: command not found
|
||||
oc error
|
||||
Could not login
|
||||
--
|
||||
|
||||
** Did not delete , as test failed **
|
||||
|
||||
1 test, 1 failure
|
||||
```
|
||||
|
||||
下面是成功测试的输出:
|
||||
|
||||
```
|
||||
✓ requires CI_COMMIT_REF_SLUG environment variable
|
||||
```
|
||||
|
||||
### 辅助库
|
||||
|
||||
像任何 Shell 脚本或库一样,BATS 测试脚本可以包括辅助库,以在测试之间共享通用代码或增强其性能。这些辅助库,例如 `bats-assert` 和 `bats-support` 甚至可以使用 BATS 进行测试。
|
||||
|
||||
库可以和 BATS 脚本放在同一个测试目录下,如果测试目录下的文件数量过多,也可以放在 `test/libs` 目录下。BATS 提供了 `load` 函数,该函数接受一个相对于要测试的脚本的 Bash 文件的路径(例如,在我们的示例中的 `test`),并援引该文件。文件必须以后缀 `.bash` 结尾,但是传递给 `load` 函数的文件路径不能包含后缀。`build.bats` 加载 `bats-assert` 和 `bats-support` 库、一个小型 [helpers.bash][7] 库以及 `docker_mock.bash` 库(如下所述),以下代码位于测试脚本的开头,解释器魔力行下方:
|
||||
|
||||
```
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
load 'helpers'
|
||||
load 'docker_mock'
|
||||
```
|
||||
|
||||
### 打标测试输入和模拟外部调用
|
||||
|
||||
大多数 Bash 脚本和库运行时都会执行函数和/或可执行文件。通常,它们被编程为基于这些函数或可执行文件的输出状态或输出(`stdout`、`stderr`)以特定方式运行。为了正确地测试这些脚本,通常需要制作这些命令的伪版本,这些命令被设计成在特定测试过程中以特定方式运行,称为“<ruby>打标<rt>stubbing</rt></ruby>”。可能还需要监视正在测试的程序,以确保其调用了特定命令,或者使用特定参数调用了特定命令,此过程称为“<ruby>模拟<rt>mocking</rt></ruby>”。有关更多信息,请查看在 Ruby RSpec 中 [有关模拟和打标的讨论][8],它适用于任何测试系统。
|
||||
|
||||
Bash shell 提供了一些技巧,可以在你的 BATS 测试脚本中使用这些技巧进行模拟和打标。所有这些都需要使用带有 `-f` 标志的 Bash `export` 命令来导出一个覆盖了原始函数或可执行文件的函数。必须在测试程序执行之前完成此操作。下面是重写可执行命令 `cat` 的简单示例:
|
||||
|
||||
```
|
||||
function cat() { echo "THIS WOULD CAT ${*}" }
|
||||
export -f cat
|
||||
```
|
||||
|
||||
此方法以相同的方式覆盖了函数。如果一个测试需要覆盖要测试的脚本或库中的函数,则在对函数进行打标或模拟之前,必须先声明已测试脚本或库,这一点很重要。否则,在声明脚本时,打标/模拟将被原函数替代。另外,在运行即将进行的测试命令之前确认打标/模拟。下面是`build.bats` 的示例,该示例模拟 `build.sh` 中描述的`raise` 函数,以确保登录函数会引发特定的错误消息:
|
||||
|
||||
```
|
||||
@test ".login raises on oc error" {
|
||||
source ${profile_script}
|
||||
function raise() { echo "${1} raised"; }
|
||||
export -f raise
|
||||
run login
|
||||
assert_failure
|
||||
assert_output -p "Could not login raised"
|
||||
}
|
||||
```
|
||||
|
||||
一般情况下,没有必要在测试后复原打标/模拟的函数,因为 `export`(输出)仅在当前 `@test` 块的 `exec`(执行)期间影响当前子进程。但是,可以模拟/打标 BATS `assert` 函数在内部使用的命令(例如 `cat`、`sed` 等)是可能的。在运行这些断言命令之前,必须对这些模拟/打标函数进行 `unset`(复原),否则它们将无法正常工作。下面是 `build.bats` 中的一个示例,该示例模拟 `sed`,运行 `build_deployable` 函数并在运行任何断言之前复原 `sed`:
|
||||
|
||||
```
|
||||
@test ".build_deployable prints information, runs docker build on a modified Dockerfile.production and publish_image when its not a dry_run" {
|
||||
local expected_dockerfile='Dockerfile.production'
|
||||
local application='application'
|
||||
local environment='environment'
|
||||
local expected_original_base_image="${application}"
|
||||
local expected_candidate_image="${application}-candidate:${environment}"
|
||||
local expected_deployable_image="${application}:${environment}"
|
||||
source ${profile_script}
|
||||
mock_docker build --build-arg OAUTH_CLIENT_ID --build-arg OAUTH_REDIRECT --build-arg DDS_API_BASE_URL -t "${expected_deployable_image}" -
|
||||
function publish_image() { echo "publish_image ${*}"; }
|
||||
export -f publish_image
|
||||
function sed() {
|
||||
echo "sed ${*}" >&2;
|
||||
echo "FROM application-candidate:environment";
|
||||
}
|
||||
export -f sed
|
||||
run build_deployable "${application}" "${environment}"
|
||||
assert_success
|
||||
unset sed
|
||||
assert_output --regexp "sed.*${expected_dockerfile}"
|
||||
assert_output -p "Building ${expected_original_base_image} deployable ${expected_deployable_image} FROM ${expected_candidate_image}"
|
||||
assert_output -p "FROM ${expected_candidate_image} piped"
|
||||
assert_output -p "build --build-arg OAUTH_CLIENT_ID --build-arg OAUTH_REDIRECT --build-arg DDS_API_BASE_URL -t ${expected_deployable_image} -"
|
||||
assert_output -p "publish_image ${expected_deployable_image}"
|
||||
}
|
||||
```
|
||||
|
||||
有的时候相同的命令,例如 `foo`,将在被测试的同一函数中使用不同的参数多次调用。这些情况需要创建一组函数:
|
||||
|
||||
* `mock_foo`:将期望的参数作为输入,并将其持久化到 TMP 文件中
|
||||
* `foo`:命令的模拟版本,该命令使用持久化的预期参数列表处理每个调用。必须使用 `export -f` 将其导出。
|
||||
* `cleanup_foo`:删除 TMP 文件,用于拆卸函数。这可以进行测试以确保在删除之前成功完成 `@test` 块。
|
||||
|
||||
由于此功能通常在不同的测试中重复使用,因此创建一个可以像其他库一样加载的辅助库会变得有意义。
|
||||
|
||||
[docker_mock.bash][9] 是一个很棒的例子。它被加载到 `build.bats` 中,并在任何测试调用 Docker 可执行文件的函数的测试块中使用。使用 `docker_mock` 典型的测试块如下所示:
|
||||
|
||||
```
|
||||
@test ".publish_image fails if docker push fails" {
|
||||
setup_publish
|
||||
local expected_image="image"
|
||||
local expected_publishable_image="${CI_REGISTRY_IMAGE}/${expected_image}"
|
||||
source ${profile_script}
|
||||
mock_docker tag "${expected_image}" "${expected_publishable_image}"
|
||||
mock_docker push "${expected_publishable_image}" and_fail
|
||||
run publish_image "${expected_image}"
|
||||
assert_failure
|
||||
assert_output -p "tagging ${expected_image} as ${expected_publishable_image}"
|
||||
assert_output -p "tag ${expected_image} ${expected_publishable_image}"
|
||||
assert_output -p "pushing image to gitlab registry"
|
||||
assert_output -p "push ${expected_publishable_image}"
|
||||
}
|
||||
```
|
||||
|
||||
该测试建立了一个使用不同的参数两次调用 Docker 的预期。在对Docker 的第二次调用失败时,它会运行测试命令,然后测试退出状态和对 Docker 调用的预期。
|
||||
|
||||
一方面 BATS 利用 `mock_docker.bash` 引入 `${BATS_TMPDIR}` 环境变量,BATS 在测试开始的位置对其进行了设置,以允许测试和辅助程序在标准位置创建和销毁 TMP 文件。如果测试失败,`mock_docker.bash` 库不会删除其持久化的模拟文件,但会打印出其所在位置,以便可以查看和删除它。你可能需要定期从该目录中清除旧的模拟文件。
|
||||
|
||||
关于模拟/打标的一个注意事项:`build.bats` 测试有意识地违反了关于测试声明的规定:[不要模拟没有拥有的!][10] 该规定要求调用开发人员没有编写代码的测试命令,例如 `docker`、`cat`、`sed` 等,应封装在自己的库中,应在使用它们脚本的测试中对其进行模拟。然后应该在不模拟外部命令的情况下测试封装库。
|
||||
|
||||
这是一个很好的建议,而忽略它是有代价的。如果 Docker CLI API 发生变化,则测试脚本不会检测到此变化,从而导致错误内容直到经过测试的 `build.sh` 脚本在使用新版本 Docker 的生产环境中运行后才显示出来。测试开发人员必须确定要严格遵守此标准的程度,但是他们应该了解其所涉及的权衡。
|
||||
|
||||
### 总结
|
||||
|
||||
在任何软件开发项目中引入测试制度,都会在以下两方面产生权衡: a、增加开发和维护代码及测试所需的时间和组织,b、增加开发人员在对应用程序整个生命周期中完整性的信心。测试制度可能不适用于所有脚本和库。
|
||||
|
||||
通常,满足以下一个或多个条件的脚本和库才可以使用 BATS 测试:
|
||||
|
||||
* 值得存储在源代码管理中
|
||||
* 用于关键流程中,并依靠它们长期稳定运行
|
||||
* 需要定期对其进行修改以添加/删除/修改其功能
|
||||
* 可以被其他人使用
|
||||
|
||||
一旦决定将测试规则应用于一个或多个 Bash 脚本或库,BATS 就提供其他软件开发环境中可用的全面测试功能。
|
||||
|
||||
致谢:感谢 [Darrin Mann][11] 向我引荐了 BATS 测试。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/2/testing-bash-bats
|
||||
|
||||
作者:[Darin London][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dmlond
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/sstephenson/bats
|
||||
[2]: http://testanything.org/
|
||||
[3]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
[4]: https://github.com/dmlond/how_to_bats/blob/preBats/build.sh
|
||||
[5]: https://github.com/dmlond/how_to_bats/blob/master/bin/build.sh
|
||||
[6]: https://github.com/dmlond/how_to_bats/blob/master/test/build.bats
|
||||
[7]: https://github.com/dmlond/how_to_bats/blob/master/test/helpers.bash
|
||||
[8]: https://www.codewithjason.com/rspec-mocks-stubs-plain-english/
|
||||
[9]: https://github.com/dmlond/how_to_bats/blob/master/test/docker_mock.bash
|
||||
[10]: https://github.com/testdouble/contributing-tests/wiki/Don't-mock-what-you-don't-own
|
||||
[11]: https://github.com/dmann
|
@ -3,32 +3,32 @@
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13195-1.html)
|
||||
|
||||
你现在可以在 Ubuntu 和基于 Debian 的 Linux 发行版上安装官方 Evernote 客户端了
|
||||
在 Linux 上安装官方 Evernote 客户端
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/12/064741kvenjiev6qvia4ia.jpg)
|
||||
|
||||
[Evernote][1] 是一款流行的笔记应用。它在推出时是一个革命性的产品。从那时起,已经有好几个这样的应用,可以将网络剪报、笔记等保存为笔记本格式。
|
||||
|
||||
多年来,Evernote 的桌面客户端一直没有在 Linux 上使用。前段时间 Evernote 承诺推出 Linux 应用,其测试版终于可以在基于 Ubuntu 的发行版上使用了。
|
||||
多年来,Evernote 一直没有在 Linux 上使用的桌面客户端。前段时间 Evernote 承诺推出 Linux 应用,其测试版终于可以在基于 Ubuntu 的发行版上使用了。
|
||||
|
||||
非 FOSS 警报!
|
||||
|
||||
Evernote Linux 客户端不是开源的。之所以在这里介绍它,是因为该应用是在 Linux 上提供的,我们也会不定期地介绍 Linux 用户常用的非 foss 应用。这对普通桌面 Linux 用户有帮助。
|
||||
> 非 FOSS 警报!
|
||||
>
|
||||
> Evernote Linux 客户端不是开源的。之所以在这里介绍它,是因为该应用是在 Linux 上提供的,我们也会不定期地介绍 Linux 用户常用的非 FOSS 应用。这对普通桌面 Linux 用户有帮助。
|
||||
|
||||
### 在 Ubuntu 和基于 Debian 的 Linux 发行版上安装 Evernote
|
||||
|
||||
进入下面这个 Evernote 的网站页面:
|
||||
|
||||
[Evernote Linux Beta Program][2]
|
||||
进入这个 Evernote 的[网站页面][2]。
|
||||
|
||||
向下滚动一点,接受“早期测试计划”的条款和条件。你会看到一个“立即安装”的按钮出现在屏幕上。点击它来下载 DEB 文件。
|
||||
|
||||
![][3]
|
||||
|
||||
要[从 DEB 文件安装应用][4],请双击它。它应该会打开软件中心,并给你选择安装它。
|
||||
要 [从 DEB 文件安装应用][4],请双击它。它应该会打开软件中心,并给你选择安装它。
|
||||
|
||||
![][5]
|
||||
|
||||
@ -50,11 +50,11 @@ Evernote Linux 客户端不是开源的。之所以在这里介绍它,是因
|
||||
|
||||
由于软件处于测试版,因此这里或那里会有些问题。
|
||||
|
||||
如上图所示,Evernote Linux 客户端检测到 [Ubuntu 中的深色模式][9]并自动切换到深色主题。然而,当我把系统主题改为浅色或标准主题时,它并没有立即改变应用主题。这些变化是在我重启 Evernote 应用后才生效的。
|
||||
如上图所示,Evernote Linux 客户端检测到 [Ubuntu 中的深色模式][9] 并自动切换到深色主题。然而,当我把系统主题改为浅色或标准主题时,它并没有立即改变应用主题。这些变化是在我重启 Evernote 应用后才生效的。
|
||||
|
||||
另一个问题是关于关闭应用。如果你点击 X 按钮关闭 Evernote,程序会进入后台而不是退出。
|
||||
另一个问题是关于关闭应用。如果你点击 “X” 按钮关闭 Evernote,程序会进入后台而不是退出。
|
||||
|
||||
有一个应用指示器,似乎可以启动最小化的 Evernote,就像 [Linux 上的 Skype][10]。不幸的是,事实并非如此。它打开了便笺,让你快速输入笔记。
|
||||
有一个似乎可以启动最小化的 Evernote 的应用指示器,就像 [Linux 上的 Skype][10]。不幸的是,事实并非如此。它打开了便笺,让你快速输入笔记。
|
||||
|
||||
这为你提供了另一个 [Linux 上的笔记应用][11],但它也带来了一个问题。这里没有退出 Evernote 的选项。它只用于打开快速记事应用。
|
||||
|
||||
@ -62,7 +62,7 @@ Evernote Linux 客户端不是开源的。之所以在这里介绍它,是因
|
||||
|
||||
那么,如何退出 Evernote 应用呢?为此,再次打开 Evernote 应用。如果它在后台运行,在菜单中搜索它,并启动它,就像你重新打开它一样。
|
||||
|
||||
当 Evernote 应用在前台运行时,点击 File->Quit 退出 Evernote。
|
||||
当 Evernote 应用在前台运行时,点击 “文件->退出” 来退出 Evernote。
|
||||
|
||||
![][13]
|
||||
|
||||
@ -81,7 +81,7 @@ via: https://itsfoss.com/install-evernote-ubuntu/
|
||||
作者:[Abhishek Prakash][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/) 荣誉推出
|
||||
|
@ -0,0 +1,63 @@
|
||||
[#]: subject: (Test cases and open source license enforcement)
|
||||
[#]: via: (https://opensource.com/article/21/3/test-cases-open-source-licenses)
|
||||
[#]: author: (Richard Fontana https://opensource.com/users/fontana)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Test cases and open source license enforcement
|
||||
======
|
||||
If you're trying to enforce open source licenses, test case litigation
|
||||
is not the right way to do it.
|
||||
![A gavel.][1]
|
||||
|
||||
A test case is a lawsuit brought primarily to achieve a policy outcome by securing a judicial ruling that reverses settled law or clarifies some disputed legal question. Bringing a test case typically involves carefully planning out where, when, and whom to sue and which legal arguments to advance in order to maximize the chances of winning the desired result. In the United States, we often see test case strategies used by public interest organizations to effect legal change that cannot practically be attained through other governmental means.
|
||||
|
||||
But a test case strategy can be used by either side of a policy dispute. Even if a test case is successful, the real policy goal may continue to be elusive, given the limitations of case-specific court judgments, which may be met with administrative obstruction or legislative nullification. Test case litigation can also fail, sometimes disastrously—in the worst case, from the test litigant's perspective, the court might issue a ruling that is the direct opposite of what was sought, as happened in [_Plessy v. Ferguson_][2].
|
||||
|
||||
It may be hard to imagine a test case centered around interpretation of a software license. While licenses are necessarily based on underlying legal rules, typical software licenses are private transactions with terms that are negotiated by the parties or are form agreements unique to the licensor. Normally, a dispute over interpretation of some term in a software license would not be expected to implicate the sort of broadly applicable policy issues that are the usual focus of test case litigation.
|
||||
|
||||
But open source is quite different in this respect. Most open source software is governed by a small set of de facto standard licenses, used without modification or customization across a wide range of projects. Relatedly, open source licenses have an importance to project communities that extends beyond mere licensing terms. They are "[constitutions of communities][3]," an expression of the collaborative and ethical norms of those communities. For these reasons, [open source licenses function as shared resources][4]. This characteristic makes a license-enforcement test case conceivable.
|
||||
|
||||
Whether there actually has ever been an open source license test case is unclear. Litigation over open source licenses has been quite uncommon (though it may be [increasing][5]). Most open source license compliance matters are resolved through voluntary efforts by the licensee, or through community discussion or amicable negotiation with licensors, without resort to the courts. Open source license-enforcement litigation has mostly involved the GPL or another copyleft license in the GNU license family. The fairly small number of litigated GPL enforcement cases brought by community-oriented organizations—Harald Welte's [GPL-violations.org][6] cases, the [Free Software Foundation's suit against Cisco][7], the [BusyBox cases][8]—largely involved factually straightforward "no source or offer" violations. The [copyright profiteering lawsuits][9] brought by Patrick McHardy are clearly not calculated to lead to judicial rulings on questions of GPL interpretation.
|
||||
|
||||
One notable GPL enforcement suit that arguably has some of the characteristics of a test case is Christoph Hellwig's [now-concluded case against VMware in Germany][10], which was funded by the Software Freedom Conservancy. The Hellwig case was apparently the first GPL enforcement lawsuit to raise as a central issue the scope of derivative works under GPLv2, a core copyleft and GPL interpretation policy issue and a policy topic that has been debated in technical and legal communities for decades. Hellwig and Conservancy may have hoped that a victory on the merits would have a far-reaching regulatory impact on activities long-criticized by many GPL supporters, particularly the practice of distributing proprietary Linux kernel modules using GPL-licensed "shim" layers. Then again, Conservancy itself was careful to downplay the notion that the Hellwig case was intended as "[the great test case of combined/derivative works.][11]" And the facts in the Hellwig case, involving a proprietary VMware kernel and GPL-licensed kernel modules, were fairly unusual in comparison to typical GPL-compliance scenarios involving Linux.
|
||||
|
||||
Some developers and lawyers may be predisposed to view open source test cases positively. But this ignores the downsides of test case litigation in the open source context, which are a direct consequence of open source licenses being shared resources. Litigation, whether based on test cases or otherwise, is a poor means of pursuing open source license compliance. You might assume that if open source licenses are shared resources, litigation resulting in judicial rulings would be beneficial by providing increased legal certainty over the limited set of licenses in wide use. But this rests on an unrealistically rosy view of litigation and its impact. Given that open source licenses are, for the most part, a small set of widely reused license texts, actions taken by a few individuals can adversely affect an entire community sharing the same license.
|
||||
|
||||
A court decision by a judge in a dispute between two parties arising out of a unique set of facts is one means by which that impact can occur. The judge, in all likelihood, will not be well informed about open source or technology in general. The judge's rulings will be shaped by the arguments of lawyers for the parties who have incentives to advance legal arguments that may be in conflict with the values and norms of communities relying on the license at issue. The litigants themselves, including the litigant seeking to enforce the license, may not share those values and norms. The capacity of the court to look beyond the arguments presented by the litigants is very limited, and authentic representatives of the project communities using the license will have no meaningful opportunity to give their perspective.
|
||||
|
||||
If, as is therefore likely, license-enforcement litigation produces a bad decision with a large community impact, the license-using community may then be stuck with that decision with few good options to remedy the situation. In many cases, there will be no easy path for a project to migrate to a different license, including a new version of the litigated license that attempts to correct against the court decision. There may be no license steward, or the license may not facilitate downstream upgradeability. Even if there is a license steward, there is generally strong social pressure in free and open source software (FOSS) to avoid license revision.
|
||||
|
||||
Test case litigation would not be immune to these kinds of problems; their drawbacks are amplified in the open source setting. For one thing, a test case might be brought by supporters of a license interpretation that is disfavored in the relevant license-using community—let's call this a "bad" test case litigant. Even if we suppose that the test case litigant's policy objectives reflect a real consensus in the license-using community—a "good" test case litigant—the test case strategy could backfire. The case might result in a ruling that is the opposite of what the test case litigant sought. Or the test case litigant might win on the facts, but in the process, the court might issue one or more rulings framed differently from what the test case litigant hoped for, perhaps having unexpected negative consequences for license interpretation or imposing undesirable new burdens on license compliance. The court might also dispose of the case in some procedural manner that could have a negative impact on the license-using community.
|
||||
|
||||
A more fundamental problem is that we really cannot know whether a given test case litigant is "good" or "bad" because of the complex and diverse nature of views on license interpretation across open source project communities. For example, an organization that is generally trusted in the community may be tempted to use test case litigation to promote highly restrictive or literalist interpretations of a license that are out of step with prevailing community views or practices.
|
||||
|
||||
Rather than pursuing open source license enforcement policy through test case litigation, we should first fully explore the use of community-based governance approaches to promote appropriate license interpretations and compliance expectations. This would be especially helpful in signaling that restrictive or illiberal license interpretations, advanced in litigation by parties motivated by private gain, have no basis of support in the larger community that shares that license text. For example, we can document and publicize license interpretations that are widely accepted in the community, expanding on work already done by some license stewards. We can also promote more liberal and modern interpretations of widely used licenses that were drafted in a different technological context, while still upholding their underlying policies, with the aim of making compliance clearer, fairer, and easier. Finally, we should consider adopting more frequent upgrade cycles for popular licenses using public and transparent license-revision processes.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/test-cases-open-source-licenses
|
||||
|
||||
作者:[Richard Fontana][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/fontana
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/law_legal_gavel_court.jpg?itok=tc27pzjI (A gavel.)
|
||||
[2]: https://www.oyez.org/cases/1850-1900/163us537
|
||||
[3]: https://meshedinsights.com/2015/12/21/faq-license/
|
||||
[4]: https://opensource.com/law/16/11/licenses-are-shared-resources
|
||||
[5]: https://opensource.com/article/19/2/top-foss-legal-developments
|
||||
[6]: http://gpl-violations.org/
|
||||
[7]: https://en.wikipedia.org/wiki/Free_Software_Foundation,_Inc._v._Cisco_Systems,_Inc.
|
||||
[8]: https://en.wikipedia.org/wiki/BusyBox#GPL_lawsuits
|
||||
[9]: https://opensource.com/article/17/8/patrick-mchardy-and-copyright-profiteering
|
||||
[10]: https://sfconservancy.org/news/2019/apr/02/vmware-no-appeal/
|
||||
[11]: https://sfconservancy.org/copyleft-compliance/vmware-lawsuit-faq.html
|
@ -1,138 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (stevenzdg988)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (6 best practices for managing Git repos)
|
||||
[#]: via: (https://opensource.com/article/20/7/git-repos-best-practices)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
6 best practices for managing Git repos
|
||||
======
|
||||
Resist the urge to add things in Git that will make it harder to manage;
|
||||
here's what to do instead.
|
||||
![Working from home at a laptop][1]
|
||||
|
||||
Having access to source code makes it possible to analyze the security and safety of applications. But if nobody actually looks at the code, the issues won’t get caught, and even when people are actively looking at code, there’s usually quite a lot to look at. Fortunately, GitHub has an active security team, and recently, they [revealed a Trojan that had been committed into several Git repositories][2], having snuck past even the repo owners. While we can’t control how other people manage their own repositories, we can learn from their mistakes. To that end, this article reviews some of the best practices when it comes to adding files to your own repositories.
|
||||
|
||||
### Know your repo
|
||||
|
||||
![Git repository terminal][3]
|
||||
|
||||
This is arguably Rule Zero for a secure Git repository. As a project maintainer, whether you started it yourself or you’ve adopted it from someone else, it’s your job to know the contents of your own repository. You might not have a memorized list of every file in your codebase, but you need to know the basic components of what you’re managing. Should a stray file appear after a few dozen merges, you’ll be able to spot it easily because you won’t know what it’s for, and you’ll need to inspect it to refresh your memory. When that happens, review the file and make sure you understand exactly why it’s necessary.
|
||||
|
||||
### Ban binary blobs
|
||||
|
||||
![Git binary check command in terminal][4]
|
||||
|
||||
Git is meant for text, whether it’s C or Python or Java written in plain text, or JSON, YAML, XML, Markdown, HTML, or something similar. Git isn’t ideal for binary files.
|
||||
|
||||
It’s the difference between this:
|
||||
|
||||
|
||||
```
|
||||
$ cat hello.txt
|
||||
This is plain text.
|
||||
It's readable by humans and machines alike.
|
||||
Git knows how to version this.
|
||||
|
||||
$ git diff hello.txt
|
||||
diff --git a/hello.txt b/hello.txt
|
||||
index f227cc3..0d85b44 100644
|
||||
\--- a/hello.txt
|
||||
+++ b/hello.txt
|
||||
@@ -1,2 +1,3 @@
|
||||
This is plain text.
|
||||
+It's readable by humans and machines alike.
|
||||
Git knows how to version this.
|
||||
```
|
||||
|
||||
and this:
|
||||
|
||||
|
||||
```
|
||||
$ git diff pixel.png
|
||||
diff --git a/pixel.png b/pixel.png
|
||||
index 563235a..7aab7bc 100644
|
||||
Binary files a/pixel.png and b/pixel.png differ
|
||||
|
||||
$ cat pixel.png
|
||||
<EFBFBD>PNG
|
||||
▒
|
||||
IHDR7n<EFBFBD>$gAMA<4D><41>
|
||||
<20>abKGD݊<44>tIME<4D>
|
||||
|
||||
-2R<32><52>
|
||||
IDA<EFBFBD>c`<60>!<21>3%tEXtdate:create2020-06-11T11:45:04+12:00<30><30>r.%tEXtdate:modify2020-06-11T11:45:04+12:00<30><30>ʒIEND<4E>B`<60>
|
||||
```
|
||||
|
||||
The data in a binary file can’t be parsed in the same way plain text can be parsed, so if anything is changed in a binary file, the whole thing must be rewritten. The only difference between one version and the other is everything, which adds up quickly.
|
||||
|
||||
Worse still, binary data can’t be reasonably audited by you, the Git repository maintainer. That’s a violation of Rule Zero: know what’s in your repository.
|
||||
|
||||
In addition to the usual [POSIX][5] tools, you can detect binaries using `git diff`. When you try to diff a binary file using the `--numstat` option, Git returns a null result:
|
||||
|
||||
|
||||
```
|
||||
$ git diff --numstat /dev/null pixel.png | tee
|
||||
\- - /dev/null => pixel.png
|
||||
$ git diff --numstat /dev/null file.txt | tee
|
||||
5788 0 /dev/null => list.txt
|
||||
```
|
||||
|
||||
If you’re considering committing binary blobs to your repository, stop and think about it first. If it’s binary, it was generated by something. Is there a good reason not to generate them at build time instead of committing them to your repo? Should you decide it does make sense to commit binary data, make sure you identify, in a README file or similar, where the binary files are, why they’re binary, and what the protocol is for updating them. Updates must be performed sparingly, because, for every change you commit to a binary blob, the storage space for that blob effectively doubles.
|
||||
|
||||
### Keep third-party libraries third-party
|
||||
|
||||
Third-party libraries are no exception to this rule. While it’s one of the many benefits of open source that you can freely re-use and re-distribute code you didn’t write, there are many good reasons not to house a third-party library in your own repository. First of all, you can’t exactly vouch for a third party, unless you’ve reviewed all of its code (and future merges) yourself. Secondly, when you copy third party libraries into your Git repo, it splinters focus away from the true upstream source. Someone confident in the library is technically only confident in the master copy of the library, not in a copy lying around in a random repo. If you need to lock into a specific version of a library, either provide developers with a reasonable URL the release your project needs or else use [Git Submodule][6].
|
||||
|
||||
### Resist a blind git add
|
||||
|
||||
![Git manual add command in terminal][7]
|
||||
|
||||
If your project is compiled, resist the urge to use `git add .` (where `.` is either the current directory or the path to a specific folder) as an easy way to add anything and everything new. This is especially important if you’re not manually compiling your project, but are using an IDE to manage your project for you. It can be extremely difficult to track what’s gotten added to your repository when an IDE manages your project, so it’s important to only add what you’ve actually written and not any new object that pops up in your project folder.
|
||||
|
||||
If you do use `git add .`, review what’s in staging before you push. If you see an unfamiliar object in your project folder when you do a `git status`, find out where it came from and why it’s still in your project directory after you’ve run a `make clean` or equivalent command. It’s a rare build artifact that won’t regenerate during compilation, so think twice before committing it.
|
||||
|
||||
### Use Git ignore
|
||||
|
||||
![Git ignore command in terminal][8]
|
||||
|
||||
Many of the conveniences built for programmers are also very noisy. The typical project directory for any project, programming, or artistic or otherwise, is littered with hidden files, metadata, and leftover artifacts. You can try to ignore these objects, but the more noise there is in your `git status`, the more likely you are to miss something.
|
||||
|
||||
You can Git filter out this noise for you by maintaining a good gitignore file. Because that’s a common requirement for anyone using Git, there are a few starter gitignore files available. [Github.com/github/gitignore][9] offers several purpose-built gitignore files you can download and place into your own project, and [Gitlab.com][10] integrated gitignore templates into the repo creation workflow several years ago. Use these to help you build a reasonable gitignore policy for your project, and stick to it.
|
||||
|
||||
### Review merge requests
|
||||
|
||||
![Git merge request][11]
|
||||
|
||||
When you get a merge or pull request or a patch file through email, don’t just test it to make sure it works. It’s your job to read new code coming into your codebase and to understand how it produces the result it does. If you disagree with the implementation, or worse, you don’t comprehend the implementation, send a message back to the person submitting it and ask for clarification. It’s not a social faux pas to question code looking to become a permanent fixture in your repository, but it’s a breach of your social contract with your users to not know what you merge into the code they’ll be using.
|
||||
|
||||
### Git responsible
|
||||
|
||||
Good software security in open source is a community effort. Don’t encourage poor Git practices in your repositories, and don’t overlook a security threat in repositories you clone. Git is powerful, but it’s still just a computer program, so be the human in the equation and keep everyone safe.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/7/git-repos-best-practices
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[校对者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/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||
[2]: https://securitylab.github.com/research/octopus-scanner-malware-open-source-supply-chain/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/git_repo.png (Git repository )
|
||||
[4]: https://opensource.com/sites/default/files/uploads/git-binary-check.jpg (Git binary check)
|
||||
[5]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[6]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
[7]: https://opensource.com/sites/default/files/uploads/git-cola-manual-add.jpg (Git manual add)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/git-ignore.jpg (Git ignore)
|
||||
[9]: https://github.com/github/gitignore
|
||||
[10]: https://about.gitlab.com/releases/2016/05/22/gitlab-8-8-released
|
||||
[11]: https://opensource.com/sites/default/files/uploads/git_merge_request.png (Git merge request)
|
@ -0,0 +1,180 @@
|
||||
[#]: subject: (3 open source tools for producing video tutorials)
|
||||
[#]: via: (https://opensource.com/article/21/3/video-open-source-tools)
|
||||
[#]: author: (Abe Kazemzadeh https://opensource.com/users/abecode)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
3 open source tools for producing video tutorials
|
||||
======
|
||||
Use OBS, OpenShot, and Audacity to create videos to teach your learners.
|
||||
![Person reading a book and digital copy][1]
|
||||
|
||||
I've learned that video tutorials are a great way to teach my students, and open source tools have helped me take my video-production skills to the next level. This article will explain how to get started and add artfulness and creativity to your video tutorial projects.
|
||||
|
||||
I'll describe an end-to-end workflow for making video tutorials using open source tools for each subtask. For the purposes of this tutorial, making a video is the "task," and the various steps to make the video are the "subtasks." Those subtasks are video screen capture, video recording, video editing, audio recording, and effort estimation. Other tools include hardware such as cameras and microphones. My workflow also includes effort estimation as a subtask, but it's more of a general skill that parallels the idea of effort estimation when developing software.
|
||||
|
||||
My workflow involves recording the bulk of the video content as screen capture. I record supporting video material (known as B-roll) using a smartphone, as it is a cheap, ubiquitous video camera. Then I edit the materials together into shot sequences using a video editor.
|
||||
|
||||
### Advantages of video tutorials
|
||||
|
||||
There are many reasons to record video tutorials. Some people prefer learning with video than with text like web pages and manuals. This preference may be partly generational—my students tend to prefer (or at least appreciate) the video option.
|
||||
|
||||
Some modalities, like graphical user interfaces (GUIs), are easier to demonstrate with video. Video tutorials also work well for documenting open source software. Showing a convenient, standard workflow for producing software demonstration videos makes it easier for users to learn new software.
|
||||
|
||||
Teaching people how to make videos can help increase the number of people participating in open source software. Enabling users to record themselves using software helps them share their knowledge. Teaching people how to do basic screen capture is a good way to make it easier for users to file bug reports on open source software.
|
||||
|
||||
Educators are increasingly turning to tutorial videos as a way to deliver course content asynchronously. The most direct way to transition to an online classroom is to lecture over a videoconference system. Another option is the flipped classroom, which "flips" the traditional teaching method (i.e., in-class teaching followed by independent homework) by having students watch a recorded lecture on their own at home and using classroom time as a live, synchronous, interactive session for doing independent and project work. While video technologies have been evolving in the classroom for some time, the Covid-19 pandemic strongly motivated many educators, like my colleagues at the University of St. Thomas and me, to adopt video techniques when Covid-19 forced schools to close.
|
||||
|
||||
Previously, I worked at the University of Southern California Annenberg School of Communications and Journalism, which offered a project and an app to help citizen journalists produce higher-quality video. (A citizen journalist is not a professional journalist but uses their proximity to current events to document and share their experiences). Similarly, this article aims to help you produce artful, quality video tutorials even if you are not a professional videographer.
|
||||
|
||||
### Screen capture
|
||||
|
||||
Screen capture is the first subtask in making a video tutorial. I use the [Open Broadcaster Software][2] (OBS) suite. OBS started as a way to stream video games and has evolved into a general-purpose tool for video recording and live streaming. It is programmed using Qt, which allows it to run on different operating systems. OBS can capture content as a video file or as a live stream, but I use it to capture to a video file for creating video tutorials.
|
||||
|
||||
Screen capture is the natural starting place for creating things like a video tutorial for a piece of software. Still, OBS is also useful for tutorials that use physical objects, like electronics or woodworking. A simple use is to record a presentation, but it also supports webcams and switching views to combine multiple webcams and screen captures. In fact, you can combine a simple presentation with a tutorial; in this case, the presentation slides provide structure to the other tutorial content.
|
||||
|
||||
![OBS][3]
|
||||
|
||||
The main abstractions in OBS are _scenes_, and these scenes are made up of _sources_. Sources are any basic video inputs, including webcams, entire desktop displays, individual applications, and static images. Scenes are composed of one or more sources. Any individual source can be a scene, but the power and creativity of scenes come from combining sources. An example of a composite scene with two sources would be a video-captured presentation with a "talking head"—i.e., a small window inset inside the larger display with the presenter's face recorded from a webcam. In some cases, the "talking head" can help the presenter engage with the audience better, and it serves as an extra channel of information to go along with the speech's audio.
|
||||
|
||||
This example implements a three-scene setup: one scene is the webcam, another scene is a full desktop display capture, and the third is the display capture with a webcam video inset.
|
||||
|
||||
If you are using a new OBS installation, you'll see a single blank scene called "Scene" without any sources in the lower-left corner. If you have an existing OBS installation, you can start fresh by creating a new scene collection from the **Scene Collection** menu.
|
||||
|
||||
Start by renaming the first scene **Face** by right-clicking the scene and selecting **Rename**. Then add the webcam as a source by selecting the **+** under **Sources**, choosing **Video Capture Device**, and clicking **Create New**. Set the name to **Webcam**, and click **OK**. This opens a screen where you can select and preview the webcam to make sure it's working (which is very useful if you have more than one webcam). After you select the webcam and click **OK**, you need to resize it. This can be done manually, but it is easier to right-click, select **Transform**, and select **Fit to Screen**.
|
||||
|
||||
An aside on naming scenes and sources: I like to make logical distinctions between scenes (which I give abstract names like Face) and sources (which I give concrete names like Webcam #1). A naming convention like this is useful when you have multiple scenes and sources. You can always rename scenes and sources by right-clicking and selecting **Rename**, so don't worry much about naming at this stage.
|
||||
|
||||
Add the second scene by clicking on the **+** button below the scenes area. Name it **Desktop** (or another name that describes this screen if you have a multiple-monitor setup). Then, under **Sources**, click **+** and select **Display Capture**. Select the display you want to capture (you only have one option if you have one monitor). Resize the video to fit the screen by right-clicking the **Transform** option. If you have one monitor, you should see a trippy, recursive view of the screen capture within a screen capture within a screen capture into infinity.
|
||||
|
||||
For the third scene, you can use a shortcut by duplicating the last scene and adding an inset webcam. To do this, right-click on the last scene, select **Duplicate**, and name it **Desktop with Talking Head** (or something similar). Then add another source for this scene by clicking **+** under **Sources** when this source is selected, selecting **Video Capture Device**, and choosing your webcam under **Add Existing** (instead of Create New, like before). Instead of fitting the webcam to the whole screen, this time, move and stretch the webcam so that it is in the lower-right corner. Now you'll have the desktop and the webcam in the same scene.
|
||||
|
||||
Now that the screen capture setup is finished, you can start making a basic software tutorial. Click **Start Recording** in the lower-right corner under **Controls**, record whatever you want to show in your tutorial, and use the scene selector to control what source you are recording. Changing scenes is like making a cut when editing a video, except it happens in real time while you are doing the tutorial. Because scene transitions in OBS happen in real time, this is more time-efficient than editing your video after the fact, so I recommend you try to do most of the scene transitions in OBS.
|
||||
|
||||
I mentioned above that OBS recursively captures itself in a way that can best be described as "trippy." Seeing OBS in the screen capture is fine if you are demonstrating how OBS works, but if you are making a tutorial about anything else, you will not want to capture the OBS application window. There are two ways to avoid this. First, if you have a second monitor, you can capture the desktop environment on one monitor and have OBS running on the other. Second, OBS allows you to capture from individual applications (rather than the entire desktop environment), so you can specify which application you want to show in your video.
|
||||
|
||||
When you are finished recording, click **Stop Recording**. To find the video you recorded, use the **File** menu and select **Show Recordings**.
|
||||
|
||||
OBS is a powerful tool with many more features than I have described. You can learn more about adding text labels, streaming, and other features in [_Linux video editing in real time with OBS Studio_][4] and [_How to livestream games like the pros with OBS_][5]. For specific questions and technical issues, OBS has a great [online user forum][6].
|
||||
|
||||
### Editing video and using B-roll footage
|
||||
|
||||
If you make mistakes when recording the screen capture or want to shorten the video, you'll need to edit it. You also might want to edit your video to make it more creative and artful. Adding creativity is also fun, and I believe having fun is necessary for sustaining your effort over time.
|
||||
|
||||
For this how-to, assume the screen capture video recorded in OBS is your main video content, and you have other video recorded to enhance the tutorial's creative quality. In cinema and television jargon, the main content is called "A-roll" footage ("roll" refers to when video was captured on rolls of film), and supporting video material is called "B-roll." B-roll footage includes the surrounding environment, hands and pointing gestures, heads nodding, and static images with logos or branding. Editing B-roll footage into the main A-roll footage can make your video look more professional and give it more creative depth.
|
||||
|
||||
A practical use of B-roll footage is to prevent _jump cuts_, which can happen when editing two similar video clips together. For example, imagine you make a mistake while doing your screen capture, and you want to cut out that part. However, this cut will leave an awkward gap—the jump cut—between the two clips after you remove the mistake. To remove that gap, put a short clip of B-roll material between the two parts. That B-roll shot placed to fill the cut is called a cutaway shot ( here, "shot" is used as a synonym of "clip," from the verb "shooting" a movie).
|
||||
|
||||
B-roll footage is also used to build _shot sequences_. Just like software engineers build design patterns from individual statements, functions, and classes, videographers build shot sequences from individual shots or clips. These shot sequences enhance the video's quality and creativity.
|
||||
|
||||
One of these, called the five-shot sequence, makes a good opening sequence to introduce your video tutorial. As the name suggests, it consists of five shots:
|
||||
|
||||
1. A close up of your hands
|
||||
2. A close up of your face
|
||||
3. A wide shot of the environment with you in it
|
||||
4. An over-the-shoulder shot showing the action as if your audience is watching over your shoulder
|
||||
5. A creative shot to capture an unusual perspective or something else the audience should know
|
||||
|
||||
|
||||
|
||||
This [example][7] shows what this looks like.
|
||||
|
||||
Showing pictures of yourself doing the activity can also help people better imagine doing it. There is a body of research about so-called "mirror neurons" that fire when observing another person's actions, especially hand movements. The five-shot sequence is also a pattern used by professional video journalists, so using it can give your video an appearance of professionalism.
|
||||
|
||||
In addition to these five B-roll shots, you may want to record yourself introducing the video. This could be done in OBS using the webcam, but recording it with a smartphone camera gives you options for different views and backgrounds.
|
||||
|
||||
#### Record your B-roll footage
|
||||
|
||||
You can use a smartphone camera to capture B-roll footage for the five-shot sequence. Not only are they ubiquitous, but smartphones' connectedness makes it easy to use [filesharing applications][8] to sync your video to your editing application on your computer.
|
||||
|
||||
You will need a tripod with a smartphone holder if you are working alone. This allows you to set up the recording without having to hold the phone in your hand. Some tripods come with remote controls that allow you to start and stop recording (search for "selfie tripod"), but this is just a convenience. Using the smartphone's forward-facing "selfie" camera can help you monitor that the camera is aimed properly.
|
||||
|
||||
There will be material at the beginning and end of the recorded clip that you need to edit out. I prefer to record the five clips as separate files, and sometimes I need multiple takes to get a shot correct. A movie-making "clapper" with a dry-erase board is a piece of optional equipment that can help you keep track of B-roll footage by allowing you to write information about the shot (e.g., "hand close up, take 2"). The clapper functionality—the bar on top that makes the clap noise—is useful for synchronizing audio. This helps if you have multiple cameras and microphones, but in this simple setup, the clapper's main utility is to make you look like a serious auteur.
|
||||
|
||||
Once you have recorded the five shots and any other material you want (e.g., a spoken introduction), copy or sync the video files to your desktop computer to begin editing.
|
||||
|
||||
#### Edit your video
|
||||
|
||||
I use [OpenShot][9], an open source video editor. Like OBS, it is programmed in Qt, so it runs on a variety of operating systems.
|
||||
|
||||
![Openshot][10]
|
||||
|
||||
_Tracks_ are OpenShot's main abstraction, and tracks can be made up of clips of individual _project files_, including video, audio, and images.
|
||||
|
||||
Start with the five clips from the five-shot sequence and the video captured from OBS. To import the clips into OpenShot, drag-and-drop them into the project files area. These project files are the raw material that go into the tracks—you can think of this collection as a staging area similar to a chef collecting ingredients before cooking a dish. The clips don't need to be edited: you can edit them using OpenShot when you add them into the final video.
|
||||
|
||||
After adding the five clips to the project files area, drag and drop the first clip to the top track. The tracks are like layers, and the higher-numbered tracks are in front of the lower-numbered tracks, so the top track should be track four or five. Ideally, each shot of the five-shot sequence will be about two or three seconds long; if they are longer, cut out the parts you don't want.
|
||||
|
||||
To cut the clip, move the cursor (the blue marker on the timeline) to the place you want to cut. Right-click on the blue cursor, select **Slice All**, and then select which side you want to keep. Once you trim the clip, add the next clip to the same track, and give a bit of space after the first clip. Trim the second clip like you did the first one. After you trim both clips, slide the first clip all the way to the left to time zero on the timeline. Then, drag the second clip over the first clip so that the beginning of the second clip overlaps the end of the first clip. When you release the mouse, you'll see a blue area where the clips overlap. This blue area is a transition that OpenShot adds automatically when the clips overlap. If the overlap is not quite right, the easiest way to fix it is to separate the clips, delete the transition (select the blue area and hit the **Delete** key), and then try again. OpenShot automatically adds a transition where the shots overlap, but it won't automatically delete it when they are separated. Continue by trimming and overlapping the remaining shots of the five-shot sequence.
|
||||
|
||||
You can do a lot more with OpenShot transitions, and [OpenShot's user guide][11] can help you learn about the options.
|
||||
|
||||
Finally, add the screen capture video clip from OBS. If necessary, you can edit it in the same way, by moving the blue cursor in the timeline to where you want to trim, right-clicking the blue cursor, and selecting **Slice All**. If you need to keep both sides of the slice—for example, if you want to cut out a mistake in the middle of the video—make a slice on either side of the mistake, keep the sides, and delete the middle. This may result in a jump shot; if so, insert a clip of B-roll footage between them. I've found that a closeup shot of hands on the keyboard or an over-the-shoulder shot are good cutaways for this purpose.
|
||||
|
||||
This example didn't use them, but the other tracks in OpenShot can be used to add parallel video tracks (e.g., a webcam, screen capture in OBS, or material recorded with a separate camera) or to add extra audio, like background music. I've found that using a single track is most convenient for combining clips for the five-shot sequence, and using multiple tracks is best for adding a separate audio track (e.g., music that will be played throughout the whole video) or when multiple views of the same action are captured separately.
|
||||
|
||||
This example used OBS to capture two sources, the webcam and the screen capture, but it was all done with a single device, the computer. If you have video from another device, like a standalone camera, you might want to use two parallel tracks to combine the camera video and the screen capture. However, because OBS can capture multiple sources on one screen in real time, another option would be to use a second webcam instead of a standalone video camera. Doing all the recording in OBS and switching scenes while doing the screen capture would enable you to avoid after-the-fact editing.
|
||||
|
||||
### Recording and editing audio
|
||||
|
||||
For the audio component of the recording, your computer's built-in microphone might be fine. It is also simpler and saves money. If your computer's built-in microphone is not good enough, you may want to invest in a dedicated microphone.
|
||||
|
||||
Even a high-quality microphone can produce poor audio quality if you don't take some care when recording it. One issue is recording in different acoustic environments: If you record one part of the video in a completely silent environment and another part in an environment with background noise (like fans, air conditioners, or other appliances), the difference in acoustic backgrounds will be very apparent.
|
||||
|
||||
You might think it is better to have no background noise. While this might be true for recording music, having some ambient room noise can even out the differences between clips recorded in different acoustic environments. To do this, record about a minute of the ambient sound in the target environment. You might not end up needing it, but it is easier to make a brief audio recording at the outset if you anticipate recording in different environments.
|
||||
|
||||
Audio compression is another technique that can help you fix volume issues if they arise. Compression helps reduce the differences between quiet and loud audio, and it has settings to not amplify background noise. [Audacity][12] is a useful open source audio tool that includes compression.
|
||||
|
||||
![Multitrack suggestion][13]
|
||||
|
||||
Using a clapper is helpful if you plan to edit multiple simultaneous audio recordings together. You can use the sharp peak in audio volume from the clapper to synchronize different tracks because the clapping noise makes it easier to line up the different recordings.
|
||||
|
||||
### Estimation and planning
|
||||
|
||||
A related issue is estimating the time and effort required to finish tasks and projects. This can be hard for many reasons, but there are some general rules of thumb that can help you estimate the time it will take to complete a video production project.
|
||||
|
||||
First, as I noted, it is easier to use OBS scene transitions to switch views while recording than to edit scene transitions after the fact. If you can capture transitions while recording, you have one less task to do while editing.
|
||||
|
||||
Another rule of thumb is that as the amount of recorded material increases, it takes more time and effort in general. For one, recording more material takes more time. Also, more material increases the overhead of organizing and editing it. Conversely and somewhat counterintuitively, given the same amount of raw material, a shorter final project will generally take more time and effort than a longer final project. When the amount of input is constant, it is harder to edit the content down to a shorter product than if you have less of a constraint on the final video's length.
|
||||
|
||||
Having a plan for your video tutorial will help you stay on track and not forget any topics. A plan can range from a set of bullet points to a mindmap to a full script. Not only will the plan help guide you when you start recording, it can also help after the video is done. One way to improve your video tutorial's usefulness is to have a video table of contents, where each topic includes the timestamp when it begins. If you have a plan for your video—whether it is bullet points or a script—you will already have the video's structure, and you can just add the timestamps. Many video-sharing sites have ways to start playing a video at a specific point. For example, YouTube allows you to add an anchor hashtag to the end of a video's URL (e.g., `youtube.com/videourl#t=1m30s` would start playback 90 seconds into the video). Providing a script with the video is also useful for deaf and hard-of-hearing viewers.
|
||||
|
||||
### Give it a try
|
||||
|
||||
One great thing about open source is that there are low barriers to trying new software. Since the software is free, the main costs of making a video tutorial are the hardware—a computer for screen capture and video editing and a smartphone to record the B-roll footage.
|
||||
|
||||
* * *
|
||||
|
||||
_Acknowledgments: When I started learning about video, I benefited greatly from help from colleagues,*friends, and acquaintances. The University of St. Thomas Center for Faculty Development sponsored this work financially and my colleague Eric Level at the University of St. Thomas gave me many ideas for using video in the classrooms where we teach. My former colleagues Melissa Loudon and Andrew Lih at USC Annenberg School of Communications and Journalism taught me about citizen journalism and the five-shot sequence. My friend Matthew Lynn is a visual effects expert who helped me with time estimation and room-tone issues. Finally, the audience in the 2020 Southern California Linux Expo (SCaLE 18x) Graphics track gave me many helpful suggestions, including the video table of contents._
|
||||
|
||||
A look behind the scenes of Dototot's The Hello World Program, a YouTube channel aimed at computer...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/video-open-source-tools
|
||||
|
||||
作者:[Abe Kazemzadeh][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/abecode
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/read_book_guide_tutorial_teacher_student_apaper.png?itok=_GOufk6N (Person reading a book and digital copy)
|
||||
[2]: https://obsproject.com/
|
||||
[3]: https://opensource.com/sites/default/files/obs-full.jpg (OBS)
|
||||
[4]: https://opensource.com/life/15/12/real-time-linux-video-editing-with-obs-studio
|
||||
[5]: https://opensource.com/article/17/7/obs-studio-pro-level-streaming
|
||||
[6]: https://obsproject.com/forum/
|
||||
[7]: https://www.youtube.com/watch?v=WnDD_59Lcas
|
||||
[8]: https://opensource.com/alternatives/dropbox
|
||||
[9]: https://www.openshot.org/
|
||||
[10]: https://opensource.com/sites/default/files/openshot-full.jpg (Openshot)
|
||||
[11]: https://www.openshot.org/user-guide/
|
||||
[12]: https://www.audacityteam.org/
|
||||
[13]: https://opensource.com/sites/default/files/screenshot_20210303_073557.png (Multitrack suggestion)
|
@ -0,0 +1,212 @@
|
||||
[#]: subject: (Troubleshoot WiFi problems with Go and a Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi)
|
||||
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Troubleshoot WiFi problems with Go and a Raspberry Pi
|
||||
======
|
||||
Build a WiFi scanner for fun.
|
||||
![Selfcare, drinking tea on the porch][1]
|
||||
|
||||
Last summer, my wife and I sold everything we owned and moved with our two dogs to Hawaii. It's been everything we thought it would be: beautiful sun, warm sand, cool surf—you name it. We've also run into some things we didn't expect: WiFi problems.
|
||||
|
||||
Now, that's not a Hawaii problem. It's limited to the apartment we are renting. We are living in a single-room studio apartment attached to our landlord's apartment. Part of the rent includes free internet! YAY! However, said internet is provided by the WiFi router in the landlord's apartment. BOO!
|
||||
|
||||
In all honesty, it works OK. Ish. OK, it doesn't work well, and I'm not sure why. The router is literally on the other side of the wall, but our signal is spotty, and we have some trouble staying connected. Back home, our WiFi router's signal crossed through many walls and some floors. Certainly, it covered an area larger than the 600 sq. foot apartment we live in!
|
||||
|
||||
What does a good techie do in such a situation? Why, investigate, of course!
|
||||
|
||||
Luckily the "everything we own" that we sold before moving here did not include our Raspberry Pi Zero W. So small! So portable! Of course, I took it to Hawaii with me. My bright idea was to use the Pi and its built-in WiFi adapter, write a little program in Go to measure the WiFi signal received from the router, and display that output. I'm going to make it super simple, quick, and dirty and worry later about making it better. I just want to know what's up with the WiFi, dang it!
|
||||
|
||||
Hunting around on Google for a minute turns up a relatively useful Go package for working with WiFi, [mdlayher/wifi][2]. Sounds promising!
|
||||
|
||||
### Getting information about the WiFi interfaces
|
||||
|
||||
My plan is to query the WiFi interface statistics and return the signal strength, so I need to find the interfaces on the device. Luckily the mdlayher/wifi package has a method to query them, so I can do that by creating a file named `main.go`:
|
||||
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mdlayher/wifi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
c, err := wifi.New()
|
||||
defer c.Close()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
interfaces, err := c.Interfaces()
|
||||
|
||||
for _, x := range interfaces {
|
||||
fmt.Printf("%+v\n", x)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
So, what's going on here? After importing it, the mdlayher/wifi module can be used in the main function to create a new Client (type `*Client`). The new client (named `c`) can then get a list of the interfaces on the system with `c.Interfaces()`. Then it can loop over the slice of Interface pointers and print information about them.
|
||||
|
||||
By adding "+" to `%+v`, it prints the names of the fields in the `*Interface` struct, too, which helps me identify what I'm seeing without having to refer back to documentation.
|
||||
|
||||
Running the code above provides a list of the WiFi interfaces on my machine:
|
||||
|
||||
|
||||
```
|
||||
&{Index:0 Name: HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:3 Type:P2P device Frequency:0}
|
||||
&{Index:3 Name:wlp2s0 HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:1 Type:station Frequency:2412}
|
||||
```
|
||||
|
||||
Note that the MAC address, `HardwareAddr`, is the same for both lines, meaning this is the same physical hardware. This is confirmed by `PHY: 0`. The Go [wifi module's docs][3] note that `PHY` is the physical device to which the interface belongs.
|
||||
|
||||
The first interface has no name and is `TYPE:P2P`. The second, named `wpl2s0` is `TYPE:Station`. The wifi module documentation lists the [different types of interfaces][4] and describes what they are. According to the docs, the "P2P" type indicates "an interface is a device within a peer-to-peer client network." I believe, and please correct me in the comments if I'm wrong, that this interface is for [WiFi Direct][5], a standard for allowing two WiFi devices to connect without an intermediate access point.
|
||||
|
||||
The "Station" type indicates "an interface is part of a managed basic service set (BSS) of client devices with a controlling access point." This is the standard function for a wireless device that most people are used to—as a client connected to an access point. This is the interface that matters for testing the quality of the WiFi.
|
||||
|
||||
### Getting the Station information from the interface
|
||||
|
||||
Using this information, I can update the loop over the interfaces to retrieve the information I'm looking for:
|
||||
|
||||
|
||||
```
|
||||
for _, x := range interfaces {
|
||||
if x.Type == wifi.InterfaceTypeStation {
|
||||
// c.StationInfo(x) returns a slice of all
|
||||
// the staton information about the interface
|
||||
info, err := c.StationInfo(x)
|
||||
if err != nil {
|
||||
fmt.Printf("Station err: %s\n", err)
|
||||
}
|
||||
for _, x := range info {
|
||||
fmt.Printf("%+v\n", x)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
First, it checks that `x.Type` (the Interface type) is `wifi.InterfaceTypeStation`—a Station interface (that's the only type that matters for this exercise). This is an unfortunate naming collision—the interface "type" is not a "type" in the Golang sense. In fact, what I'm working on here is a Go `type` named `InterfaceType` to represent the type of interface. Whew, that took me a minute to figure out!
|
||||
|
||||
So, assuming the interface is of the _correct_ type, the station information can be retrieved with `c.StationInfo(x)` using the client `StationInfo()` method to get the info about the interface, `x`.
|
||||
|
||||
This returns a slice of `*StationInfo` pointers. I'm not sure quite why there's a slice. Perhaps the interface can have multiple StationInfo responses? In any case, I can loop over the slice and use the same `+%v` trick to print the keys and values for the StationInfo struct.
|
||||
|
||||
Running the above returns:
|
||||
|
||||
|
||||
```
|
||||
`&{HardwareAddr:70:5a:9e:71:2e:d4 Connected:17m10s Inactive:1.579s ReceivedBytes:2458563 TransmittedBytes:1295562 ReceivedPackets:6355 TransmittedPackets:6135 ReceiveBitrate:2000000 TransmitBitrate:43300000 Signal:-79 TransmitRetries:2306 TransmitFailed:4 BeaconLoss:2}`
|
||||
```
|
||||
|
||||
The thing I'm interested in is the "Signal" and possibly "TransmitFailed" and "BeaconLoss." The signal is reported in units of dBm (or decibel-milliwatts).
|
||||
|
||||
#### A quick aside: How to read WiFi dBm
|
||||
|
||||
According to [MetaGeek][6]:
|
||||
|
||||
* –30 is the best possible signal strength—it's neither realistic nor necessary
|
||||
* –67 is very good; it's for apps that need reliable packet delivery, like streaming media
|
||||
* –70 is fair, the minimum reliable packet delivery, fine for email and web
|
||||
* –80 is poor, absolute basic connectivity, unreliable packet delivery
|
||||
* –90 is unusable, approaching the "noise floor"
|
||||
|
||||
|
||||
|
||||
_Note that dBm is logarithmic scale: -60 is 1,000x lower than -30_
|
||||
|
||||
### Making this a real "scanner"
|
||||
|
||||
So, looking at my signal from above: –79. YIKES, not good. But that single result is not especially helpful. That's just a point-in-time reference and only valid for the particular physical space where the WiFi network adapter was at that instant. What would be more useful would be a continuous reading, making it possible to see how the signal changes as the Raspberry Pi moves around. The main function can be tweaked again to accomplish this:
|
||||
|
||||
|
||||
```
|
||||
var i *wifi.Interface
|
||||
|
||||
for _, x := range interfaces {
|
||||
if x.Type == wifi.InterfaceTypeStation {
|
||||
// Loop through the interfaces, and assign the station
|
||||
// to var x
|
||||
// We could hardcode the station by name, or index,
|
||||
// or hardwareaddr, but this is more portable, if less efficient
|
||||
i = x
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
// c.StationInfo(x) returns a slice of all
|
||||
// the staton information about the interface
|
||||
info, err := c.StationInfo(i)
|
||||
if err != nil {
|
||||
fmt.Printf("Station err: %s\n", err)
|
||||
}
|
||||
|
||||
for _, x := range info {
|
||||
fmt.Printf("Signal: %d\n", x.Signal)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
```
|
||||
|
||||
First, I name a variable `i` of type `*wifi.Interface`. Since it's outside the loop, I can use it to store the interface information. Any variable created inside the loop is inaccessible outside the scope of that loop.
|
||||
|
||||
Then, I can break the loop into two. The first loop ranges over the interfaces returned by `c.Interfaces()`, and if that interface is a Station type, it stores that in the `i` variable created earlier and breaks out of the loop.
|
||||
|
||||
The second loop is an infinite loop, so it'll just run over and over until I hit **Ctrl**+**C** to end the program. This loop takes that interface information and retrieves the station information, as before, and prints out the signal information. Then it sleeps for one second and runs again, printing the signal information over and over until I quit.
|
||||
|
||||
So, running that:
|
||||
|
||||
|
||||
```
|
||||
[chris@marvin wifi-monitor]$ go run main.go
|
||||
Signal: -81
|
||||
Signal: -81
|
||||
Signal: -79
|
||||
Signal: -81
|
||||
```
|
||||
|
||||
Oof. Not good.
|
||||
|
||||
### Mapping the apartment
|
||||
|
||||
This information is good to know, at least. With an attached screen or E Ink display and a battery (or a looooong extension cable), I can walk the Pi around the apartment and map out where the dead spots are.
|
||||
|
||||
Spoiler alert: With the landlord's access point in the apartment next door, the big dead spot for me is a cone shape emanating from the refrigerator in the studio apartment's kitchen area… the refrigerator that shares a wall with the landlord's apartment!
|
||||
|
||||
I think in Dungeons and Dragons lingo, this is a "Cone of Silence." Or at least a "Cone of Poor Internet."
|
||||
|
||||
Anyway, this code can be compiled directly on the Raspberry Pi with `go build -o wifi_scanner`, and the resulting binary, `wifi_scanner`, can be shared with any other ARM devices (of the same version). Alternatively, it can be compiled on a regular system with the right libraries for ARM devices.
|
||||
|
||||
Happy Pi scanning! May your WiFi router not be behind your refrigerator! You can find the code used for this project in [my GitHub repo][7].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi
|
||||
|
||||
作者:[Chris Collins][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/clcollins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_selfcare_wfh_porch_520.png?itok=2qXG0T7u (Selfcare, drinking tea on the porch)
|
||||
[2]: https://github.com/mdlayher/wifi
|
||||
[3]: https://godoc.org/github.com/mdlayher/wifi#Interface
|
||||
[4]: https://godoc.org/github.com/mdlayher/wifi#InterfaceType
|
||||
[5]: https://en.wikipedia.org/wiki/Wi-Fi_Direct
|
||||
[6]: https://www.metageek.com/training/resources/wifi-signal-strength-basics.html
|
||||
[7]: https://github.com/clcollins/goPiWiFi
|
@ -0,0 +1,117 @@
|
||||
[#]: subject: (Understanding file names and directories in FreeDOS)
|
||||
[#]: via: (https://opensource.com/article/21/3/files-freedos)
|
||||
[#]: author: (Kevin O'Brien https://opensource.com/users/ahuka)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Understanding file names and directories in FreeDOS
|
||||
======
|
||||
Learn how to create, edit, and name files in FreeDOS.
|
||||
![Files in a folder][1]
|
||||
|
||||
The open source operating system [FreeDOS][2] is a tried-and-true project that helps users play retro games, update firmware, run outdated but beloved applications, and study operating system design. FreeDOS offers insights into the history of personal computing (because it implements the de facto operating system of the early '80s) but in a modern context. In this article, I'll use FreeDOS to explain how file names and extensions developed.
|
||||
|
||||
### Understanding file names and ASCII text
|
||||
|
||||
FreeDOS file names follow what is called the _8.3 convention_. This means that all FreeDOS file names have two parts that contain up to eight and three characters, respectively. The first part is often referred to as the _file name_ (which can be a little confusing because the combination of the file name and the file extension is also called a file name). This part can have anywhere from one to eight characters in it. This is followed by the _extension_, which can have from zero to three characters. These two parts are separated by a dot.
|
||||
|
||||
File names can use any letter of the alphabet or any numeral. Many of the other characters found on a keyboard are also allowed, but not all of them. That's because many of these other characters have been assigned a special use in FreeDOS. Some of the characters that can appear in a FreeDOS file name are:
|
||||
|
||||
|
||||
```
|
||||
`~ ! @ # $ % ^ & ( ) _ - { } ``
|
||||
```
|
||||
|
||||
There are also characters in the extended [ASCII][3] set that can be used, such as <20>.
|
||||
|
||||
Characters with a special meaning in FreeDOS that, therefore, cannot be used in file names include:
|
||||
|
||||
|
||||
```
|
||||
`*/ + | \ = ? [ ] ; : " . < > ,`
|
||||
```
|
||||
|
||||
Also, you cannot use a space in a FreeDOS file name. The FreeDOS console [uses spaces to separate commands][4] from options and parameters.
|
||||
|
||||
FreeDOS is case _insensitive_, so it doesn't matter whether you use uppercase or lowercase letters. All letters are converted to uppercase, so your files end up with uppercase letters in the name, no matter what you do.
|
||||
|
||||
#### File extensions
|
||||
|
||||
A file in FreeDOS isn't required to have an extension, but file extensions do have some uses. Certain file extensions have built-in meanings in FreeDOS, such as:
|
||||
|
||||
* **EXE**: executable file
|
||||
* **COM**: command file
|
||||
* **SYS**: system file
|
||||
* **BAT**: batch file
|
||||
|
||||
|
||||
|
||||
Specific software programs use other extensions, or you can use them when you create a file. These extensions have no absolute file associations, so if you use a FreeDOS word processor, it doesn't matter what extension you use for your files. You could get creative and use extensions as part of your filing system if you want. For instance, you could name your memos using *.JAN, *.FEB, *.MAR, *.APR, and so on.
|
||||
|
||||
### Editing files
|
||||
|
||||
FreeDOS comes with the Edit application for quick and easy text editing. It's a simple editor with a menu bar along the top of the screen for easy access to all the usual functions (such as copy, paste, save, and so on.)
|
||||
|
||||
![Editing in FreeDOS][5]
|
||||
|
||||
(Kevin O'Brien, [CC BY-SA 4.0][6])
|
||||
|
||||
As you might expect, many other text editors are available, including the tiny but versatile [e3 editor][7]. You can find a good variety of [FreeDOS applications][8] on GitLab.
|
||||
|
||||
### Creating files
|
||||
|
||||
You can create empty files in FreeDOS using the `touch` command. This simple utility updates a file's modification time or creates a new file:
|
||||
|
||||
|
||||
```
|
||||
C:\>touch foo.txt
|
||||
C:\>dir
|
||||
FOO TXT 0 01-12-2021 10:00a
|
||||
```
|
||||
|
||||
You can also create a file directly from the FreeDOS console without using the Edit text editor. First, use the `copy` command to copy input in the console (`con` for short) into a new file object. Terminate input with **Ctrl**+**Z** followed by the **Return** or **Enter** key:
|
||||
|
||||
|
||||
```
|
||||
C:\>copy con test.txt
|
||||
con => test.txt
|
||||
This is a test file.
|
||||
^Z
|
||||
```
|
||||
|
||||
The **Ctrl**+**Z** character shows up in the console as `^Z`. It isn't copied to the file but serves as an End of File (EOF) delimiter. In other words, it tells FreeDOS when to stop copying. This is a neat trick for making quick notes or starting a simple document to work on later.
|
||||
|
||||
### Files and FreeDOS
|
||||
|
||||
FreeDOS is open source, free, and [easy to install][9]. Exploring how FreeDOS treats files can help you understand how computing has developed over the years, regardless of your usual operating system. Boot up FreeDOS and start exploring modern retro computing!
|
||||
|
||||
* * *
|
||||
|
||||
_Some of the information in this article was previously published in [DOS lesson 7: DOS filenames; ASCII][10] (CC BY-SA 4.0)._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/files-freedos
|
||||
|
||||
作者:[Kevin O'Brien][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/ahuka
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/files_documents_paper_folder.png?itok=eIJWac15 (Files in a folder)
|
||||
[2]: https://www.freedos.org/
|
||||
[3]: tmp.2sISc4Tp3G#ASCII
|
||||
[4]: https://opensource.com/article/21/2/set-your-path-freedos
|
||||
[5]: https://opensource.com/sites/default/files/uploads/freedos_2_files-edit.jpg (Editing in FreeDOS)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://opensource.com/article/20/12/e3-linux
|
||||
[8]: https://gitlab.com/FDOS/
|
||||
[9]: https://opensource.com/article/18/4/gentle-introduction-freedos
|
||||
[10]: https://www.ahuka.com/dos-lessons-for-self-study-purposes/dos-lesson-7-dos-filenames-ascii/
|
@ -0,0 +1,187 @@
|
||||
[#]: subject: (Linux Mint Cinnamon vs MATE vs Xfce: Which One Should You Use?)
|
||||
[#]: via: (https://itsfoss.com/linux-mint-cinnamon-mate-xfce/)
|
||||
[#]: author: (Dimitrios https://itsfoss.com/author/dimitrios/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Linux Mint Cinnamon vs MATE vs Xfce: Which One Should You Use?
|
||||
======
|
||||
|
||||
Linux Mint is undoubtedly [one of the best Linux distributions for beginners][1]. This is especially true for Windows users that walking their first steps to Linux world.
|
||||
|
||||
Since 2006, the year that Linux Mint made its first release, a selection of [tools][2] has been developed to enhance user experience. Furthermore, Linux Mint is based on Ubuntu, so you have a large community of users to seek help.
|
||||
|
||||
I am not going to discuss how good Linux Mint is. If you have already made your mind to [install Linux Mint][3], you probably get a little confused on the [download section][4] on its website.
|
||||
|
||||
It gives you three options to choose from: Cinnamon, MATE and Xfce. Confused? I’ll help you with that in this article.
|
||||
|
||||
![][5]
|
||||
|
||||
If you are absolutely new to Linux and have no idea about what the above things are, I recommend you to understand a bit on [what is a desktop environment in Linux][6]. And if you could spare some more minutes, read this excellent explanation on [what is Linux and why there are so many of Linux operating systems that look similar to each other][7].
|
||||
|
||||
With that information, you are ready to understand the difference between the various Linux Mint editions. If you are unsure which to choose, with this article I will help you to make a conscious choice.
|
||||
|
||||
### Which Linux Mint version should you choose?
|
||||
|
||||
![][8]
|
||||
|
||||
Briefly, the available choices are the following:
|
||||
|
||||
* **Cinnamon desktop:** A modern touch on traditional desktop
|
||||
* **MATE desktop:** A traditional looking desktop resembling the GNOME 2 era.
|
||||
* **Xfce desktop:** A popular lightweight desktop environment.
|
||||
|
||||
|
||||
|
||||
Let’s have a look at the Mint variants one by one.
|
||||
|
||||
#### Linux Mint Cinnamon edition
|
||||
|
||||
Cinnamon desktop is developed by Linux Mint team and clearly it is the flagship edition of Linux Mint.
|
||||
|
||||
Almost a decade back when the GNOME desktop opted for the unconventional UI with GNOME 3, Cinnamon development was started to keep the traditional looks of the desktop by forking some components of GNOME 2.
|
||||
|
||||
Many Linux users like Cinnamon for its similarity with Windows 7 like interface.
|
||||
|
||||
![Linux Mint Cinnamon desktop][9]
|
||||
|
||||
##### Performance and responsiveness
|
||||
|
||||
The cinnamon desktop performance has improved from the past releases but without an SSD you can feel a bit sluggish. The last time I used cinnamon desktop was in version 4.4.8, the RAM consumption right after boot was around 750mb. There is a huge improvement in the current version 4.8.6, reduced by 100mb after boot.
|
||||
|
||||
To get the best user experience, a dual-core CPU with 4 GB of RAM as a minimum should be considered.
|
||||
|
||||
![Linux Mint 20 Cinnamon idle system stats][10]
|
||||
|
||||
##### Pros
|
||||
|
||||
* Seamless switch from Windows
|
||||
* Pleasing aesthetics
|
||||
* Highly [customizable][11]
|
||||
|
||||
|
||||
|
||||
##### Cons
|
||||
|
||||
* May still not be ideal if you have a system with 2 GB RAM
|
||||
|
||||
|
||||
|
||||
**Bonus Tip**: If you prefer Debian instead of Ubuntu you have the option of [Linux Mint Debian Edition][12]. The main difference between LMDE and Debian with Cinnamon desktop is that LMDE ships the latest desktop environment to its repositories.
|
||||
|
||||
#### Linux Mint Mate edition
|
||||
|
||||
[MATE desktop environment][13] shares a similar story as it aims to maintain and support the GNOME 2 code base and applications. The Look and feel is very similar to GNOME 2.
|
||||
|
||||
In my opinion, the best implementation of MATE desktop is by far [Ubuntu MATE][14]. In Linux Mint you get a customized version of MATE desktop, which is in line with Cinnamon aesthetics and not to the traditional GNOME 2 set out.
|
||||
|
||||
![Screenshot of Linux Mint MATE desktop][15]
|
||||
|
||||
##### Performance and responsiveness
|
||||
|
||||
MATE desktop has a reputation of its lightweight nature and there is no doubt about that. Compared to Cinnamon desktop, the CPU usage always remains a bit lower, and this can be translated to a better battery life on a laptop.
|
||||
|
||||
Although it doesn’t feel as snappy as Xfce (in my opinion), but not to an extent to compromise user experience. RAM consumption starts under 500mb which is impressive for a feature rich desktop environment.
|
||||
|
||||
![Linux Mint 20 MATE idle system stats][16]
|
||||
|
||||
##### Pros
|
||||
|
||||
* Lightweight desktop without compromising on [features][17]
|
||||
* Enough [customization][18] potential
|
||||
|
||||
|
||||
|
||||
##### Cons
|
||||
|
||||
* Traditional looks may give you a dated feel
|
||||
|
||||
|
||||
|
||||
#### Linux Mint Xfce edition
|
||||
|
||||
XFCE project started in 1996 inspired by the [Common Desktop Environment][19] of UNIX. XFCE” stands for “[XForms][20] Common Environment”, but since it no longer uses the XForms toolkit, the name is spelled as “Xfce”.
|
||||
|
||||
It aims to be fast, lightweight and easy to use. Xfce is the flagship desktop of many popular Linux distributions like [Manjaro][21] and [MX Linux][22].
|
||||
|
||||
Linux Mint offers a polished Xfce desktop but can’t match the beauty of Cinnamon desktop even in a Dark theme.
|
||||
|
||||
![Linux Mint 20 Xfce desktop][23]
|
||||
|
||||
##### Performance and responsiveness
|
||||
|
||||
Xfce is the leanest desktop environment Linux Mint has to offer. By clicking the start menu, the settings control panel or exploring the bottom panel you will notice that this is a simple yet a flexible desktop environment.
|
||||
|
||||
Despite I find minimalism a positive attribute, Xfce is not an eye candy, leaving a more traditional taste. For some users a classic desktop environment is the one to go for.
|
||||
|
||||
At the first boot the ram usage is similar to MATE desktop but not quite as good. If your computer isn’t equipped with an SSD, Xfce desktop environment can resurrect your system.
|
||||
|
||||
![Linux Mint 20 Xfce idle system stats][24]
|
||||
|
||||
##### Pros
|
||||
|
||||
* Simple to use
|
||||
* Very lightweight – suitable for older hardware
|
||||
* Rock-solid stable
|
||||
|
||||
|
||||
|
||||
##### Cons
|
||||
|
||||
* Outdated look
|
||||
* May not have as much customization to offer in comparison to Cinnamon
|
||||
|
||||
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Since all these three desktop environments are based on GTK toolkit, the choice is purely a matter of taste. All of them are easy on system resources and perform well for a modest system with 4 GB RAM. Xfce and MATE can go a bit lower by supporting systems with as low as 2 GB RAM.
|
||||
|
||||
Linux Mint is not the only distribution that provides multiple choices. Distros like Manjaro, Fedora and [Ubuntu have various flavors][25] to choose from as well.
|
||||
|
||||
If you still cannot make your mind, I’ll say go with the default Cinnamon edition first and try to [use Linux Mint in a virtual box][26]. See if you like the look and feel. If not, you can test other variants in the same fashion. If you decide on the version, you can go on and [install it on your main system][3].
|
||||
|
||||
I hope I was able to help you with this article. If you still have questions or suggestions on this topic, please leave a comment below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/linux-mint-cinnamon-mate-xfce/
|
||||
|
||||
作者:[Dimitrios][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://itsfoss.com/best-linux-beginners/
|
||||
[2]: https://linuxmint-developer-guide.readthedocs.io/en/latest/mint-tools.html#
|
||||
[3]: https://itsfoss.com/install-linux-mint/
|
||||
[4]: https://linuxmint.com/download.php
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-version-options.png?resize=789%2C277&ssl=1
|
||||
[6]: https://itsfoss.com/what-is-desktop-environment/
|
||||
[7]: https://itsfoss.com/what-is-linux/
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/Linux-Mint-variants.jpg?resize=800%2C450&ssl=1
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-20.1-cinnamon.jpg?resize=800%2C500&ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/Linux-Mint-20-Cinnamon-ram-usage.png?resize=800%2C600&ssl=1
|
||||
[11]: https://itsfoss.com/customize-cinnamon-desktop/
|
||||
[12]: https://itsfoss.com/lmde-4-release/
|
||||
[13]: https://mate-desktop.org/
|
||||
[14]: https://itsfoss.com/ubuntu-mate-20-04-review/
|
||||
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/07/linux-mint-mate.jpg?resize=800%2C500&ssl=1
|
||||
[16]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/Linux-Mint-20-MATE-ram-usage.png?resize=800%2C600&ssl=1
|
||||
[17]: https://mate-desktop.org/blog/2020-02-10-mate-1-24-released/
|
||||
[18]: https://itsfoss.com/ubuntu-mate-customization/
|
||||
[19]: https://en.wikipedia.org/wiki/Common_Desktop_Environment
|
||||
[20]: https://en.wikipedia.org/wiki/XForms_(toolkit)
|
||||
[21]: https://itsfoss.com/manjaro-linux-review/
|
||||
[22]: https://itsfoss.com/mx-linux-19/
|
||||
[23]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/07/linux-mint-xfce.jpg?resize=800%2C500&ssl=1
|
||||
[24]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/Linux-Mint-20-Xfce-ram-usage.png?resize=800%2C600&ssl=1
|
||||
[25]: https://itsfoss.com/which-ubuntu-install/
|
||||
[26]: https://itsfoss.com/install-linux-mint-in-virtualbox/
|
@ -0,0 +1,248 @@
|
||||
[#]: subject: (Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact)
|
||||
[#]: via: (https://www.linux.com/news/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/)
|
||||
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact
|
||||
======
|
||||
|
||||
_By Matt Zand_
|
||||
|
||||
## **Recap**
|
||||
|
||||
In our two previous articles, first we covered “[Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy][1]” where we discussed the following five Hyperledger Distributed Ledger Technologies (DLTs):
|
||||
|
||||
1. Hyperledger Indy
|
||||
2. Hyperledger Fabric
|
||||
3. Hyperledger Iroha
|
||||
4. Hyperledger Sawtooth
|
||||
5. Hyperledger Besu
|
||||
|
||||
|
||||
|
||||
Then, we moved on to our second article ([Review of three Hyperledger Tools- Caliper, Cello and Avalon][2]) where we surveyed the following three Hyperledger t ools:
|
||||
|
||||
1. Hyperledger Caliper
|
||||
2. Hyperledger Cello
|
||||
3. Hyperledger Avalon
|
||||
|
||||
|
||||
|
||||
So in this follow-up article, we review four (as listed below) Hyperledger libraries that work very well with other Hyperledger DLTs. As of this writing, all of these libraries are at the incubation stage except for Hyperledger Aries, which has [graduated][3] to active.
|
||||
|
||||
1. Hyperledger Aries
|
||||
2. Hyperledger Quilt
|
||||
3. Hyperledger Ursa
|
||||
4. Hyperledger Transact
|
||||
|
||||
|
||||
|
||||
**Hyperledger Aries**
|
||||
|
||||
Identity has been adopted by the industry as one of the most promising use cases of DLTs. Solutions and initiatives around creating, storing, and transmitting verifiable digital credentials will result in a reusable, shared, interoperable tool kit. In response to such growing demand, Hyperledger has come up with three projects (Hyperledger Indy, Hyperledger Iroha and Hyperledger Aries) that are specifically focused on identity management.
|
||||
|
||||
Hyperledger Aries is infrastructure for blockchain-rooted, peer-to-peer interactions. It includes a shared cryptographic wallet (the secure storage tech, not a UI) for blockchain clients as well as a communications protocol for allowing off-ledger interactions between those clients. This project consumes the cryptographic support provided by Hyperledger Ursa to provide secure secret management and decentralized key management functionality.
|
||||
|
||||
According to Hyperledger Aries’ documentation, Aries includes the following features:
|
||||
|
||||
* An encrypted messaging system for off-ledger interactions using multiple transport protocols between clients.
|
||||
* A blockchain interface layer that is also called as a resolver. It is used for creating and signing blockchain transactions.
|
||||
* A cryptographic wallet to enable secure storage of cryptographic secrets and other information that is used for building blockchain clients.
|
||||
* An implementation of ZKP-capable W3C verifiable credentials with the help of the ZKP primitives that are found in Hyperledger Ursa.
|
||||
* A mechanism to build API-like use cases and higher-level protocols based on secure messaging functionality.
|
||||
* An implementation of the specifications of the Decentralized Key Management System (DKMS) that are being currently incubated in Hyperledger Indy.
|
||||
* Initially, the generic interface of Hyperledger Aries will support the Hyperledger Indy resolver. But the interface is flexible in the sense that anyone can build a pluggable method using DID method resolvers such as Ethereum and Hyperledger Fabric, or any other DID method resolver they wish to use. These resolvers would support the resolving of transactions and other data on other ledgers.
|
||||
* Hyperledger Aries will additionally provide the functionality and features outside the scope of the Hyperledger Indy ledger to be fully planned and supported. Owing to these capabilities, the community can now build core message families to facilitate interoperable interactions using a wide range of use cases that involve blockchain-based identity.
|
||||
|
||||
|
||||
|
||||
For more detailed discussion on its implementation, visit the link provided in the References section.
|
||||
|
||||
**Hyperledger Quilt**
|
||||
|
||||
The widespread adoption of blockchain technology by global businesses has coincided with the emergence of tons of isolated and disconnected networks or ledgers. While users can easily conduct transactions within their own network or ledger, they experience technical difficultly (and in some cases impracticality) for doing transactions with parties residing on different networks or ledgers. At best, the process of cross-ledger (or cross-network) transactions is slow, expensive, or manual. However, with the advent and adoption of Interledger Protocol (ILP), money and other forms of value can be routed, packetized, and delivered over ledgers and payment networks.
|
||||
|
||||
Hyperledger Quilt is a tool for interoperability between ledger systems and is written in Java by implementing the ILP for atomic swaps. While the Interledger is a protocol for making transactions across ledgers, ILP is a payment protocol designed to transfer value across non-distributed and distributed ledgers. The standards and specifications of Interledger protocol are governed by the open-source community under the World Wide Web Consortium umbrella. Quilt is an enterprise-grade implementation of the ILP, and provides libraries and reference implementations for the core Interledger components used for payment networks. With the launch of Quilt, the JavaScript (Interledger.js) implementation of Interledger was maintained by the JS Foundation.
|
||||
|
||||
According to the Quilt documentation, as a result of ILP implementation, Quilt offers the following features:
|
||||
|
||||
* A framework to design higher-level use-case specific protocols.
|
||||
* A set of rules to enable interoperability with basic escrow semantics.
|
||||
* A standard for data packet format and a ledger-dependent independent address format to enable connectors to route payments.
|
||||
|
||||
|
||||
|
||||
For more detailed discussion on its implementation, visit the link provided in the References section.
|
||||
|
||||
**Hyperledger Ursa**
|
||||
|
||||
Hyperledger Ursa is a shared cryptographic library that enables people (and projects) to avoid duplicating other cryptographic work and hopefully increase security in the process. The library is an opt-in repository for Hyperledger projects (and, potentially others) to place and use crypto.
|
||||
|
||||
Inside Project Ursa, a complete library of modular signatures and symmetric-key primitives is at the disposal of developers to swap in and out different cryptographic schemes through configuration and without having to modify their code. On top its base library, Ursa also includes newer cryptography, including pairing-based, threshold, and aggregate signatures. Furthermore, the zero-knowledge primitives including SNARKs are also supported by Ursa.
|
||||
|
||||
According to the Ursa’s documentation, Ursa offers the following benefits:
|
||||
|
||||
* Preventing duplication of solving similar security requirements across different blockchain
|
||||
* Simplifying the security audits of cryptographic operations since the code is consolidated into a single location. This reduces maintenance efforts of these libraries while improving the security footprint for developers with beginner knowledge of distributed ledger projects.
|
||||
* Reviewing all cryptographic codes in a single place will reduce the likelihood of dangerous security bugs.
|
||||
* Boosting cross-platform interoperability when multiple platforms, which require cryptographic verification, are using the same security protocols on both platforms.
|
||||
* Enhancing the architecture via modularity of common components will pave the way for future modular distributed ledger technology platforms using common components.
|
||||
* Accelerating the time to market for new projects as long as an existing security paradigm can be plugged-in without a project needing to build it themselves.
|
||||
|
||||
|
||||
|
||||
For more detailed discussion on its implementation, visit the link provided in the References section.
|
||||
|
||||
**Hyperledger Transact**
|
||||
|
||||
Hyperledger Transact, in a nutshell, makes writing distributed ledger software easier by providing a shared software library that handles the execution of smart contracts, including all aspects of scheduling, transaction dispatch, and state management. Utilizing Transact, smart contracts can be executed irrespective of DLTs being used. Specifically, Transact achieves that by offering an extensible approach to implementing new smart contract languages called “smart contract engines.” As such, each smart contract engine implements a virtual machine or interpreter that processes smart contracts.
|
||||
|
||||
At its core, Transact is solely a transaction processing system for state transitions. That is, s tate data is normally stored in a key-value or an SQL database. Considering an initial state and a transaction, Transact executes the transaction to produce a new state. These state transitions are deemed “pure” because only the initial state and the transaction are used as input. (In contrast to other systems such as Ethereum where state and block information are mixed to produce the new state). Therefore, Transact is agnostic about DLT framework features other than transaction execution and state.
|
||||
|
||||
According to Hyperledger Transact’s documentation, Transact comes with the following components:
|
||||
|
||||
* **State**. The Transact state implementation provides get, set, and delete operations against a database. For the Merkle-Radix tree state implementation, the tree structure is implemented on top of LMDB or an in-memory database.
|
||||
* **Context manager**. In Transact, state reads and writes are scoped (sandboxed) to a specific “context” that contains a reference to a state ID (such as a Merkle-Radix state root hash) and one or more previous contexts. The context manager implements the context lifecycle and services the calls that read, write, and delete data from state.
|
||||
* **Scheduler**. This component controls the order of transactions to be executed. Concrete implementations include a serial scheduler and a parallel scheduler. Parallel transaction execution is an important innovation for increasing network throughput.
|
||||
* **Executor**. The Transact executor obtains transactions from the scheduler and executes them against a specific context. Execution is handled by sending the transaction to specific execution adapters (such as ZMQ or a static in-process adapter) which, in turn, send the transaction to a specific smart contract.
|
||||
* **Smart Contract Engines**. These components provide the virtual machine implementations and interpreters that run the smart contracts. Examples of engines include WebAssembly, Ethereum Virtual Machine, Sawtooth Transactions Processors, and Fabric Chaincode.
|
||||
|
||||
|
||||
|
||||
For more detailed discussion on its implementation, visit the link provided in the References section.
|
||||
|
||||
** Summary**
|
||||
|
||||
In this article, we reviewed four Hyperledger libraries that are great resources for managing Hyperledger DLTs. We started by explaining Hyperledger Aries, which is infrastructure for blockchain-rooted, peer-to-peer interactions and includes a shared cryptographic wallet for blockchain clients as well as a communications protocol for allowing off-ledger interactions between those clients. Then, we learned that Hyperledger Quilt is the interoperability tool between ledger systems and is written in Java by implementing the ILP for atomic swaps. While the Interledger is a protocol for making transactions across ledgers, ILP is a payment protocol designed to transfer value across non-distributed and distributed ledgers. We also discussed that Hyperledger Ursa is a shared cryptographic library that would enable people (and projects) to avoid duplicating other cryptographic work and hopefully increase security in the process. The library would be an opt-in repository for Hyperledger projects (and, potentially others) to place and use crypto. We concluded our article by reviewing Hyperledger Transact by which smart contracts can be executed irrespective of DLTs being used. Specifically, Transact achieves that by offering an extensible approach to implementing new smart contract languages called “smart contract engines.”
|
||||
|
||||
**References**
|
||||
|
||||
For more references on all Hyperledger projects, libraries and tools, visit the below documentation links:
|
||||
|
||||
1. [Hyperledger Indy Project][4]
|
||||
2. [Hyperledger Fabric Project][5]
|
||||
3. [Hyperledger Aries Library][6]
|
||||
4. [Hyperledger Iroha Project][7]
|
||||
5. [Hyperledger Sawtooth Project][8]
|
||||
6. [Hyperledger Besu Project][9]
|
||||
7. [Hyperledger Quilt Library][10]
|
||||
8. [Hyperledger Ursa Library][11]
|
||||
9. [Hyperledger Transact Library][12]
|
||||
10. [Hyperledger Cactus Project][13]
|
||||
11. [Hyperledger Caliper Tool][14]
|
||||
12. [Hyperledger Cello Tool][15]
|
||||
13. [Hyperledger Explorer Tool][16]
|
||||
14. [Hyperledger Grid (Domain Specific)][17]
|
||||
15. [Hyperledger Burrow Project][18]
|
||||
16. [Hyperledger Avalon Tool][19]
|
||||
|
||||
|
||||
|
||||
**Resources**
|
||||
|
||||
* Free Training Courses from The Linux Foundation & Hyperledger
|
||||
* [Blockchain: Understanding Its Uses and Implications (LFS170)][20]
|
||||
* [Introduction to Hyperledger Blockchain Technologies (LFS171)][21]
|
||||
* [Introduction to Hyperledger Sovereign Identity Blockchain Solutions: Indy, Aries & Ursa (LFS172)][22]
|
||||
* [Becoming a Hyperledger Aries Developer (LFS173)][23]
|
||||
* [Hyperledger Sawtooth for Application Developers (LFS174)][24]
|
||||
* eLearning Courses from The Linux Foundation & Hyperledger
|
||||
* [Hyperledger Fabric Administration (LFS272)][25]
|
||||
* [Hyperledger Fabric for Developers (LFD272)][26]
|
||||
* Certification Exams from The Linux Foundation & Hyperledger
|
||||
* [Certified Hyperledger Fabric Administrator (CHFA)][27]
|
||||
* [Certified Hyperledger Fabric Developer (CHFD)][28]
|
||||
* [Hands-On Smart Contract Development with Hyperledger Fabric V2][29] Book by Matt Zand and others.
|
||||
* [Essential Hyperledger Sawtooth Features for Enterprise Blockchain Developers][30]
|
||||
* [Blockchain Developer Guide- How to Install Hyperledger Fabric on AWS][31]
|
||||
* [Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth][32]
|
||||
* [Intro to Blockchain Cybersecurity][33]
|
||||
* [Intro to Hyperledger Sawtooth for System Admins][34]
|
||||
* [Blockchain Developer Guide- How to Install Hyperledger Iroha on AWS][35]
|
||||
* [Blockchain Developer Guide- How to Install Hyperledger Indy and Indy CLI on AWS][36]
|
||||
* [Blockchain Developer Guide- How to Configure Hyperledger Sawtooth Validator and REST API on AWS][37]
|
||||
* [Intro blockchain development with Hyperledger Fabric][38]
|
||||
* [How to build DApps with Hyperledger Fabric][39]
|
||||
* [Blockchain Developer Guide- How to Build Transaction Processor as a Service and Python Egg for Hyperledger Sawtooth][40]
|
||||
* [Blockchain Developer Guide- How to Create Cryptocurrency Using Hyperledger Iroha CLI][41]
|
||||
* [Blockchain Developer Guide- How to Explore Hyperledger Indy Command Line Interface][42]
|
||||
* [Blockchain Developer Guide- Comprehensive Blockchain Hyperledger Developer Guide from Beginner to Advance Level][43]
|
||||
* [Blockchain Management in Hyperledger for System Admins][44]
|
||||
* [Hyperledger Fabric for Developers][45]
|
||||
|
||||
|
||||
|
||||
**About Author**
|
||||
|
||||
**Matt Zand** is a serial entrepreneur and the founder of three tech startups: [DC Web Makers][46], [Coding Bootcamps][47] and [High School Technology Services][48]. He is a leading author of [Hands-on Smart Contract Development with Hyperledger Fabric][29] book by O’Reilly Media. He has written more than 100 technical articles and tutorials on blockchain development for Hyperledger, Ethereum and Corda R3 platforms at sites such as IBM, SAP, Alibaba Cloud, Hyperledger, The Linux Foundation, and more. As a public speaker, he has presented webinars at many Hyperledger communities across USA and Europe . At DC Web Makers, he leads a team of blockchain experts for consulting and deploying enterprise decentralized applications. As chief architect, he has designed and developed blockchain courses and training programs for Coding Bootcamps. He has a master’s degree in business management from the University of Maryland. Prior to blockchain development and consulting, he worked as senior web and mobile App developer and consultant, angel investor, business advisor for a few startup companies. You can connect with him on [LinkedIn][49].
|
||||
|
||||
The post [Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact][50] appeared first on [Linux Foundation – Training][51].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
|
||||
|
||||
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
|
||||
[2]: https://training.linuxfoundation.org/announcements/review-of-three-hyperledger-tools-caliper-cello-and-avalon/
|
||||
[3]: https://www.hyperledger.org/blog/2021/02/26/hyperledger-aries-graduates-to-active-status-joins-indy-as-production-ready-hyperledger-projects-for-decentralized-identity
|
||||
[4]: https://www.hyperledger.org/use/hyperledger-indy
|
||||
[5]: https://www.hyperledger.org/use/fabric
|
||||
[6]: https://www.hyperledger.org/projects/aries
|
||||
[7]: https://www.hyperledger.org/projects/iroha
|
||||
[8]: https://www.hyperledger.org/projects/sawtooth
|
||||
[9]: https://www.hyperledger.org/projects/besu
|
||||
[10]: https://www.hyperledger.org/projects/quilt
|
||||
[11]: https://www.hyperledger.org/projects/ursa
|
||||
[12]: https://www.hyperledger.org/projects/transact
|
||||
[13]: https://www.hyperledger.org/projects/cactus
|
||||
[14]: https://www.hyperledger.org/projects/caliper
|
||||
[15]: https://www.hyperledger.org/projects/cello
|
||||
[16]: https://www.hyperledger.org/projects/explorer
|
||||
[17]: https://www.hyperledger.org/projects/grid
|
||||
[18]: https://www.hyperledger.org/projects/hyperledger-burrow
|
||||
[19]: https://www.hyperledger.org/projects/avalon
|
||||
[20]: https://training.linuxfoundation.org/training/blockchain-understanding-its-uses-and-implications/
|
||||
[21]: https://training.linuxfoundation.org/training/blockchain-for-business-an-introduction-to-hyperledger-technologies/
|
||||
[22]: https://training.linuxfoundation.org/training/introduction-to-hyperledger-sovereign-identity-blockchain-solutions-indy-aries-and-ursa/
|
||||
[23]: https://training.linuxfoundation.org/training/becoming-a-hyperledger-aries-developer-lfs173/
|
||||
[24]: https://training.linuxfoundation.org/training/hyperledger-sawtooth-application-developers-lfs174/
|
||||
[25]: https://training.linuxfoundation.org/training/hyperledger-fabric-administration-lfs272/
|
||||
[26]: https://training.linuxfoundation.org/training/hyperledger-fabric-for-developers-lfd272/
|
||||
[27]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-administrator-chfa/
|
||||
[28]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-developer/
|
||||
[29]: https://www.oreilly.com/library/view/hands-on-smart-contract/9781492086116/
|
||||
[30]: https://weg2g.com/application/touchstonewords/article-essential-hyperledger-sawtooth-features-for-enterprise-blockchain-developers.php
|
||||
[31]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-fabric-on-amazon-web-services.php
|
||||
[32]: https://myhsts.org/tutorial-learn-how-to-install-and-work-with-blockchain-hyperledger-sawtooth.php
|
||||
[33]: https://learn.coding-bootcamps.com/p/learn-how-to-secure-blockchain-applications-by-examples
|
||||
[34]: https://learn.coding-bootcamps.com/p/introduction-to-hyperledger-sawtooth-for-system-admins
|
||||
[35]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-iroha-on-amazon-web-services.php
|
||||
[36]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-indy-on-amazon-web-services.php
|
||||
[37]: https://myhsts.org/tutorial-learn-how-to-configure-hyperledger-sawtooth-validator-and-rest-api-on-aws.php
|
||||
[38]: https://learn.coding-bootcamps.com/p/live-and-self-paced-blockchain-development-with-hyperledger-fabric
|
||||
[39]: https://learn.coding-bootcamps.com/p/live-crash-course-for-building-dapps-with-hyperledger-fabric
|
||||
[40]: https://myhsts.org/tutorial-learn-how-to-build-transaction-processor-as-a-service-and-python-egg-for-hyperledger-sawtooth.php
|
||||
[41]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-iroha-cli-to-create-cryptocurrency.php
|
||||
[42]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-indy-command-line-interface.php
|
||||
[43]: https://myhsts.org/tutorial-comprehensive-blockchain-hyperledger-developer-guide-for-all-professional-programmers.php
|
||||
[44]: https://learn.coding-bootcamps.com/p/learn-blockchain-development-with-hyperledger-by-examples
|
||||
[45]: https://learn.coding-bootcamps.com/p/hyperledger-blockchain-development-for-developers
|
||||
[46]: https://blockchain.dcwebmakers.com/
|
||||
[47]: http://coding-bootcamps.com/
|
||||
[48]: https://myhsts.org/
|
||||
[49]: https://www.linkedin.com/in/matt-zand-64047871
|
||||
[50]: https://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
|
||||
[51]: https://training.linuxfoundation.org/
|
@ -0,0 +1,90 @@
|
||||
[#]: subject: (Set up network parental controls on a Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-parental-control)
|
||||
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Set up network parental controls on a Raspberry Pi
|
||||
======
|
||||
With minimal investment of time and money, you can keep your kids safe
|
||||
online.
|
||||
![Family learning and reading together at night in a room][1]
|
||||
|
||||
Parents are always looking for ways to protect their kids online—from malware, banner ads, pop-ups, activity-tracking scripts, and other concerns—and to prevent them from playing games and watching YouTube when they should be doing their schoolwork. Many businesses use tools that regulate their employees' online safety and activities, but the question is how to make this happen at home?
|
||||
|
||||
The short answer is a tiny, inexpensive Raspberry Pi computer that enables you to set parental controls for your kids and your work at home. This article walks you through how easy it is to build your own parental control-enabled home network with a Raspberry Pi.
|
||||
|
||||
### Install the hardware and software
|
||||
|
||||
For this project, you'll need a Raspberry Pi and a home network router. If you spend only five minutes exploring online shopping sites, you will find a lot of options. The [Raspberry Pi 4][2] and a [TP-Link router][3] are good options for beginners.
|
||||
|
||||
Once you have your network device and Pi, you need to install [Pi-hole][4] as a Linux container or a supported operating system. There are several [ways to install it][5], but an easy way is to issue the following command on your Pi:
|
||||
|
||||
|
||||
```
|
||||
`curl -sSL https://install.pi-hole.net | bash`
|
||||
```
|
||||
|
||||
### Configure Pi-hole as your DNS server
|
||||
|
||||
Next, you need to configure the DHCP settings in both your router and Pi-hole:
|
||||
|
||||
1. Disable the DHCP server setting in your router
|
||||
2. Enable the DHCP server in Pi-hole
|
||||
|
||||
|
||||
|
||||
Every device is different, so there's no way for me to tell you exactly what you need to click on to adjust your settings. Generally, you access your home router through a web browser. Your router's address is sometimes printed on the bottom of the router, and it begins with either 192.168 or 10.
|
||||
|
||||
In your web browser, navigate to your router's address and log in with the credentials you received when you got your internet service. It's often as simple as `admin` with a numeric password (sometimes this password is also printed on the router). If you don't know the login, call your internet provider and ask for details.
|
||||
|
||||
In the graphical interface, look for a section within your LAN about DHCP, and deactivate the DHCP server. Your router's interface will almost certainly look different from mine, but this is an example of what I saw when setting it up. Uncheck **DHCP server**:
|
||||
|
||||
![Disable DHCP][6]
|
||||
|
||||
(Daniel Oh, [CC BY-SA 4.0][7])
|
||||
|
||||
Next, you _must_ activate the DHCP server on the Pi-hole. If you don't do that, none of your devices will be able to get online unless you manually assign IP addresses!
|
||||
|
||||
### Make your network family-friendly
|
||||
|
||||
You're all set. Now, your network devices (i.e., mobile phone, tablet PC, laptop, etc.) will automatically find the DHCP server on the Raspberry Pi. Then, each device will be assigned a dynamic IP address to access the internet.
|
||||
|
||||
Note: If your router device supports setting a DNS server, you can also configure the DNS clients in your router. The client will refer to the Pi-hole as your DNS server.
|
||||
|
||||
To set up rules for which sites and activities your kids can access, open a web browser to the Pi-hole admin page, `http://pi.hole/admin/`. On the dashboard, click on **Whitelist** to add web pages your kids are allowed to access. You can also add sites that your kids aren't allowed to access (e.g., gaming, adult, ads, shopping, etc.) to the **Blocklist**.
|
||||
|
||||
![Pi-hole admin dashboard][8]
|
||||
|
||||
(Daniel Oh, [CC BY-SA 4.0][7])
|
||||
|
||||
### What's next?
|
||||
|
||||
Now that you've set up your Raspberry Pi for parental control, you can keep your kids safer online while giving them access to approved entertainment options. This can also decrease your home internet usage by reducing how much your family is streaming. For more advanced usage, access Pi-hole's [documentation][9] and [blogs][10].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/raspberry-pi-parental-control
|
||||
|
||||
作者:[Daniel Oh][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/daniel-oh
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/family_learning_kids_night_reading.png?itok=6K7sJVb1 (Family learning and reading together at night in a room)
|
||||
[2]: https://www.raspberrypi.org/products/
|
||||
[3]: https://www.amazon.com/s?k=tp-link+router&crid=3QRLN3XRWHFTC&sprefix=TP-Link%2Caps%2C186&ref=nb_sb_ss_ts-doa-p_3_7
|
||||
[4]: https://pi-hole.net/
|
||||
[5]: https://github.com/pi-hole/pi-hole/#one-step-automated-install
|
||||
[6]: https://opensource.com/sites/default/files/uploads/disabledhcp.jpg (Disable DHCP)
|
||||
[7]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[8]: https://opensource.com/sites/default/files/uploads/blocklist.png (Pi-hole admin dashboard)
|
||||
[9]: https://docs.pi-hole.net/
|
||||
[10]: https://pi-hole.net/blog/#page-content
|
@ -1,262 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (stevenzdg988)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Testing Bash with BATS)
|
||||
[#]: via: (https://opensource.com/article/19/2/testing-bash-bats)
|
||||
[#]: author: (Darin London https://opensource.com/users/dmlond)
|
||||
|
||||
利用 BATS 测试 Bash
|
||||
======
|
||||
Bash 自动测试系统通过 Java,Ruby 和 Python 开发人员所使用的相同类型的测试进程来提交 Bash 代码。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf)
|
||||
|
||||
用Java,Ruby和Python等语言编写应用程序的软件开发人员拥有完善的库,可以帮助他们随着时间的推移保持软件的完整性。他们创建测试,以在结构化环境中通过一系列执行来运行应用程序,以确保其所有软件方面均按预期工作。
|
||||
|
||||
当这些测试在持续集成(CI)系统中自动化时甚至会更加健壮,在这种情况下,每次推送到源知识库都会使测试运行,并且在测试失败时会立即通知开发人员。这种快速反馈提高了开发人员对其应用程序功能完整性的信心。
|
||||
|
||||
Bash 自动测试系统([BATS][1])使开发人员能够编写 Bash 脚本和库,以将Java,Ruby,Python 和其他开发人员所使用的相同惯例应用于其 Bash 代码。
|
||||
|
||||
### 安装 BATS
|
||||
|
||||
BATS GitHub 页面包含安装指令。有两个 BATS 帮助程序函数库,它们提供更强大的断言或允许使用 BATS 重写 Test Anything Protocol(测试协议)([TAP][2])输出格式。可以将它们安装在标准位置,并由所有脚本提供。在 Git 知识库中包含完整版本的 BATS 及其帮助函数库对于要测试的每组脚本或函数库可能会更实用。这可以使用 **[git submodule][3]** (git 子模块)系统来完成。
|
||||
|
||||
以下命令会将 BATS 及其帮助函数库安装到 Git 知识库中的 **test** 目录中。
|
||||
|
||||
```
|
||||
git submodule init
|
||||
git submodule add https://github.com/sstephenson/bats test/libs/bats
|
||||
git submodule add https://github.com/ztombol/bats-assert test/libs/bats-assert
|
||||
git submodule add https://github.com/ztombol/bats-support test/libs/bats-support
|
||||
git add .
|
||||
git commit -m 'installed bats'
|
||||
```
|
||||
|
||||
要克隆 Git 知识库并同时安装其子模块,请使用
|
||||
**\-recurse-submodules** 为 **git clone** 标记。
|
||||
|
||||
每个 BATS 测试脚本必须由 **bats** 可执行文件执行。如果您将 BATS 安装到源代码知识库的 **test/libs** 目录中,则可以使用以下命令调用测试:
|
||||
|
||||
```
|
||||
./test/libs/bats/bin/bats <path to test script>
|
||||
```
|
||||
|
||||
或者,将以下内容添加到每个 BATS 测试脚本的开头:
|
||||
|
||||
```
|
||||
#!/usr/bin/env ./test/libs/bats/bin/bats
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
```
|
||||
|
||||
并且执行命令 **chmod +x <测试脚本的路径>**。 这将 a) 使它们与安装在 **./test/libs/bats** 中的 BATS 可执行,并且 b) 包括这些帮助函数库。BATS 测试脚本通常存储在 **test** 目录中,并为要测试的脚本命名,扩展名为 **.bats**。例如,测试 **bin/build** 的 BATS 脚本应称为 **test/build.bats**。
|
||||
|
||||
您还可以通过正则表达式传递给 BATS 来运行整套 BATS 测试文件,例如 **./test/lib/bats/bin/bats test/*.bats**。
|
||||
|
||||
### 为 BATS 组织函数库和脚本的重写范围
|
||||
|
||||
Bash 脚本和库必须以一种有效地将其内部工作暴露给 BATS 的方式进行组织。通常,在调用或执行时库函数和运行诸多命令的 Shell 脚本不适合进行有效的 BATS 测试。
|
||||
|
||||
例如,[build.sh][4] 是许多人编写的典型脚本。本质上是一大堆代码。有些人甚至可能将这堆代码放入库中的函数中。但是,不可能在 BATS 测试中运行大量代码并涵盖在单独的测试用例中可能遇到的所有类型的故障。测试具有足够重写范围的这堆代码的唯一方法是将其分解为许多小的,可重用的,最重要的是可独立测试的功能。
|
||||
|
||||
向库添加更多功能(函数)很简单。额外的好处是其中一些功能本身可以变得出奇的有用。将库函数分解为许多较小的函数后,您可以在 BATS 测试中 **source** 库,并像测试任何其他命令一样运行这些函数。
|
||||
|
||||
Bash 脚本还必须分解为多个函数,执行脚本时,脚本的主要部分应调用这些函数。此外,还有一个非常有用的技巧,可以使使用 BATS 测试 Bash 脚本变得更加容易:将脚本主要部分中执行的所有代码都移到一个函数中,称为 **run_main**。然后,将以下内容添加到脚本的末尾:
|
||||
|
||||
```
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]
|
||||
then
|
||||
run_main
|
||||
fi
|
||||
```
|
||||
|
||||
这段额外的代码做了一些特殊的事情。它使脚本当作为脚本执行时与使用 **source** 进入环境时的行为有所不同。此技巧使通过与测试库相同的方式测试脚本和测试各个函数功能成为可能。例如,利用脚本 [build.sh 重构以获得更好的 BATS 可测试性][5]。
|
||||
|
||||
### 编写和运行测试
|
||||
|
||||
如上所述,BATS 是一个 TAP 兼容测试框架,其语法和输出对于使用过其他 TAP 兼容测试套件(例如 JUnit,RSpec 或 Jest)的用户来说将是熟悉的。它的测试被组织进各个测试脚本。测试脚本被组织进一个或多个描述性 **@test** 块中,它们描述了被测试应用程序的单元。每个 **@test** 块都将运行一系列准备测试环境命令,运行要测试的命令,并对退出和被测试命令的输出进行断言。许多断言函数是通过 **bats** , **bats-assert** , 和 **bats-support** 库导入的,这些库在 BATS 测试脚本的开头加载到环境中。下面是一个典型的 BATS 测试块:
|
||||
|
||||
```
|
||||
@test "requires CI_COMMIT_REF_SLUG environment variable" {
|
||||
unset CI_COMMIT_REF_SLUG
|
||||
assert_empty "${CI_COMMIT_REF_SLUG}"
|
||||
run some_command
|
||||
assert_failure
|
||||
assert_output --partial "CI_COMMIT_REF_SLUG"
|
||||
}
|
||||
```
|
||||
|
||||
如果 BATS 脚本包含 **setup(安装)** 和/或 **teardown(拆卸)** 功能,则 BATS 将在每个测试块运行之前和之后自动执行它们。这样就可以创建环境变量,测试文件以及执行一个或所有测试所需的其他操作,然后在每次测试运行后将其拆卸。[**Build.bats**][6] 是对我们新格式化的 **build.sh** 脚本的完整 BATS 测试。(此测试中的 **mock_docker** 命令将在以下关于模拟/桩的部分中进行说明。)
|
||||
|
||||
当测试脚本运行时,BATS 使用 **exec** 来将每个 **@test** 块作为单独的子进程运行。这样就可以在一个 **@test** 中导出环境变量甚至函数,而不会影响其他 **@test** 或污染您当前的 Shell 会话。测试运行的输出是一种标准格式,可以被人理解,并且可以由 TAP 用户以编程方式进行解析或操作。下面是 **CI_COMMIT_REF_SLUG** 测试块失败时的输出示例:
|
||||
|
||||
```
|
||||
✗ requires CI_COMMIT_REF_SLUG environment variable
|
||||
(from function `assert_output' in file test/libs/bats-assert/src/assert.bash, line 231,
|
||||
in test file test/ci_deploy.bats, line 26)
|
||||
`assert_output --partial "CI_COMMIT_REF_SLUG"' failed
|
||||
|
||||
-- output does not contain substring --
|
||||
substring (1 lines):
|
||||
CI_COMMIT_REF_SLUG
|
||||
output (3 lines):
|
||||
./bin/deploy.sh: join_string_by: command not found
|
||||
oc error
|
||||
Could not login
|
||||
--
|
||||
|
||||
** Did not delete , as test failed **
|
||||
|
||||
1 test, 1 failure
|
||||
```
|
||||
|
||||
下面是成功测试的输出:
|
||||
|
||||
```
|
||||
✓ requires CI_COMMIT_REF_SLUG environment variable
|
||||
```
|
||||
|
||||
### 助手
|
||||
|
||||
像任何 Shell 脚本或库一样,BATS 测试脚本可以包括帮助程序库,以在测试之间共享通用代码或增强其性能。这些帮助程序库,例如 **bats-assert** 和 **bats-support** 甚至可以使用 BATS 进行测试。
|
||||
|
||||
如果测试目录中的文件数量庞大,则可以将库放置在同一测试目录中作为 BATS 脚本,也可以将它们放置在 **test/libs** 目录中。BATS 提供了 **load** 函数,该函数采用相对于要测试的脚本的 Bash 文件的路径(例如,在我们的示例中的 **test**),并声明该文件。文件必须以前缀 **.bash** 结尾,但是传递给 **load** 函数的文件路径不能包含前缀。**build.bats** 加载 **bats-assert** 和 **bats-support** 库,一个小型 **[helpers.bash][7]** 库以及 **docker_mock.bash** 库(如下所述),以下代码位于解释器调谐线下方的测试脚本的开头:
|
||||
|
||||
```
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
load 'helpers'
|
||||
load 'docker_mock'
|
||||
```
|
||||
|
||||
### 测试输入桩和模拟外部调用
|
||||
|
||||
大多数 Bash 脚本和库运行时执行函数和(或)可执行文件。通常,它们被程序化为基于特定方式运行退出状态或这些函数或可执行文件的输出(**stdout**,**stderr**)。为了正确地测试这些脚本,通常需要制作这些命令的伪版本,这些被设计用来在特定测试过程中以特定方式运行,称为“桩(桩?)”。可能还需要监视正在测试的程序,以确保其调用了特定命令,或者使用特定参数调用了特定命令,此过程称为“模拟”。有关更多信息,请查看在 Ruby RSpec 中适用于任何测试系统的伟大的 [有关模拟和桩的讨论][8]。
|
||||
|
||||
Bash shell 提供了的技巧,可以在您的 BATS 测试脚本中使用进行模拟和桩。所有这些都需要使用带有 **-f** 标志的 Bash **export** 命令来导出重写原始函数或可执行文件的函数。必须在测试程序执行之前完成此操作。下面是重写可执行命令 **cat** 的简单示例:
|
||||
|
||||
```
|
||||
function cat() { echo "THIS WOULD CAT ${*}" }
|
||||
export -f cat
|
||||
```
|
||||
|
||||
此方法以相同的方式重写函数。如果测试需要重写要测试的脚本或库中的函数,则在对函数进行桩或模拟之前,必须先声明已测试脚本或库,这一点很重要。否则,在声明脚本时,桩/模拟将被原函数替代。另外,在运行即将进行的测试命令之前确认桩/模拟。下面是**build.bats**的示例,该示例模拟**build.sh**中描述的**raise**函数,以确保利用登录函数引发特定的错误消息:
|
||||
|
||||
```
|
||||
@test ".login raises on oc error" {
|
||||
source ${profile_script}
|
||||
function raise() { echo "${1} raised"; }
|
||||
export -f raise
|
||||
run login
|
||||
assert_failure
|
||||
assert_output -p "Could not login raised"
|
||||
}
|
||||
```
|
||||
|
||||
一般情况下,没有必要在测试后复原桩/模拟功能,因为 **export**(输出)仅在当前 **@test** 块的 **exec**(执行)期间影响当前子进程。但是,可以模拟/桩 BATS **assert** 函数在内部使用的命令(例如**cat**,**sed**等)是可能的。在运行这些断言命令之前,必须对这些模拟/桩函数进行 **unset**(复原) ,否则它们将无法正常工作。下面是 **build.bats** 中的一个示例,该示例模拟 **sed**,运行 **build_deployable** 函数并在运行任何断言之前复原 **sed**:
|
||||
|
||||
```
|
||||
@test ".build_deployable prints information, runs docker build on a modified Dockerfile.production and publish_image when its not a dry_run" {
|
||||
local expected_dockerfile='Dockerfile.production'
|
||||
local application='application'
|
||||
local environment='environment'
|
||||
local expected_original_base_image="${application}"
|
||||
local expected_candidate_image="${application}-candidate:${environment}"
|
||||
local expected_deployable_image="${application}:${environment}"
|
||||
source ${profile_script}
|
||||
mock_docker build --build-arg OAUTH_CLIENT_ID --build-arg OAUTH_REDIRECT --build-arg DDS_API_BASE_URL -t "${expected_deployable_image}" -
|
||||
function publish_image() { echo "publish_image ${*}"; }
|
||||
export -f publish_image
|
||||
function sed() {
|
||||
echo "sed ${*}" >&2;
|
||||
echo "FROM application-candidate:environment";
|
||||
}
|
||||
export -f sed
|
||||
run build_deployable "${application}" "${environment}"
|
||||
assert_success
|
||||
unset sed
|
||||
assert_output --regexp "sed.*${expected_dockerfile}"
|
||||
assert_output -p "Building ${expected_original_base_image} deployable ${expected_deployable_image} FROM ${expected_candidate_image}"
|
||||
assert_output -p "FROM ${expected_candidate_image} piped"
|
||||
assert_output -p "build --build-arg OAUTH_CLIENT_ID --build-arg OAUTH_REDIRECT --build-arg DDS_API_BASE_URL -t ${expected_deployable_image} -"
|
||||
assert_output -p "publish_image ${expected_deployable_image}"
|
||||
}
|
||||
```
|
||||
|
||||
有的时候相同的命令,例如 `foo`,将在被测试的同一函数中使用不同的参数多次调用。 这些情况需要创建一组函数:
|
||||
|
||||
* mock_foo:将期望的参数作为输入,并将其持久化到 TMP 文件中
|
||||
* foo:命令的模拟版本,该命令使用持久化的预期参数列表处理每个调用。必须使用 `export -f` 将其导出。
|
||||
* cleanup_foo:删除 TMP 文件,用于拆卸函数。这可以进行测试以确保在删除之前成功完成 `@test` 块。
|
||||
|
||||
由于此功能通常在不同的测试中重复使用,因此创建可以像其他库一样加载的帮助程序库会变得有意义。
|
||||
|
||||
**[docker_mock.bash][9]**是一个很棒的例子。它被加载到 **build.bats** 中,并在任何测试调用 Docker 可执行文件的函数的测试块中使用。使用 **docker_mock** 典型的测试块如下所示:
|
||||
|
||||
```
|
||||
@test ".publish_image fails if docker push fails" {
|
||||
setup_publish
|
||||
local expected_image="image"
|
||||
local expected_publishable_image="${CI_REGISTRY_IMAGE}/${expected_image}"
|
||||
source ${profile_script}
|
||||
mock_docker tag "${expected_image}" "${expected_publishable_image}"
|
||||
mock_docker push "${expected_publishable_image}" and_fail
|
||||
run publish_image "${expected_image}"
|
||||
assert_failure
|
||||
assert_output -p "tagging ${expected_image} as ${expected_publishable_image}"
|
||||
assert_output -p "tag ${expected_image} ${expected_publishable_image}"
|
||||
assert_output -p "pushing image to gitlab registry"
|
||||
assert_output -p "push ${expected_publishable_image}"
|
||||
}
|
||||
```
|
||||
|
||||
该测试建立了一个使用不同的参数两次调用 Docker 的预期。在对Docker 的第二次调用失败时,将运行测试命令,然后测试退出状态和对 Docker 调用的预期。
|
||||
|
||||
一方面 BATS 利用 **mock_docker.bash** 引入 **${BATS_TMPDIR}** 环境变量,BATS 在测试开始的位置对其进行了设置,以允许测试和助手程序在标准位置创建和销毁 TMP 文件。如果测试失败,**mock_docker.bash** 库将不会删除其持久化的模拟文件,但会在其所在位置进行打印,以便可以查看和删除它。您可能需要定期从该目录中清除旧的模拟文件。
|
||||
|
||||
请注意关于模拟/桩的警告:**build.bats** 测试有意识地违反了关于测试声明的规定:[不要模拟没有拥有的!][10]该规定要求调用开发人员没有编写代码的测试命令,例如 **docker**,**cat**,**sed**等,应封装在自己的库中,应在使用它们脚本的测试中对其进行模拟。然后应该在不模拟外部命令的情况下测试封装库。
|
||||
|
||||
这是一个很好的建议,而忽略它是有代价的。如果 Docker CLI API 发生变化,则测试脚本将不会检测到此变化,从而导致一个错误内容直到经过测试的 **build.sh** 脚本在使用新版本 Docker 的生产环境中运行后才显示出来。测试开发人员必须确定要严格遵守此标准的程度,但是他们应该了解其所涉及的权衡。
|
||||
|
||||
### 总结
|
||||
|
||||
在任何软件开发项目中引入测试方案都会在 a)增加开发和维护代码及测试所需的时间和组织与 b)增加开发人员在对应用程序整个生命周期中完整性的信心之间进行权衡。测试方案可能不适用于所有脚本和库。
|
||||
|
||||
通常,满足以下一个或多个条件的脚本和库才可以使用 BATS 测试:
|
||||
|
||||
* They are used by others
|
||||
* 值得存储在源代码管理中
|
||||
* 用于关键进程中,并可以长期稳定运行
|
||||
* 需要定期对其进行修改以添加/删除/修改其函数
|
||||
* 可以被其他人使用
|
||||
|
||||
一旦决定将测试规则应用于一个或多个 Bash 脚本或库,BATS 将提供其他软件开发环境中可用的全面测试功能。
|
||||
|
||||
致谢:感激[Darrin Mann][11]向我引荐了 BATS 测试。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/2/testing-bash-bats
|
||||
|
||||
作者:[Darin London][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dmlond
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/sstephenson/bats
|
||||
[2]: http://testanything.org/
|
||||
[3]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
[4]: https://github.com/dmlond/how_to_bats/blob/preBats/build.sh
|
||||
[5]: https://github.com/dmlond/how_to_bats/blob/master/bin/build.sh
|
||||
[6]: https://github.com/dmlond/how_to_bats/blob/master/test/build.bats
|
||||
[7]: https://github.com/dmlond/how_to_bats/blob/master/test/helpers.bash
|
||||
[8]: https://www.codewithjason.com/rspec-mocks-stubs-plain-english/
|
||||
[9]: https://github.com/dmlond/how_to_bats/blob/master/test/docker_mock.bash
|
||||
[10]: https://github.com/testdouble/contributing-tests/wiki/Don't-mock-what-you-don't-own
|
||||
[11]: https://github.com/dmann
|
@ -0,0 +1,135 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (stevenzdg988)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (6 best practices for managing Git repos)
|
||||
[#]: via: (https://opensource.com/article/20/7/git-repos-best-practices)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
6 个最佳的 Git 仓库管理实践
|
||||
======
|
||||
阻止向 Git 中添加内容的主张会使其变得更难管理;
|
||||
这里有替代方法。
|
||||
![在家中使用笔记本电脑工作][1]
|
||||
|
||||
有权访问源代码使对安全性的分析以及应用程序的安全成为可能。但是,如果没有人真正看过代码,问题就不会被发现,即使人们积极地看代码,通常也要看很多东西。幸运的是,GitHub 拥有一个活跃的安全团队,最近,他们 [发现了已提交到多个 Git 存储库中的特洛伊木马病毒][2],甚至仓库的所有者也偷偷溜走了。尽管我们无法控制其他人如何管理自己的存储库,但我们可以从他们的错误中吸取教训。为此,本文回顾了将文件添加到自己的存储库中的一些最佳实践。
|
||||
|
||||
### 了解您的仓库
|
||||
|
||||
![Git 存储库终端][3]
|
||||
|
||||
对于安全的 Git 存储库来说大概是 Rule Zero (头号规则)。作为项目维护者,无论您是从自己的开始还是采用别人的,您的工作是了解自己存储库中的内容。您可能没有代码库中关于每个文件的存储列表,但是您需要了解所管理内容的基本组成。如果几十个合并后出现一个偏离的文件,您将可以很容易地识别它,因为您不知道它的用途,并且需要刷新内存检查它。发生这种情况时,请查看文件,并确保准确了解为什么它是必要的。
|
||||
|
||||
### 禁止二进制大文件
|
||||
|
||||
![终端中 Git 的二进制检查命令][4]
|
||||
|
||||
Git 用于文本,无论是用纯文本编写的 C 或 Python 还是 Java 文本,亦或是 JSON,YAML,XML,Markdown,HTML 或类似的文本。Git 对于二进制文件不是很理想。
|
||||
|
||||
两者之间的区别是:
|
||||
|
||||
```
|
||||
$ cat hello.txt
|
||||
This is plain text.
|
||||
It's readable by humans and machines alike.
|
||||
Git knows how to version this.
|
||||
|
||||
$ git diff hello.txt
|
||||
diff --git a/hello.txt b/hello.txt
|
||||
index f227cc3..0d85b44 100644
|
||||
\--- a/hello.txt
|
||||
+++ b/hello.txt
|
||||
@@ -1,2 +1,3 @@
|
||||
This is plain text.
|
||||
+It's readable by humans and machines alike.
|
||||
Git knows how to version this.
|
||||
```
|
||||
|
||||
和
|
||||
|
||||
```
|
||||
$ git diff pixel.png
|
||||
diff --git a/pixel.png b/pixel.png
|
||||
index 563235a..7aab7bc 100644
|
||||
Binary files a/pixel.png and b/pixel.png differ
|
||||
|
||||
$ cat pixel.png
|
||||
<EFBFBD>PNG
|
||||
▒
|
||||
IHDR7n<EFBFBD>$gAMA<4D><41>
|
||||
<20>abKGD݊<44>tIME<4D>
|
||||
|
||||
-2R<32><52>
|
||||
IDA<EFBFBD>c`<60>!<21>3%tEXtdate:create2020-06-11T11:45:04+12:00<30><30>r.%tEXtdate:modify2020-06-11T11:45:04+12:00<30><30>ʒIEND<4E>B`<60>
|
||||
```
|
||||
|
||||
二进制文件中的数据无法以解析纯文本相同的方式进行解析,因此,如果二进制文件发生任何更改,则必须重写整个内容。一个版本与另一个版本之间的仅有地区别是快速增加的内容。
|
||||
|
||||
更糟糕的是,Git 存储库维护者无法合理地审计二进制数据。这违反了 Rule Zero (头号规则):应该对存储库的内容了如指掌。
|
||||
|
||||
除了常用的 [POSIX(可移植性操作系统接口)][5] 工具之外,您还可以使用 `git diff` 检测二进制文件。当您尝试使用 `--numstat` 选项来比较二进制文件时,Git 返回空结果:
|
||||
|
||||
```
|
||||
$ git diff --numstat /dev/null pixel.png | tee
|
||||
\- - /dev/null => pixel.png
|
||||
$ git diff --numstat /dev/null file.txt | tee
|
||||
5788 0 /dev/null => list.txt
|
||||
```
|
||||
|
||||
如果您正在考虑将二进制大文件提交到存储库,请停下来先思考一下。如果是二进制文件,则它是由什么生成的。 有充分的理由在构建时生成它们来代替将它们提交存储库?你决定提交二进制数据可行,请确保在 README 文件或类似文件中标识二进制文件的位置,为什么是二进制的原因以及更新它们的协议。必须谨慎执行更新,因为对于提交给二进制大文件的每次更改,该二进制大文件的存储空间实际上都会加倍。
|
||||
|
||||
### 保留第三方库
|
||||
|
||||
第三方库也不例外。尽管它是开放源代码的众多优点之一,您可以不受限制地重用和重新分发未编写的代码,但是有很多充分的理由不去覆盖存储在您自己的存储库中第三方库。首先,除非您自己检查了所有代码(以及将来的合并),否则您无法准确确定第三方库。其次,当您将第三方库复制到您的 Git 存储库中时,会将焦点从真正的上游源分离出来。从技术上仅对主库的副本有把握,而不对随机存储库的副本有把握。如果您需要锁定特定版本的库,请为开发人员提供项目所需版本的合理 URL,或者使用[Git 子模块][6]。
|
||||
|
||||
### 抵制盲目的 `git add`
|
||||
|
||||
![Git 手动添加命令终端中][7]
|
||||
|
||||
如果您的项目已编译,请不要使用 `git add .`(其中 `.` 是当前目录或特定文件夹的路径)作为添加任意和每一个新内容的简单方法。如果您不是手动编译项目,而是使用 IDE 为您管理项目,则这一点尤其重要。用 IDE 管理项目时,跟踪添加到存储库中的内容非常困难,因此仅添加您实际编写的内容非常重要,而不是在项目文件夹中弹出的任何新对象。
|
||||
|
||||
如果您使用 `git add .` 做,请在推送之前检查这一状态里的情况。如果在执行 `git status` 时在项目文件夹中看到一个陌生的对象,请在运行 `make clean` 或等效命令找出它的来源以及为什么仍然在项目的目录中。这是非常好的不会在编译期间重新生成的创建方法,因此在提交前请三思。
|
||||
|
||||
### 使用 Git ignore
|
||||
|
||||
![终端中的 `Git ignore` 命令][8]
|
||||
|
||||
为程序员提供的许多方便的创建众说纷纭。任何项目,程序,富有艺术性的或其他的典型项目目录中都充斥着隐藏的文件,元数据和残留的内容。您可以尝试忽略这些对象,但是 `git status` 中的提示越多,您错过某件事的可能性就越大。
|
||||
|
||||
您可以通过维护一个良好的 `gitignore` 文件来为您过滤掉这种噪音。因为这是使用 Git 的用户的共同要求,所以有一些入门 `gitignore` 文件可用。[Github.com/github/gitignore][9] 提供了几个专门创建 `gitignore` 的文件,您可以下载这些文件并将其放置到自己的项目中,几年前 [Gitlab.com][10] 将`gitignore` 模板集成到了存储库创建工作流程中。使用这些帮助您为项目创建适合的 `gitignore` 策略并遵守它。
|
||||
|
||||
### 查看合并请求
|
||||
|
||||
![Git 合并请求][11]
|
||||
|
||||
当您通过电子邮件收到合并或拉取请求或补丁文件时,请勿仅对其进行测试以确保其正常工作。您的工作是阅读新代码进入代码库的并了解其如何产生结果。如果您不同意实施,或者更糟的是,您不理解该实施,请向提交该实施的人发送消息,并要求其进行说明。询问所依赖代码要成为存储库中永久性装置具有优先权,但是这是在你同你的用户的不知道将合并什么到他们将要使用的代码中开启的约定。
|
||||
|
||||
### Git 责任
|
||||
|
||||
社区致力于开源软件良好的安全性。不要鼓励在您的存储库中使用不良的 Git 实践,也不要忽视克隆的存储库中的安全威胁。Git 功能强大,但它仍然只是一个计算机程序,因此要以人为本,确保每个人的安全。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/7/git-repos-best-practices
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[校对者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/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||
[2]: https://securitylab.github.com/research/octopus-scanner-malware-open-source-supply-chain/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/git_repo.png (Git repository )
|
||||
[4]: https://opensource.com/sites/default/files/uploads/git-binary-check.jpg (Git binary check)
|
||||
[5]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[6]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
[7]: https://opensource.com/sites/default/files/uploads/git-cola-manual-add.jpg (Git manual add)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/git-ignore.jpg (Git ignore)
|
||||
[9]: https://github.com/github/gitignore
|
||||
[10]: https://about.gitlab.com/releases/2016/05/22/gitlab-8-8-released
|
||||
[11]: https://opensource.com/sites/default/files/uploads/git_merge_request.png (Git merge request)
|
Loading…
Reference in New Issue
Block a user