Merge pull request #19 from LCTT/master

update from LCTT
This commit is contained in:
perfiffer 2021-09-19 21:25:36 +08:00 committed by GitHub
commit 0eac8270ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 3750 additions and 2083 deletions

View File

@ -0,0 +1,444 @@
[#]: collector: (lujun9972)
[#]: translator: (zpl1025)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13796-1.html)
[#]: subject: (13 of the best React JavaScript frameworks)
[#]: via: (https://opensource.com/article/20/1/react-javascript-frameworks)
[#]: author: (Amit Dua https://opensource.com/users/amitdua)
13 个最好的 React JavaScript 框架
======
> 如果你正在用 React.js 或 React Native 来开发用户界面的话,试试这些框架。
![](https://img.linux.net.cn/data/attachment/album/202109/18/095748k48eskmjpzuhyzuj.jpg)
React.js 和 React Native 都是用来开发用户界面UI的很受欢迎的开源平台。在 StackOverflow 2019 年度开发者调查里两个框架的可取性和使用情况都排名靠前。React.js 是 Facebook 在 2011 年开发的一个 JavaScript 库,来实现跨平台,动态以及高性能的 UI 设计需求;而 React Native 则是 Facebook 在 2015 年发布的框架,目的是使用 JavaScript 构建原生应用。
下面介绍 13 个最好的 React JavaScript 框架,都是开源项目。前 11 个(和 React 一样)都使用 MIT 许可证授权,后面两个使用 Apache 2.0 许可证。
### 1、Create React App
这个 Facebook 开发的命令行工具是 React Native 项目一定要用的。因为 [Create React App][2] 使用很简单,还可以避免你自己手动设定和配置应用,因此能节省大量的时间和精力。仅仅使用给一个简单的命令,就可以为你准备好创建 React 原生项目所需的一切。你可以用它来创建分类和文件,而且该框架还自带了工具用来构建,测试和启动应用。
```
# 安装软件包
$ npm install -g create-react-native-web-app
 
# 运行 create-react-native-web-app <项目目录>
$ create-react-native-web-app myApp
 
# 切换到创建的 <项目目录>
$ cd myApp
 
# 运行 Web/Ios/Android 调试
# Web
$ npm run web
 
# IOS模拟
$ npm run ios
 
# Android实际连接的设备
$ npm run android
```
#### 为什么选择 Create React App
1. 使用配置包、转码器,以及测试运行器进行开发的一流工具
2. 在应用架构里不需要配置以及没有额外文件
3. 确定的开发栈
4. 高效快速的开发工具
### 2、Material Kit React
[Material Kit React][3] 是受谷歌的 Material Design 系统启发开发的,很适合用来创建 React UI 组件。这个库最大的优点是提供了大量的组件,可以互相搭配做出非常好的效果。有超过一千个完全编码的组件,每一个都有用文件夹组织起来的独立层。这样你就可以有上千个选项可以选择。它同时也包含一些示例页面,方便你从中寻找灵感,或者向别人分享你的点子或创意。
#### 安装 Material Kit
```
$ npm install @material-ui/core
```
#### 使用
```
import React from 'react';
import Button from '@material-ui/core/Button';
const App = () => (
  <Button variant="contained" color="primary">
    Hello World
  </Button>
);
```
Material-UI 组件不需要其他额外设置,也不会干扰全局变量空间。
#### 优点
这个 React 组件支持简易快速的网页开发。你可以用它创建自己的设计系统,或者直接开始 Material Design。
### 3、Shards React
这个现代的 React UI 工具为了追求高效率,是从最底层开始构建的。它拥有现代的设计系统,可以让你按自己的想法任意定制。你甚至可以下载源文件,然后从代码级别定制。另外,它用来设计样式的 SCSS 语法提高了开发体验。
[Shards React][4] 基于 Shards使用了 React Datepicker、React Popper一个定位引擎和 noUISlider。还带有非常优秀的 Material Design 图标。还有很多设计好的版本,可以帮你寻找灵感或上手。
#### 用 Yarn 或 NPM 安装 Shards
```
# Yarn
yarn add shards-react
# NPM
npm i shards-react
```
#### 优点
1. Shards 是一个轻量级的脚本,压缩后大概 13kb
2. Shards 默认支持响应式,图层可以适配任意大小屏幕
3. Shards 有完整的文档,可以快速开始构建漂亮的界面
### 4、Styled Components
这个高效的 CSS 工具可以用来为应用的可视界面创建小型可重用的组件。使用传统的 CSS你可能会不小心覆盖掉网站其他位置的选择器但 [Styled Components][5] 通过使用直接内嵌到组件里的 CSS 语法,可以完全避免这个问题。
#### 安装
```
npm install --save styled-components
```
#### 使用
```
const Button = styled.button`
  background: background_type;
  border-radius: radius_value;
  border: abc;
  color: name_of_color;
  Margin: margin_value;
  padding: value`;
```
#### 优点
1. 让组件有更好的可读性
2. 组件样式依赖 JavaScript
3. 创建定制 CSS 组件
4. 内嵌样式
5. 简单地调用 `styled()` 可以将组件甚至是自定义组件转换成样式组件
### 5、Redux
[Redux][6] 是一个为 JavaScript 应用提供状态管理的方案。常用于 React.js也可以用在其他类 React 框架里。
#### 安装
```
sudo npm install redux
sudo npm install react-redux
```
#### 使用
```
import { createStore } from "redux";
import rotateReducer from "reducers/rotateReducer";
function configureStore(state = { rotating: value}) {
  return createStore(rotateReducer,state);
}
export default configureStore;
```
#### 优点
1. 可预计的状态更新有助于定义应用里的数据流
2. 逻辑上测试更简单,使用 reducer 函数进行时间旅行调试也更容易
3. 统一管理状态
### 6、React Virtualized
这个 React Native JavaScript 框架帮助渲染 large-list 和 tabular-data。使用 [React Virtualized][7]你可以限制请求和文档对象模型DOM元素的数量从而提高 React 应用的性能。
#### 安装
```
npm install react-virtualized
```
#### 使用
```
import 'react-virtualized/styles.css'
import { Column, Table } from 'react-virtualized'
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'
import List from 'react-virtualized/dist/commonjs/List'
{
  alias: {
    'react-virtualized/List': 'react-virtualized/dist/es/List',
  },
  ...等等
}
```
#### 优点
1. 高效展示大量数据
2. 渲染超大数据集
3. 使用一系列组件实现虚拟渲染
### 7、React DnD
[React DnD][8] 用来创建复杂的拖放界面。拖放控件库有很多,选用 React DnD 是因为它是基于 HTML5 的拖放 API 的,创建界面更简单。
#### 安装
```
npm install react-dnd-preview
```
#### 使用
```
import Preview from 'react-dnd-preview';
 
const generatePreview = ({itemType, item, style}) => {
  return <div class="item-list" style={style}>{itemType}</div>;
};
class App extends React.Component {
...
  render() {
    return (
      <DndProvider backend={MyBackend}>
        <ItemList />
        <Preview generator={generatePreview} />
        // or
        <Preview>{generatePreview}</Preview>
      </DndProvider>
    );
  }
}
```
#### 优点
1. 漂亮自然的控件移动
2. 强大的键盘和屏幕阅读支持
3. 极限性能
4. 强大整洁的接口
5. 标准浏览器支持非常好
6. 中性样式
7. 没有额外创建 DOM 节点
### 8、React Bootstrap
这个 UI 库将 Bootstrap 的 JavaScript 替换成了 React可以更好地控制每个组件的功能。每个组件都构建成能轻易访问因此 [React Bootstrap][9] 有利于构建前端框架。有上千种 bootstrap 主题可以选择。
#### 安装
```
npm install react-bootstrap bootstrap
```
#### 使用
```
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
```
#### 优点
1. 可以简单导入所需的代码/组件
2. 通过压缩 Bootstrap 节省了输入和问题
3. 通过压缩 Bootstrap 减少了输入工作和冲突
4. 使用简单
5. 使用元素封装
### 9、React Suite
[React Suite][10] 是另一个高效的 React.js 框架,包含了大量组件库,方便开发企业级产品。支持所有主流浏览器和平台,适用于任何系统。还支持服务器端渲染。
#### 安装
```
npm i rsuite --save
```
#### 使用
```
import { Button } from 'rsuite';
import 'rsuite/styles/less/index.less';
ReactDOM.render(<Button>Button</Button>, mountNode);
```
#### 优点
1. 通过全局访问特性轻松管理应用
2. 使用 Redux 库集中管理系统状态
3. Redux 库有灵活的 UI 层,以及广泛的生态
4. Redux 库减少系统复杂度,并提供了全局访问特性
### 10、PrimeReact
[PrimeReact][11] 最值得推荐的是它提供了几乎覆盖所有基本 UI 需求的组件,比如输入选项,菜单,数据展示,消息,等等。这个框架还优化了移动体验,帮助你设计触摸优化的元素。
#### 安装
```
npm install primereact --save
npm install primeicons --save
```
#### 使用
```
import {Dialog} from 'primereact/dialog';
import {Accordion,AccordionTab} from 'primereact/accordion';
dependencies: {
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "react-transition-group": "^2.2.1",
    "classnames": "^2.2.5",
    "primeicons": "^2.0.0"
}
```
#### 优点
1. 简单而高效
2. 容易使用
3. Spring 应用
4. 创建复杂用户界面
5. 好用而简单
### 11、React Router
[React Router][12] 在 React Native 开发社区很受欢迎,因为它上手很容易。只需要你在电脑上安装 Git 和 npm 包管理工具,有 React 的基础知识,以及好学的意愿。没什么特别难的地方。
#### 安装
```
$ npm install --save react-router
```
#### 使用
```
import { Router, Route, Switch } from "react-router";
 
// 使用 CommonJS 模块
var Router = require("react-router").Router;
var Route = require("react-router").Route;
var Switch = require("react-router").Switch;
```
#### 优点
1. 动态路由匹配
2. 在导航时支持不同页面的 CSS 切换
3. 统一的应用结构和行为
### 12、Grommet
[Grommet][13] 常用于开发响应式、可访问的移动网页应用。这个用 Apache 2.0 许可证授权的 JavaScript 框架最大的优点是用很小的包提供了可访问性、模块化、响应式以及主题功能。这可能是它被一些公司广泛使用的主要原因,比如奈飞、通用电气、优步以及波音。
#### 安装 for yarn and npm
```
$ npm install grommet styled-components --save
```
#### 使用
```
"grommet-controls/chartjs": {
          "transform": "grommet-controls/es6/chartjs/${member}",
          "preventFullImport": true,
          "skipDefaultConversion": true
```
#### 优点
1. 创建一个工具包来打包
2. 把开放政策发挥到极致
3. 重构有助于影响已成立的组织
### 13、Onsen UI
[Onsen UI][14] 另一个使用 HTML5 和 JavaScript 的手机应用开发框架,集成了 Angular、Vue 和 React使用 Apache 2.0 许可证授权。
Onsen 提供了标签、侧边栏、堆栈导航以及其他组件。这个框架最好的地方是,它所有的组件都支持 iOS 和安卓 Material Design 自动适配,会根据不同的平台切换应用的外观。
#### 安装
```
npm install onsenui
```
#### 使用
```
(function() {
    'use strict';
    var module = angular.module('app', ['onsen']);
    module.controller('AppController', function($scope) {
      // more to come here
    });
})();
```
#### 优点
1. Onsen UI 基于自由而开源代码
2. 不强制基于它开发的应用使用任何形式的 DRM
3. 内置了 JavaScript 和 HTML5 代码
4. 给最终用户带来原生体验
* * *
你最喜欢哪个 React JavaScript 框架?请在评论区分享。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/1/react-javascript-frameworks
作者:[Amit Dua][a]
选题:[lujun9972][b]
译者:[zpl1025](https://github.com/zpl1025)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/amitdua
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_javascript.jpg?itok=60evKmGl (Javascript code close-up with neon graphic overlay)
[2]: https://github.com/facebook/create-react-app
[3]: https://github.com/creativetimofficial/material-kit-react
[4]: https://github.com/DesignRevision/shards-react
[5]: https://github.com/styled-components/styled-components
[6]: https://github.com/reduxjs/redux
[7]: https://github.com/bvaughn/react-virtualized
[8]: https://github.com/react-dnd/react-dnd/
[9]: https://github.com/react-bootstrap/react-bootstrap
[10]: https://github.com/rsuite/rsuite
[11]: https://github.com/primefaces/primereact
[12]: https://github.com/ReactTraining/react-router
[13]: https://github.com/grommet/grommet
[14]: https://github.com/OnsenUI/OnsenUI

View File

@ -0,0 +1,250 @@
[#]: subject: "How to Easily Install Debian Linux"
[#]: via: "https://itsfoss.com/install-debian-easily/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "guevaraya"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13789-1.html"
如何轻松安装 Debian Linux 系统
======
![](https://img.linux.net.cn/data/attachment/album/202109/16/123647x9uz7zjjqrq0qwkk.jpg)
安装 Debian 的轻松程度依赖于选择什么镜像。
如果你使用 Debain 官网的默认 ISO 镜像,安装 Debian 就比较费劲。你会卡在这种界面,让你从外部可移动介质上安装网络驱动。
![对于新用户来说,从默认的 ISO 中安装 Debian 是有问题的][1]
当然你可以花时间去排除这个故障,但这让事情变得没有必要的复杂。
不用担心,让我来展示如何轻松地简单安装 Debian。
### 轻松安装 Debian 桌面系统的方法
在你查看这些步骤之前,请确认以下准备工作:
* 一个至少 4GB 大小的 USB 盘。
* 一个连接了互联网的系统(可以是要安装 Debian 的同一个机器)。
* 一个要安装的 Debian 的机器。它将会清理掉系统上所有数据,因此请复制重要数据到其他外部磁盘
你需要为 Debian 准备什么样配置的机器?这取决于你想用什么类型的 [桌面环境][2]。例如GNOME 桌面系统可以在 4GB 内存上运行,但在 8GB 内存上更流畅一些。如果你只有 4GB 或更少的内存,还是建议尝试 KDE、Cinnamon 或 Xfce 桌面系统。
Debian 支持 [32 位和 64 位的指令架构][3]。你需要根据你的 CPU 指令架构选择对应的 Debian ISO 镜像。
你的系统应该至少要有 25GB 可用的硬盘空间。越多越好。
> **警告!**
>
> 这个方法会移除磁盘上所有其他操作系统及其数据。
>
> 你可以保存你后面还需要用的个人信息、文档、照片等到外部 USB 盘或云存储中。
在这个教程中,我将展示安装带有 GNOME 桌面环境的 Debian 11 Bullseye 的步骤。即使你选择其他的桌面环境,步骤也应该是一样的。
这个教程是在 GPT 分区的 UEFI 系统上测试的。如果你的系统是 [MBR 而不是 GPT][4],或是 [传统的 BIOS 而不是 UEFI][5],那么创建<ruby>临场<rt>Live</rt></ruby> USB 盘的步骤有一点不同。
#### 步骤 1获取正确的 Debian ISO 镜像
在安装 Debian 过程中,选择正确的 ISO 镜像就已经成功一半了。令人惊讶的是,对于一个新的 Debian 用户来说,要浏览 Debian 的网站并找到最轻松好用的 ISO 真的很困难。
如果你点击 Debian 官网的下载按钮,它会下载一个最小化的网络安装文件,这对普通用户来说是非常复杂的。请 **不要** 使用这个。
反而,你应该用<ruby>临场<rt>Live</rt></ruby> ISO。但这里要注意有一些单独的含有非自由软件以包括网络硬件的驱动程序的版本。
你应该下载这个非自由版的临场 ISO 镜像。不过另一个问题是,你不会在网站的显著位置注意到它,而且有各种架构的 BT 种子或直接下载的 URL。
让我把这些链接放在这里:
- [32 位和 64 位的主仓地址][7]
- [Debian 11 官方下载][8]
- [Debian 11 种子地址][9]
你会看到几个文件,文件名中提到了桌面环境。选择一种你要的桌面环境。直接下载的话,直接点击 .iso 结尾的链接即可。
![下载非自由版的临场 Debian ISO][10]
一旦你有了对应的 ISO 下载包,剩下就是和其他 Linux 发行版一样的标准安装流程了。
#### 步骤 2: 创建一个 Debian 的临场 USB 盘
将 USB 盘插入你的系统。在用之前最好格式化一下,反正它最终也会被格式化的。
你可以根据你的选择使用任何临场 USB 创建工具。如果你使用 Windows可以使用 Rufus。我们在这里使用 Etcher因为这个工具在 Windows 和 Linux 都可以用。
从它的官网下载 Etcher。
- [下载 Etcher][11]
我专门写过一篇 [在 Linux 下使用 Etcher 的教程][12],因此这里我就不深入介绍了。只要运行下载的可执行程序,浏览找到 Debian 的 ISO 镜像,确认选择正确的 USB 盘,然后点击 “Flash” 按钮即可。
![用 Etcher 创建 Debian 的临场 USB 盘][13]
不一会就创建好临场 USB 盘了。创建好之后,就可以开机引导了。
#### 步骤 3从临场 USB 盘引导启动
重启你要安装 Debian 的机器。当显示制造商标识的时候,按下 `F2`、`F10` 或 `F12` 等键进入开机引导设置界面。你也可以从 Windows [进入到 UEFI 固件设置界面][14]。
有些机器如果启用了<ruby>安全启动<rt>secure boot</rt></ruby>功能,就不允许从临场 USB 盘引导。如果是这种情况,请 [从 BIOS 设置里禁用安全启动][15]
不同的的制造商在界面上会有一些差异。
![][16]
你在 BIOS 里做了修改之后,按下 `F10` 保存并退出。你的系统将会重新启动。
再一次,当看到制造商的标识后按下 `F2`、`F10` 或 `F12` 查看引导配置。你应该可以看到从 USB 引导的选项,然后选中它。
![][17]
一会儿就会看到如下图的显示界面,选择第一个选项。
![Debian 启动界面][18]
#### 步骤 4: 开始安装 Debian
当你进入临场 Debian 会话,如果你使用 GNONE 桌面,它呈现一个欢迎界面,可以在此选择你的键盘和语言。当你看到这些界面时,只需要点击下一步。
![Debian 临场欢迎界面][19]
欢迎界面之后,按下 `Windows` / `Super` 键进入活动区。你应该可以看到 Debian 的安装按钮。
![开始安装 Debian][20]
它会打开一个友好的 [Calamares 图形安装器][21]。从这里开始事情就比较简单了,
![Debian 11 Calamares 图形安装器][22]
它会让你选择你的地理位置和时区。
![选择你的地理位置和时区][23]
下一个界面,会让你选择键盘类型。这儿请 **注意**。你的键盘会根据你所选的位置自动选择。例如,我的位置是印度,它会自动默认选择印度键盘和印地语。我需要将其改为印度英语。
![选择键盘类型][24]
下一个界面是关于磁盘分区和要安装 Debian 的地方。在本文中,把 Debian 作为你电脑上唯一的操作系统来安装。
最简单的方法是直接选择 “<ruby>擦除磁盘<rt>Erase Disk</rt></ruby>”。除了必须的 ESP 分区和交换分区外Debian 会把其他所有东西都放在根挂载点(`/`)上。实际上,下面显示了你所选的安装方式后的磁盘布局。
![磁盘分区][25]
如果你想把事情掌握在自己手中,你也可以选择手动分区,选择分配给 `/`、`/home`、`/boot` 或交换分区的大小。只有在你知道自己在做什么时,才可以这样做。
下一界面,你需要提供用户名和密码。但它不会设置 root 的密码,并将其保持为空。
![设置用户名和密码][26]
这也意味着你可以用新创建的用户使用 `sudo` 。在“复杂的 Debian 安装”中,你也可以设置 root 密码,但这样你就必须手动将普通用户添加到 `sudoer` 列表。看看,这种安装过程是不是对新手来说很容易?
在继续实际安装之前,它会呈现你所做的选择的汇总信息。如果没有问题,就可以点击“<ruby>安装<rt>Install</rt></ruby>”按钮。
![安装配置的汇总信息][27]
现在只需要等待安装完成。
![安装 Debian][28]
几分钟后就会完成安装。当安装完成,它会提示重启。
![完成 Debian 安装][29]
重启系统后如果一切顺利,你应该可以看到 Debian 的 GRUB 界面。
![Debian 启动画面][30]
### 疑难解答(如果系统没有启动到 Debian
我遇到情况是,我的 Dell 系统不能识别任何要引导的操作系统。这很奇怪,我看见 Debian 经创建了一个 ESP 分区。
如果你也是同样的情况,进去 BIOS 配置里。检查<ruby>启动顺序<rt>Boot Sequence</rt></ruby>,如果你看不到任何东西,就点击“<ruby>新增引导选项<rt>Add Boot Option</rt></ruby>”。
![增加新的启动选项][31]
它会提供一个增加 EFI 文件的选项。
![选择 EFI 文件][32]
由于在安装过程中 Debian 创建了 ESP 分区,因此一个包含必要文件的 `EFI` 目录已经创建好了。
![选择 EFI 目录][33]
它会显示一个 `Debian` 目录及其他目录。选择 `Debian` 目录。
![选择 Debian 目录][34]
`Debian` 目录,你将看到 `grubx64.efi`、`shimx64.efi` 等文件。请选择 `shimx64.efi`
![选择 shimx64.efi][35]
你需要给这个文件一个合适的名字。最后的界面应该如下:
![增加 efi 文件的新启动选项][36]
现在你应该有了这个启动选项。因为我命名为 `Debian`,它显示了两个 `Debian` 引导选项(我猜其中一个是从 efi 文件来的)。按下 `F10` 保存退出 BIOS 的配置。
![新增的启动选项][37]
现在启动你的系统,你可以看到带有 Debian 启动选项的 GRUB 界面了。你现在可以体验 Debian 了。
![][30]
### 你能安装 Debian 吗?
我写这篇文章的目的是让事情变得轻松点。并不是说你不能从默认的网络安装程序 ISO 来安装,只是它需要花更多的精力。
这个教程对你安装 Debian 有帮助吗?你如果还是有问题,请在下面留言给我,我会尽力提供帮助。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-debian-easily/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[巴龙](https://github.com/guevaraya)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Debian-firmware.png?resize=800%2C600&ssl=1
[2]: https://itsfoss.com/what-is-desktop-environment/
[3]: https://itsfoss.com/32-bit-64-bit-ubuntu/
[4]: https://itsfoss.com/check-mbr-or-gpt/
[5]: https://itsfoss.com/check-uefi-or-bios/
[6]: https://www.debian.org/
[7]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/
[8]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/amd64/iso-hybrid/
[9]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/amd64/bt-hybrid/
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/downloading-Debian-live-non-free-iso.png?resize=800%2C490&ssl=1
[11]: https://www.balena.io/etcher/
[12]: https://itsfoss.com/install-etcher-linux/
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/creating-live-debian-usb-with-etcher-800x518.png?resize=800%2C518&ssl=1
[14]: https://itsfoss.com/access-uefi-settings-windows-10/
[15]: https://itsfoss.com/disable-secure-boot-windows/
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2014/05/Disable_Secure_Boot_Windows8.jpg?resize=700%2C525&ssl=1
[17]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/boot-from-windows-disk-ventoy.jpg?resize=800%2C611&ssl=1
[18]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/debian-live-boot-screen.png?resize=617%2C432&ssl=1
[19]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/debian-live-welcome-screen.png?resize=800%2C450&ssl=1
[20]: https://itsfoss.com/wp-content/uploads/2021/08/start-Debian-installation-800x473.webp
[21]: https://calamares.io/
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-1.png?resize=800%2C441&ssl=1
[23]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-2-800x441.webp
[24]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-4-800x441.webp
[25]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-5.png?resize=800%2C441&ssl=1
[26]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-6.png?resize=800%2C441&ssl=1
[27]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-7-800x500.webp
[28]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-8.png?resize=800%2C500&ssl=1
[29]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-9.png?resize=800%2C500&ssl=1
[30]: https://itsfoss.com/wp-content/uploads/2021/08/debian-boot-screen.webp
[31]: https://itsfoss.com/wp-content/uploads/2021/08/add-new-boot-option.webp
[32]: https://itsfoss.com/wp-content/uploads/2021/08/add-efi-file-for-boot-option.webp
[33]: https://itsfoss.com/wp-content/uploads/2021/08/select-efi-file-boot-option.webp
[34]: https://itsfoss.com/wp-content/uploads/2021/08/select-debian-folder-for-uefi.webp
[35]: https://itsfoss.com/wp-content/uploads/2021/08/select-shim-boot.webp
[36]: https://itsfoss.com/wp-content/uploads/2021/08/new-boot-option.webp
[37]: https://itsfoss.com/wp-content/uploads/2021/08/new-boot-option-added.webp

View File

@ -3,18 +3,18 @@
[#]: author: "Nived V https://opensource.com/users/nivedv"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "turbokernel"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13792-1.html"
容器的四大基础技术
======
> 命名空间、控制组、seccomp 和 SELinux 构成了在你的系统上构建和运行一个容器进程的 Linux 技术基础。
> 命名空间、控制组、seccomp 和 SELinux 构成了在系统上构建和运行一个容器进程的 Linux 技术基础。
![企鹅驾驶一辆黄色背景的汽车][1]
![](https://img.linux.net.cn/data/attachment/album/202109/17/085439ye0iq5ynzyhpusy5.jpg)
在以前的文章中,我介绍过 [容器镜像][2] 及其 [运行时][3]。在这篇文章中,我研究了容器是如何在一些特殊的 Linux 技术基础上实现的,这些技术包括命名空间和控制组。
在以前的文章中,我介绍过 [容器镜像][2] 及其 [运行时][3]。在本文中,我研究了容器是如何在一些特殊的 Linux 技术基础上实现的,这其中包括命名空间和控制组。
![容器技术的层次][4]
@ -29,7 +29,7 @@
### 命名空间
<ruby>命名空间<rt>namespace</rt></ruby> 为容器提供了一个隔离层,给容器提供了一个看起来是它自己的 Linux 文件系统的视图。这就限制了进程所能看到的东西,从而限制了它所能获得的资源。
<ruby>命名空间<rt>namespace</rt></ruby> 为容器提供了一个隔离层,给容器提供了一个看起来是独占的 Linux 文件系统的视图。这就限制了进程能访问的内容,从而限制了它所能获得的资源。
在创建容器时Docker 或 Podman 和其他容器技术使用了 Linux 内核中的几个命名空间:
@ -48,15 +48,15 @@
```
#### 用户
用户(`user`)命名空间将用户和组隔离在一个容器内。这是通过允许容器与宿主系统有不同的 UID 和 GID 范围来实现的。用户命名空间使软件能够以 root 用户的身份在容器内运行。如果入侵者攻击容器,然后逃逸到宿主机上,他们就受限于只能以非 root身份出现了。
用户(`user`)命名空间将用户和组隔离在一个容器内。这是通过分配给容器与宿主系统有不同的 UID 和 GID 范围来实现的。用户命名空间使软件能够以 root 用户的身份在容器内运行。如果入侵者攻击容器,然后逃逸到宿主机上,他们就只能以受限的非 root 身份运行了。
#### 挂载
挂载(`mnt`)命名空间允许容器对系统的文件系统层次结构有自己的视图。你可以在 Linux 系统中的 `/proc/<PID>/mounts` 位置找到每个容器进程的挂载点。
挂载(`mnt`)命名空间允许容器有自己的文件系统层次结构视图。你可以在 Linux 系统中的 `/proc/<PID>/mounts` 位置找到每个容器进程的挂载点。
#### UTS
<ruby>Unix 分时系统<rt>Unix Timeharing System</rt></ruby>UTS命名空间允许容器有一个唯一主机名和域名。当你运行一个容器时,即使使用 `- name` 标签,也会使用一个随机的 ID 作为主机名。你可以使用 [unshare 命令][6] 来了解一下这个工作原理。
<ruby>Unix 分时系统<rt>Unix Timeharing System</rt></ruby>UTS命名空间允许容器有一个唯一主机名和域名。当你运行一个容器时,即使使用 `- name` 标签,也会使用一个随机的 ID 作为主机名。你可以使用 [unshare 命令][6] 来了解一下这个工作原理。
```
nivedv@homelab ~]$ docker container run -it --name nived alpine sh
@ -76,7 +76,7 @@ homelab.redhat.com
#### IPC
<ruby>进程间通信<rt>Inter-Process Communication</rt></ruby>IPC命名空间允许不同的容器进程通过访问共享内存或使用共享消息队列来进行通信。
<ruby>进程间通信<rt>Inter-Process Communication</rt></ruby>IPC命名空间允许不同的容器进程之间,通过访问共享内存或使用共享消息队列来进行通信。
```
[root@demo /]# ipcmk -M 10M
@ -97,11 +97,11 @@ key semid owner perms nsems
#### PID
<ruby>进程 ID<rt>Process ID</rt></ruby>PID命名空间确保在容器内运行的进程与外部世界隔离。当你在容器内运行 `ps` 命令时,由于这个命名空间的存在,你只能看到在容器内运行的进程,而不是在宿主机上。
<ruby>进程 ID<rt>Process ID</rt></ruby>PID命名空间确保运行在容器内的进程与外部隔离。当你在容器内运行 `ps` 命令时,由于这个命名空间隔离的存在,你只能看到在容器内运行的进程,而不是在宿主机上。
#### 网络
网络(`net`)命名空间允许容器网络接口、IP 地址、路由表、端口号等有自己的视图。容器如何能够与外部世界沟通?你创建的所有容器都会被附加到一个特殊的虚拟网络接口上进行通信。
网络(`net`)命名空间允许容器有自己网络接口、IP 地址、路由表、端口号等视图。容器如何能够与外部通?你创建的所有容器都会被附加到一个特殊的虚拟网络接口上进行通信。
```
[nivedv@homelab ~]$ docker container run --rm -it alpine sh
@ -117,7 +117,7 @@ master docker0 state UP mode DEFAULT group default
### 控制组
控制组(`cgroup`)是制作一个容器的基本模块。控制组会分配和限制资源,如 CPU、内存、网络 I/O 等,这些资源被容器所使用。容器引擎会自动创建每种类型的控制组文件系统,并在容器运行时为每个容器设置
控制组(`cgroup`)是组成一个容器的基本模块。控制组会分配和限制容器所使用的资源,如 CPU、内存、网络 I/O 等。容器引擎会自动创建每种类型的控制组文件系统,并在容器运行时为每个容器设置配额
```
[root@homelab ~]# lscgroup | grep docker
@ -133,7 +133,7 @@ blkio:/docker
pids:/docker
```
容器运行时为每个容器设置了控制组值,所有信息都存储在 `/sys/fs/cgroup/*/docker`。下面的命令将确保容器可以使用 50000 微秒的 CPU 时间,并将内存的软、硬限制分别设置为 500M 和 1G。
容器运行时为每个容器设置了控制组值,所有信息都存储在 `/sys/fs/cgroup/*/docker`。下面的命令将确保容器可以使用 50000 微秒的 CPU 时间,并将内存的软、硬限制分别设置为 500M 和 1G。
```
[root@homelab ~]# docker container run -d --name test-cgroups --cpus 0.5 --memory 1G --memory-reservation 500M httpd
@ -154,13 +154,13 @@ memory:/docker/c3503ac704dafea3522d3bb82c77faff840018e857a2a7f669065f05c8b2cc84
### SECCOMP
Seccomp 意思是“<ruby>安全计算<rt>secure computing</rt></ruby>”。它是一项 Linux 功能,用于限制应用程序允许进行的系统调用的集合。例如Docker 的默认 seccomp 配置文件禁用了大约 44 个系统调用(总计超过 300 个)。
Seccomp 意思是“<ruby>安全计算<rt>secure computing</rt></ruby>”。它是一项 Linux 功能用于限制应用程序进行的系统调用的集合。例如Docker 的默认 seccomp 配置文件禁用了大约 44 个系统调用(总计超过 300 个)。
这里的思路是让容器只访问容器可能需要的那些资源。例如,如果你不需要容器改变主机上的时钟时间,你可能不会使用 `clock_adjtime``clock_settime` 系统调用,屏蔽它们是合理的。同样地,你不希望容器改变内核模块,所以没有必要让它们进行 `create_module``delete_module` 系统调用。
这里的思路是让容器只访问所必须的资源。例如,如果你不需要容器改变主机上的时钟时间,你可能不会使用 `clock_adjtime``clock_settime` 系统调用,屏蔽它们是合理的。同样地,你不希望容器改变内核模块,所以没有必要让它们使用 `create_module``delete_module` 系统调用。
### SELinux
SELinux 是“<ruby>安全增强的 Linux<rt>security-enhanced Linux</rt></ruby>”的缩写。如果你在你的宿主机上运行的是 Red Hat 发行版,那么 SELinux 是默认启用的。SELinux 可以让你限制一个应用程序只能访问它自己的文件,并阻止任何其他进程访问它们。因此,如果一个应用程序被破坏了,它将限制该应用程序可以影响或控制的文件数量。通过为文件和进程设置上下文环境以及定义策略来实现这一目的,这些策略将强制执行一个进程可以看到和改变的内容。
SELinux 是“<ruby>安全增强的 Linux<rt>security-enhanced Linux</rt></ruby>”的缩写。如果你在你的宿主机上运行的是 Red Hat 发行版,那么 SELinux 是默认启用的。SELinux 可以让你限制一个应用程序只能访问它自己的文件,并阻止任何其他进程访问。因此,如果一个应用程序被破坏了,它将限制该应用程序可以影响或控制的文件数量。通过为文件和进程设置上下文环境以及定义策略来实现,这些策略将限制一个进程可以访问和更改的内容。
容器的 SELinux 策略是由 `container-selinux` 包定义的。默认情况下,容器以 `container_t` 标签运行,允许在 `/usr` 目录下读取(`r`)和执行(`x`),并从 `/etc` 目录下读取大部分内容。标签`container_var_lib_t` 是与容器有关的文件的通用标签。
@ -177,15 +177,15 @@ via: https://opensource.com/article/21/8/container-linux-technology
作者:[Nived V][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[校对者ID](https://github.com/校对者ID)
校对:[turbokernel](https://github.com/turbokernel)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/nivedv
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
[2]: https://opensource.com/article/21/8/container-fundamentals-2
[3]: https://opensource.com/article/21/8/deep-dive-container-runtimes
[2]: https://linux.cn/article-13766-1.html
[3]: https://linux.cn/article-13772-1.html
[4]: https://opensource.com/sites/default/files/1linuxtechs.png (layers of linux technologies)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://opensource.com/article/19/10/namespaces-and-containers-linux

View File

@ -4,13 +4,15 @@
[#]: collector: "lujun9972"
[#]: translator: "unigeorge"
[#]: reviewer: "turbokernel"
[#]: publisher: " "
[#]: url: " "
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13793-1.html"
在 Linux 上使用 lspci 命令查看硬件情况
======
lspci 命令用于显示 Linux 系统上的设备和驱动程序。
![computer screen ][1]
> lspci 命令用于显示 Linux 系统上的设备和驱动程序。
![](https://img.linux.net.cn/data/attachment/album/202109/17/091425l7c8au5c865x7q68.jpg)
当你在个人电脑或服务器上运行 Linux 时,有时需要识别该系统中的硬件。`lspci` 命令用于显示连接到 PCI 总线的所有设备,从而满足上述需求。该命令由 [pciutils][2] 包提供,可用于各种基于 Linux 和 BSD 的操作系统。
@ -50,7 +52,7 @@ $ sudo lspci
### 详细输出
添加 `-v` 选项会显示每个设备的详细信息,你可以使用 `-vv``-vvv` 来获取更多的设备细节。在 `-v` 级别,`lspci` 会显示所有设备的各种子系统和内存地址、中断请求 (IRQ) 编号和一些其他功能信息。输出信息会非常长。在你的系统上试一试吧。
添加 `-v` 选项会显示每个设备的详细信息,你可以使用 `-vv``-vvv` 来获取更多的设备细节。在 `-v` 级别,`lspci` 会显示所有设备的各种子系统和内存地址、中断请求IRQ编号和一些其他功能信息。输出信息会非常长。在你的系统上试一试吧。
### 使用 grep 过滤搜索
@ -81,7 +83,7 @@ $ sudo lspci -nn | grep -e VGA
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK107 [GeForce GTX 650] [10de:0fc6] (rev a1)
```
设备名称后的方括号内有用冒号分隔的数字,即供应商和设备 ID。输出表明 Nvidia Corporation 制造的设备的供应商 ID 为 **10de**
设备名称后的方括号内有用冒号分隔的数字,即供应商和设备 ID。输出表明 Nvidia Corporation 制造的设备的供应商 ID 为 `10de`
`-d` 选项用于指定供应商、设备或类 ID 的所有设备。以下是我系统中的所有 Nvidia 设备(保留 `-nn` 以解析供应商 ID
@ -109,14 +111,14 @@ $ sudo lspci -nn -k -d 10de:
 Kernel modules: snd_hda_intel
```
可以看到额外显示了两行:<ruby>_正在使用的内核驱动程序_<rt><rp>(</rp>Kernel driver in use<rp>)</rp></rt></ruby><ruby>_内核模块_<rt><rp>(</rp>Kernel modules<rp>)</rp></rt></ruby>,其中后者列出了可用于支持该设备的模块。
可以看到额外显示了两行:<ruby>正在使用的内核驱动程序<rt>Kernel driver in use</rt></ruby><ruby>内核模块<rt>Kernel modules</rt></ruby>,其中后者列出了可用于支持该设备的模块。
### 同步最新状态
新设备和供应商总是在不断迭代。如果看到显示为 _unknown_ 的设备,说明你的 PCI 设备 ID 数据库可能已过时。有两种方法可以检查更新。`-Q` 选项会使用 DNS 查询中央数据库,当然,这需要联网。
新设备和供应商总是在不断迭代。如果看到显示为 `unknown` 的设备,说明你的 PCI 设备 ID 数据库可能已过时。有两种方法可以检查更新。`-Q` 选项会使用 DNS 查询中央数据库,当然,这需要联网。
```
`$ sudo lspci -Q`
$ sudo lspci -Q
```
你还可以通过运行命令 `update-pciids` 来更新本地 PCI ID 数据库。

View File

@ -3,71 +3,56 @@
[#]: author: "Jim Hall https://opensource.com/users/jim-hall"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13795-1.html"
从命令行调试网页错误
从命令行使用 wget 调试网页错误
======
调试网络服务器的一种方法是使用 wget 命令行程序。
![Digital creative of a browser on the internet][1]
有时在管理一个网站时,事情会被搞得一团糟。你可能会删除一些陈旧的内容,用重定向到其他页面来代替。后来,在做了其他改动后,你发现一些网页变得完全无法访问了。你可能会在浏览器中看到一个错误:“该页面没有正确重定向”,并建议你检查你的 cookies。
> 调试 Web 服务器的一种方法是使用 wget 命令行程序。
![](https://img.linux.net.cn/data/attachment/album/202109/17/225018elcip4pii4qcknir.jpg)
有时在管理一个网站时,事情会被搞得一团糟。你可能会删除一些陈旧的内容,用重定向到其他页面来代替。后来,在做了其他改动后,你发现一些网页变得完全无法访问了。你可能会在浏览器中看到一个错误:“该页面没有正确重定向”,并建议你检查你的 cookie。
![Redirect loop example in Firefox][2]
Screenshot by Jim Hall[CC-BY SA 4.0][3]
调试这种情况的一个方法是使用 `wget` 命令行程序,使用 `-S` 选项来显示所有的服务器响应。当使用 `wget` 进行调试时,我也喜欢使用 `-O` 选项将输出保存到一些临时文件中,以备以后需要查看其内容。
```
$ wget -O /tmp/test.html -S <http://10.0.0.11/announce/>
\--2021-08-24 17:09:49-- <http://10.0.0.11/announce/>
$ wget -O /tmp/test.html -S http://10.0.0.11/announce/
--2021-08-24 17:09:49-- http://10.0.0.11/announce/
Connecting to 10.0.0.11:80... connected.
HTTP request sent, awaiting response...
HTTP request sent, awaiting response...
HTTP/1.1 302 Found
Date: Tue, 24 Aug 2021 22:09:49 GMT
Server: Apache/2.4.48 (Fedora)
X-Powered-By: PHP/7.4.21
Location: <http://10.0.0.11/assets/>
Location: http://10.0.0.11/assets/
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Location: <http://10.0.0.11/assets/> [following]
\--2021-08-24 17:09:49-- <http://10.0.0.11/assets/>
Location: http://10.0.0.11/assets/ [following]
--2021-08-24 17:09:49-- http://10.0.0.11/assets/
Reusing existing connection to 10.0.0.11:80.
HTTP request sent, awaiting response...
HTTP request sent, awaiting response...
HTTP/1.1 302 Found
Date: Tue, 24 Aug 2021 22:09:49 GMT
Server: Apache/2.4.48 (Fedora)
X-Powered-By: PHP/7.4.21
Location: <http://10.0.0.11/announce/>
Location: http://10.0.0.11/announce/
Content-Length: 0
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Location: <http://10.0.0.11/announce/> [following]
\--2021-08-24 17:09:49-- <http://10.0.0.11/announce/>
Location: http://10.0.0.11/announce/ [following]
--2021-08-24 17:09:49-- http://10.0.0.11/announce/
Reusing existing connection to 10.0.0.11:80.
.
.
@ -84,7 +69,7 @@ via: https://opensource.com/article/21/9/wget-debug-web-server
作者:[Jim Hall][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/) 荣誉推出

View File

@ -3,14 +3,16 @@
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13790-1.html"
如何在 Ubuntu 中运行 Java 程序
======
那么,你已经开始学习 Java 编程了?这很好。
![](https://img.linux.net.cn/data/attachment/album/202109/16/163803pn2dja7ajcx8jjw2.jpg)
听说,你已经开始学习 Java 编程了?很好。
你想在你的 Linux 系统上运行 Java 程序?那就更好了。
@ -24,7 +26,7 @@
要运行一个 Java 程序,你需要先编译该程序。为此你需要 Java 编译器。
Java 编译器是 [JDK][1]Java 开发工具包)的一部分。你需要安装 JDK以便编译和运行 Java 程序。
Java 编译器是 [JDK][1]<ruby>Java 开发工具包<rt>Java Development Kit</rt></ruby>)的一部分。你需要安装 JDK以便编译和运行 Java 程序。
首先,检查你的系统上是否已经安装了 Java 编译器:
@ -42,19 +44,19 @@ javac --version
sudo apt install default-jdk
```
你会被要求输入你的账户密码。当你输入密码时,屏幕上什么也看不到。这很正常。直接输入密码即可。当询问时,按回车键或 Y 键。
你会被要求输入你的账户密码。当你输入密码时,屏幕上什么也看不到。这很正常。直接输入密码即可。当询问时,按回车键或 `Y` 键。
![Installing JDK that also contains the Java compiler][3]
上述命令应该适用于其他基于 Debian 和 Ubuntu 的发行版,如 Linux Mint、Elementary OS 等。对于其他发行版,请使用你的发行版的包管理器。包的名称也可能不同。
安装完毕后,验证 javac 现在是否可用。
安装完毕后,验证 `javac` 现在是否可用。
![Verify that Java compiler can be used now][4]
#### 第二步:在 Linux 中编译 Java 程序
因为这个原因,你需要有一个 Java 程序文件。假设你创建了一个名为 **HelloWorld.java** 的新的 Java 程序文件,它的内容如下:
要编译的话,你首先需要有一个 Java 程序文件。假设你创建了一个名为 `HelloWorld.java` 的新的 Java 程序文件,它的内容如下:
```
class HelloWorld{
@ -64,7 +66,7 @@ class HelloWorld{
}
```
你可以[使用终端的 Nano 编辑器][5]或 Gedit 图形化文本编辑器来编写你的 Java 程序。
你可以 [使用终端的 Nano 编辑器][5] 或 Gedit 图形化文本编辑器来编写你的 Java 程序。
```
javac HelloWorld.java
@ -76,13 +78,13 @@ javac HelloWorld.java
#### 第三步:运行 Java 类文件
你不需要在这里指定类的扩展名。只需要类的名称。而这一次,你使用 java 命令,而不是 javac。
你不需要在这里指定类的扩展名。只需要类的名称。而这一次,你使用 `java` 命令,而不是 `javac`
```
java HelloWorld
```
我的程序将在屏幕上打印 Hello World。
我的程序将在屏幕上打印 Hello World
![Running java programs in the Linux terminal][6]
@ -90,7 +92,7 @@ java HelloWorld
这是最简单的一个例子。这个示例程序只有一个类。Java 编译器为你程序中的每个类都创建一个类文件。对于较大的程序和项目来说,事情会变得很复杂。
这就是为什么我建议[在 Ubuntu 上安装 Eclipse][7]来进行 Java 编程。在 IDE 中编程更容易。
这就是为什么我建议 [在 Ubuntu 上安装 Eclipse][7] 来进行 Java 编程。在 IDE 中编程更容易。
希望本教程对你有所帮助。有问题或建议吗?评论区都是你的。
@ -101,7 +103,7 @@ via: https://itsfoss.com/run-java-program-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/) 荣誉推出

View File

@ -3,38 +3,38 @@
[#]: author: "Quinn Foster https://opensource.com/users/quinn-foster"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13800-1.html"
构建开源的社区健康分析平台
======
一个学术性的 OSPO 正在与 CHAOSS 软件合作以建立一个社区健康分析平台。
![metrics and data shown on a computer screen][1]
罗切斯特理工学院RIT最近在增加其在开源世界的存在方面取得了相当大的进展。例如其开源项目办公室Open@RIT已经开始帮助 RIT 的教职员工为他们的开源项目建立和维护社区
> 一个学术性的 OSPO 正在与 CHAOSS 软件合作,以建立一个社区健康分析平台。
这些进展是由 RIT 的学生、教师和工作人员推动的。目前,大学里已经有越来越多的人在领导他们自己的开放项目。然而,运行一个完全的开源项目可能是很麻烦的。这主要来自于维护项目的社区和管理数据,如项目的代码、问题跟踪和仓库。
![](https://img.linux.net.cn/data/attachment/album/202109/19/100755mlngkwvvwjjlblgn.png)
为了帮助这些人Open@RIT 正在创建一个名为 Mystic 的系统,这是一个社区健康分析平台,利用了 [GrimoireLab][2],这是一个由 [CHAOSS][3] 软件开发的开源工具包为开源项目提供指标和分析。GrimoireLab 允许用户收集、丰富、过滤和可视化一个项目的数据,例如一个报告的问题被解决的时间、贡献者的关系等。
<ruby>罗切斯特理工学院<rt>Rochester Institute of Technology</rt></ruby>RIT最近在增加其在开源世界的影响力方面取得了相当大的进展。RIT的自由和开源软件及自由文化辅修课程是学术界的第一个此类课程。例如其开源项目办公室 Open@RIT 已经开始帮助 RIT 的教职员工和研究员为他们的开源项目建立和维护社区。
这些进展是由 RIT 的学生、教师和工作人员推动的。目前,大学里已经有越来越多的人在管理他们自己的开源项目。然而,运行一个完全的开源项目可能是很麻烦的。这主要来自于维护项目的社区和管理数据,如项目的代码、问题跟踪和仓库。
为了帮助他们Open@RIT 正在创建一个名为 Mystic 的系统,这是一个社区健康分析平台,利用了 [GrimoireLab][2],这是一个由 [CHAOSS][3] 软件开发的开源工具包为开源项目提供了指标和分析。GrimoireLab 允许用户收集、丰富、过滤和可视化一个项目的数据,例如一个报告的问题被解决的时间、贡献者的关系等。
Mystic 将作为一个前端门户,任何人都可以提交他们的项目。在那里,项目将被直接发送到 GrimoireLab它将在几分钟后为提交者计算并发布项目的指标。
> Open@RIT 的全栈开发者和 Mystic 的首席开发者 Emi Simpson 说:“我们希望 RIT 的任何管理、领导或参与开源项目的人都能将该项目提交给 Mystic并获得他们需要的任何指标”。
这个过程很简单。登录 Mystic 后,上传项目的用户会打开一个弹出式窗口,输入项目的细节和数据源的链接,如 GitLab、RSS feed 和一个开放软件基金会OSF项目。一旦细节和项目被保存下来Mystic 就会使用 GrimoireLab 从项目源中自动检索指标,并为每个源渲染图表。然后,该项目及其指标将显示在它自己的仪表板上。
这个过程很简单。登录 Mystic 后,上传项目的用户会打开一个弹出式窗口,输入项目的细节和数据源的链接,如 GitLab、RSS feed 和一个<ruby>开放软件基金会<rt>Open Software Foundation</rt></ruby>OSF项目。一旦保存了细节和项目Mystic 就会使用 GrimoireLab 从项目源中自动检索指标,并为每个源渲染图表。然后,该项目及其指标将显示在它自己的仪表板上。
![Mystic statistics page][4]
Screenshot by Quinn Foster[CC-BY SA 4.0][5]
这些仪表盘将并列显示在一个页面上,以供其他人查看,鼓励 RIT 内部的开源社区之间的合作开发和互动。Simpson 和 Open@RIT 希望这将增加 RIT 的开放工作的参与度,并进一步巩固该大学作为开放工作中心的地位。
这些仪表盘将并列显示在一个页面上,以供其他人查看,鼓励全世界 RIT 内部的开源社区之间的合作开发和互动。Simpson 和 Open@RIT 希望这将增加 RIT 的开放工作的参与度,并进一步巩固该大学作为开放工作中心的地位。
> Simpson 说:“如果有人问 RIT 在为开源软件做什么,我希望人们能够指着 Mystic 和 GrimoireLab 说就是这些。通过建立‘这些’是我们正在做的,这些是我们的贡献,这些是人们正在做的项目的指标,我们可以在 RIT 建立一个以我们正在做的开源工作为中心的社区。”
> Simpson 说:“如果有人问 RIT 在为开源软件做什么,我希望人们能够指着 Mystic 和 GrimoireLab 说就是这些。通过建立‘这些是我们正在做的,这些是我们的贡献,这些是人们正在做的项目’的指标,我们可以在 RIT 建立一个以我们正在做的开源工作为中心的社区。”
目前Mystic 仍在开发中,还没有准备好进入生产环境,但它对 RIT 和整个开源的潜力仍然是有目共睹的。未来的目标包括实现与大学报告工具的轻松整合,以及在项目层面和总体上的综合仪表盘。
你对 Mystic 的贡献感兴趣吗?[请与我们联系][6]开始吧。
你对 Mystic 的贡献感兴趣吗?[请与我们联系][6] 开始吧。
--------------------------------------------------------------------------------
@ -43,7 +43,7 @@ via: https://opensource.com/article/21/9/openrit-mystic
作者:[Quinn Foster][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/) 荣誉推出

View File

@ -0,0 +1,96 @@
[#]: subject: "Raspberry Pi Zero vs Zero W: Whats the Difference?"
[#]: via: "https://itsfoss.com/raspberry-pi-zero-vs-zero-w/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "anine09"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13799-1.html"
树莓派 Zero 与 Zero W 对比
======
树莓派十年前凭借 25 美元的迷你电脑掀起了一场革命。随着时间的推移,树莓派发布了许多变种。有些是对以前的型号进行升级,有些是为特定目的而制作的。
在所有的树莓派模块中Pi Zero 和 Pi Zero W 是最便宜的型号,旨在用于小规模项目和 IoT 项目。这两种设备几乎是相同的,但是它们之间有一些微妙而重要的区别。
**那么,树莓派 Zero 和 Zero W 之间的区别是什么Zero W 中的 W 代表的是<ruby>无线<rt>Wireless</rt></ruby>,它表示的是 Zero W 模块拥有无线功能。这是这两个相似模块之间的最大差异。**
让我们来详细了解一下。
### Pi Zero 与 Pi Zero W 之间的主要不同点
![][1]
树莓派 Zero 是以在只有 A+ 板一半的大小上提供尽可能多的功能为目标。
而树莓派 Zero W 是为了支持无线在后来推出的,在不需要任何附加的组件和模块的情况下就可以使用蓝牙和 Wi-Fi。
这是两者之间的关键区别,其他的规格保持一致。
所以,如果你需要以下功能:
* 802.11 b/g/n 无线网口
* 蓝牙 4.1
* 低功耗蓝牙BLE
树莓派 Zero W 将是你的不二之选。
此外,树莓派 Zero W 还提供了一种带引脚的版本,叫做 “树莓派 Pi Zero WH”
### 树莓派 Zero 和 Zero W 的规格
![Raspberry Pi Zero W][6]
[树莓派 Zero 和 Zero W 的规格][7] 几乎是一样的。
它们都具有 1 GHz 的单核 CPU 和 512 MB 的 RAM。至于接口方面一个 mini HDMI 接口,支持 micro USB OTG、micro USB 供电和一个 CSI 摄像头接口(用于插入一个相机模块)。
这些板子会提供一种叫 [HAT][8]<ruby>顶部附加硬件<rt>Hardware Attached on Top</rt></ruby>)兼容的 40 个引脚。但一般情况下,没有这些可以让你轻松插入接口的引脚。
你可以根据自己的功能需要选择使用 [各种树莓派兼容的系统][9],但无论哪种情况,我还是推荐你使用树莓派 OS。
### 树莓派 Zero 系列值不值得买?
![Raspberry Pi Zero][10]
树莓派 Zero 是一种很受人们喜欢的单片机形式,即使你有很多树莓派 Zero 的替代品,树莓派 Zero 仍然是最推荐的选择。
当然,除非你有特殊需求。
除了板子的尺寸之外,定价、功率要求、运算能力也是这款 20 美元以下的板子的主要亮点。
因此,如果你正在寻找预算内满足基本功能的单片机,树莓派 Zero 就是专门为你打造的。
### 树莓派 Zero 系列价格怎么样?
树莓派 Zero 售价 **5 美元** Zero W 售价 **10 美元左右**,当然,根据其供应情况和地区,定价规则会不一样,如果你选择带引脚的版本树莓派 Zero WH ,售价大概是 **14 美元** 左右。
还有 [其他的设备可以代替树莓派 Zero][11],它们价格也相差不大。
--------------------------------------------------------------------------------
via: https://itsfoss.com/raspberry-pi-zero-vs-zero-w/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[anine09](https://github.com/anine09)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-vs-zero-w.png?resize=800%2C450&ssl=1
[2]: https://i1.wp.com/m.media-amazon.com/images/I/517BwcAPmTL._SL160_.jpg?ssl=1
[3]: https://www.amazon.com/dp/B072N3X39J?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 "CanaKit Raspberry Pi Zero W (Wireless) Complete Starter Kit - 16 GB Edition"
[4]: https://www.amazon.com/gp/prime/?tag=chmod7mediate-20 "Amazon Prime"
[5]: https://www.amazon.com/dp/B072N3X39J?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 "Buy on Amazon"
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-w.png?resize=600%2C400&ssl=1
[7]: https://itsfoss.com/raspberry-pi-zero-w/
[8]: https://github.com/raspberrypi/hats
[9]: https://itsfoss.com/raspberry-pi-os/
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-1.png?resize=600%2C400&ssl=1
[11]: https://itsfoss.com/raspberry-pi-zero-alternatives/
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/10/raspberry-pi-zero-w-projects.png?fit=800%2C450&ssl=1
[13]: https://itsfoss.com/raspberry-pi-zero-projects/

View File

@ -0,0 +1,107 @@
[#]: subject: "Kali Linux 2021.3 Brings in Kali Live VM Support, New Tools, and Other Improvements"
[#]: via: "https://news.itsfoss.com/kali-linux-2021-3-release/"
[#]: author: "Omar Maarof https://news.itsfoss.com/author/omar/"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-13798-1.html"
Kali Linux 2021.3 的新改进
======
> Kali Linux 2021.3 带来了一些重要的功能改进以及一些新工具。此外还有一个惊喜,他们还宣布正在开发他们的第一个 NetHunter 智能手表。
![](https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/09/kali-linux-2021-3.jpg?w=1200&ssl=1)
Kali Linux 是 [用于渗透测试的最佳 Linux 发行版][1] 之一。它是基于 Debian 的,但它可能不适合替代你的成熟的桌面操作系统。
最新的 2021.3 版本带来了一些重要的功能添加和改进。让我们来看看它们。
### 有何新变化?
![][2]
#### OpenSSL 兼容性
重新配置了 [OpenSSL][3],以扩大 Kali 可以连接的服务。因此,老式过期的协议,如 TLS 1.0 和 TLS 1.1 以及更旧的加密算法,在默认情况下是允许的。也就是说;它将让 Kali 可以连接到更多过时的服务器。然而,如果你不需要它,你可以改变这个选项。
#### 虚拟化的改进
众所周知Kali 可以作为一个虚拟机完美地工作。首先,无论你的访客机是在 VirtualBox、VMware、Hyper-V 还是 QEMU+Spice 下运行,宿主机和访客机系统之间的拖放、复制和粘贴等操作都比以前更顺畅。
其次,使用 Kali-Tweaks 可以更容易为 Hyper-V 增强会话模式(一种虚拟化管理程序)配置 Kali。
简而言之Kali Linux 2021.3 使得在设置虚拟环境时的体验更加完美。
#### Kali 工具
每一个 Kali 版本都包含新的工具这是理所当然的。同样的这个版本也不例外。Kali 加入的工具有:
* [Berate_ap][4] - 编组 MANA rogue Wi-Fi 接入点
* [CALDERA][5] - 可扩展的自动对手模拟平台
* [EAPHammer][6] - 针对 WPA2-Enterprise Wi-Fi 网络的 evil twin 攻击
* [HostHunter][7] - 使用 OSINT 技术发现主机名的侦察工具
* [RouterKeygenPC][8] - 生成默认的 WPA/WEP 无线密钥
* [Subjack][9] - 子域接管
* [WPA_Sycophant][10] - EAP 中继攻击的邪恶客户端部分
#### Kali ARM 更新和 Kali-Tools
在 Kali 2021.3 中,对 ARM 设备的支持得到了更多的改进。我发现最吸引人的是:
* en_US.UTF-8 是所有镜像的默认语言。
* 重新构建了 Kali ARM 构建脚本,以更好地支持一些设备。
* 树莓派镜像现在可以使用 `/boot` 分区上的 `wpa_supplicant.conf` 文件。
此外Kali 刷新了其信息域 **Kali-Tools**,以提供简洁的工具概述、整洁的界面和快速的系统。
### 其他变化
![Kali Linux 2021.3][11]
Kali 还有其他一些不错的改进,包括:
* 改进了 Xfce 和 Gnome 版本的布局。Kali 并没有忘记 KDE因为这是它最喜欢的桌面环境之一已经内置了 KDE 5.21 是新的版本。
* 他们的文档网站中的一些重要页面进行了大幅更新。
* 与 Ampere 合作,让其 ARM 包构建机运行在 Ampere 的硬件上。因此,其大幅的提速使得 Kali 受益。
Kali 增强了针对安卓设备的移动渗透测试平台。换句话说,你现在可以在 Android 11 设备上安装 Kali NetHunter而不需要完整的可工作的 [TWRP][12]Team Win Recovery Project。最重要的是由于其方便的安装程序这一更新很有希望。
除了这个版本之外,他们还宣布了他们的第一个 NetHunter 智能手表,**TicHunter Pro**。但是,它仍然处于开发的最初阶段。
要了解更多关于这次升级的所有技术变化,请参考 [官方公告][13]。
### 总结
总的来说,这是一个重要的版本,提供了重要的改进和令人兴奋的新工具。从它的官方网站上下载它,就可以开始了。
- [下载 Kali Linux 2021.3][14]
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/kali-linux-2021-3-release/
作者:[Omar Maarof][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://news.itsfoss.com/author/omar/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/linux-hacking-penetration-testing/
[2]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/09/kali-linux-desktop-2021-3.png?w=1200&ssl=1
[3]: https://www.openssl.org/
[4]: https://pkg.kali.org/pkg/berate-ap
[5]: https://pkg.kali.org/pkg/caldera
[6]: https://pkg.kali.org/pkg/eaphammer
[7]: https://pkg.kali.org/pkg/hosthunter
[8]: https://pkg.kali.org/pkg/routerkeygenpc
[9]: https://pkg.kali.org/pkg/subjack
[10]: https://pkg.kali.org/pkg/wpa-sycophant
[11]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/09/banner-kali-2021.3-release.jpg?w=1200&ssl=1
[12]: http://twrp.me/
[13]: https://www.kali.org/blog/kali-linux-2021-3-release/
[14]: https://www.kali.org/get-kali/

View File

@ -1,71 +0,0 @@
[#]: subject: "Ubuntus Yaru Theme Now Officially Supports Xfce"
[#]: via: "https://news.itsfoss.com/yaru-xfce-support/"
[#]: author: "Jacob Crume https://news.itsfoss.com/author/jacob/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Ubuntus Yaru Theme Now Officially Supports Xfce
======
Back when [Ubuntu 20.04][1] was released, the Ubuntu team stunned everyone with the new Yaru themes beautiful visuals and simplicity. It keeps on getting better with each Ubuntu release. It has become the symbolism of Ubuntu now.
However, the Yaru theme was not well supported for other desktop environments like Xfce.
Fortunately, this is set to change with a recent pull request on the [projects GitHub page][2]. Here, we will be looking at this change, as well as how to try out these changes for yourself.
### Yaru on Xfce
![][3]
This update started in late July, when developer [Muqtxdir][4] opened [a pull request on the Yaru GitHub page][5] to add support for the XFCE desktop environment. Over the course of a month, the awesome developers there worked tirelessly on improving Muqtxdirs work, with a result that is truly stunning.
![][3]
One interesting change is the panel, which now looks similar to the panel found in the GNOME desktop environment.
### If you want to try it right away (not recommended)
If you are already using XFCE, trying out the Yaru theme is as simple as following the instructions on here. For this, I will be assuming that you are using Xubuntu, however the commands can be easily adapted for other distributions.
```
sudo apt install git meson sassc libglib2.0-dev libxml2-utils
git clone https://github.com/ubuntu/yaru
cd yaru && meson build -Dxfwm4=true && sudo ninja -C build install
```
_**If you dont quite feel comfortable building it from source, I suspect that it will be available with Xubuntu 21.10, which is only a month away now.**_
Either way, I am really excited about this change, especially as it gives XFCE a much more modern and simplistic look. Plus, it also gives users a major reason to upgrade to Xubuntu 21.10.
What do you think about the Yaru theme on XFCE? Let me know in the comments below!
_Source: [Linux Uprising][6]_
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/yaru-xfce-support/
作者:[Jacob Crume][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://news.itsfoss.com/author/jacob/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/download-ubuntu-20-04/
[2]: https://github.com/ubuntu/yaru
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[4]: https://github.com/Muqtxdir
[5]: https://github.com/ubuntu/yaru/pull/2971
[6]: https://www.linuxuprising.com/2021/09/ubuntus-yaru-theme-gets-official.html

View File

@ -1,81 +0,0 @@
[#]: subject: "Vivaldi Replaces Firefox as the Default Browser on Manjaro Linux Cinnamon"
[#]: via: "https://news.itsfoss.com/vivaldi-replaces-firefox-manjaro/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Vivaldi Replaces Firefox as the Default Browser on Manjaro Linux Cinnamon
======
Vivaldi is one of the [best web browsers available for Linux][1].
For all the good reasons, many Linux users have been switching to Vivaldi, especially after [Vivaldi 4.0 release][2].
Now, to take it up a notch, Vivaldi has managed to replace Firefox as the default browser on Arch-based Manjaro Linux (Cinnamon edition).
![][3]
Even though the Cinnamon version is a community edition, it is surprising that Mozilla Firefox dropped from a Linux distribution.
As per the official announcement, Manjaros co-CEO mentioned why they chose Vivaldi:
> _To give Vivaldi more of the attention it deserves, I decided to include it as the default browser in our popular Cinnamon Community Edition. With its remarkable browsing speed, exceptional customizability and especially the way it values user privacy, Vivaldi for me is a perfect match for Manjaro Linux._
### Customized Experience for Manjaro Linux Users
![][4]
To spice things up, [Vivaldi][5] comes baked in with a Manjaro-Cinnamon theme to give you a refreshing out-of-the-box experience.
Of course, if you have already used Vivaldi as your browser, you have to sync your data to get started.
### Vivaldi is a Great Option for Linux Users
![][6]
It is worth noting that Vivaldi is not 100% open-source, but you can find most of its source code online, except its UI. Also, it is based on Chromium.
However, it is a feature-rich web browser that lets you customize a lot of things. You also get a unique tab management feature, integration of web apps, email, calendar, timer, RSS feeds, and more.
I have been using Vivaldi as my daily driver on Linux, keeping Firefox as the secondary for a while now. And, I like the experience so far!
So, if you prefer multi-tasking without leaving the web browser, Vivaldi as your default choice should be exciting.
In addition to this, Vivaldi seems to be taking good care of its privacy policies while offering in-built ad blockers and encrypted sync features.
### Get Started Using Vivaldi on Manjaro Linux
You should be able to find and install Vivaldi through official Manjaro repositories.
If you want it by default, you can consider performing a fresh installation of Manjaro Linux Cinnamon.
Manjaro Linux Cinnamon
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/vivaldi-replaces-firefox-manjaro/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-browsers-ubuntu-linux/
[2]: https://news.itsfoss.com/vivaldi-4-0-release/
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUyNCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQyMCIgd2lkdGg9IjY2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[5]: https://vivaldi.com
[6]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjYxOCIgd2lkdGg9IjY5NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=

View File

@ -1,103 +0,0 @@
[#]: subject: "Fedora 35 Release Date and Expected New Features"
[#]: via: "https://news.itsfoss.com/fedora-35-release-date-features/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Fedora 35 Release Date and Expected New Features
======
Fedora 35 is just around the corner. And, if you cannot wait already, let us highlight some of the essential details about the release.
### Fedora 35 Release Date
The expected release date for Fedora 35 beta is **14th September 2021**. But, if delayed, the next planned date is **21st September 2021**.
After the public beta testing, the final release has been planned for **19th October 2021,** with a delayed date for **26th October 2021.**
Of course, you can get your hands on Fedora 35 before the final and beta releases as well. But, considering it is just a few days away from its first beta release, you may want to wait it out.
### Fedora 35 Features
![][1]
[Fedora 34][2] was an exciting release with GNOME 40 and a new i3 spin. And Fedora 35 is also shaping up as an interesting upgrade to it.
Some of the fundamental changes that you can expect are:
#### GNOME 41
GNOME 41 may not be a radical change when compared to [GNOME 40][3], but there are some visual improvements and valuable feature additions that you can expect.
For instance, the GNOME Software will get a clean look and context tiles, resembling much like all the details that you can find in the [Apps for GNOME][4] portal. You should also find [VoIP support added to GNOME 41][5].
A new “**Connections**” app has been added to let you connect to other platforms/systems remotely.
GNOME 41 has a planned release date of **September 22, 2021**. So, you may want to watch out for our coverage for the complete details when it releases.
#### DNS Over TLS Support
DNS Over TLS (DoT) is essential to encrypt DNS requests and prevent your ISP from spying. With Fedora 35, any configured DNS server should automatically attempt to connect using DoT if the DNS supports it.
#### Default Btrfs Filesystem for Fedora Cloud
While Fedora has already switched to the Btrfs filesystem since [Fedora 33][6], they enforce that change for the Cloud edition.
#### Linux Kernel 5.14
[Linux Kernel 5.14][7] wasnt a big release, but it added many features, especially when it comes to ARM devices.
For Fedora 35, the improved hardware support should make a difference.
#### Flathub Applications Included with Third-Party Repositories
You also get some selected Flatpak applications added from a filtered Flathub remote when you enable third-party repositories.
This should come in handy for better third-party app support in Fedora.
#### PulseAudio Daemon Replaced by PipeWire
While we saw initial implementations of replacing PulseAudio in Fedora 34, this time, there is a proposal to replace the PulseAudio daemon with a compatible implementation based on PipeWire.
### Other Improvements
Along with the key highlights mentioned above, you should find several under-the-hood changes and package updates that could translate as significant upgrades.
For instance, the Firewalld package update and the GNU Toolchain update should prove to be valuable upgrades.
You can explore more about the proposed changes in their [official changeset wiki][8].
### Wrapping Up
It should be exciting to see the changes in the final release. For now, let us keep an eye out to test the public beta release. And, if you do not want to experiment on your system with a beta release, you should wait for the stable release.
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/fedora-35-release-date-features/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUyMSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[2]: https://news.itsfoss.com/fedora-34-release/
[3]: https://news.itsfoss.com/gnome-40-release/
[4]: https://news.itsfoss.com/apps-for-gnome-portal/
[5]: https://news.itsfoss.com/gnome-41-beta/
[6]: https://itsfoss.com/fedora-33/
[7]: https://news.itsfoss.com/kernel-5-14-release/
[8]: https://fedoraproject.org/wiki/Releases/35/ChangeSet

View File

@ -0,0 +1,86 @@
[#]: subject: "After Chromium, Ubuntu Now Converts Firefox to Snap by Default"
[#]: via: "https://news.itsfoss.com/ubuntu-firefox-snap-default/"
[#]: author: "Abhishek https://news.itsfoss.com/author/root/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
After Chromium, Ubuntu Now Converts Firefox to Snap by Default
======
One of the major and controversial [changes in the upcoming Ubuntu 21.10][1] is the conversion of Firefox from deb to snap.
Yes, you heard it right. The default Firefox will be a Snap application, not the regular DEB version.
As [spotted by OMG! Ubuntu][2], this is done as per an agreement between Mozilla and Canonical (Ubuntus parent company).
The [feature freeze exception (FFE)][3] mentions it clearly:
> Per Canonicals distribution agreement with Mozilla, were making the snap the default installation of Firefox on desktop ISOs starting with Ubuntu 21.10.
With this change, the Firefox deb package will be converted to Firefox snap package.
This means that going forward, Firefox will be available as Snap. I think this change also means that even if you use apt command to install it, youll be getting the Snap package.
### Deja vu?
If you feel that this has been done in the past, you have got the right feeling. In the past, Ubuntu converted the Chromium browser to Snap.
Today, if you use apt install chromium-browser, you still get the Snap version. There is no DEB package for Chromium in Ubuntu anymore.
When Ubuntu made this sudden change on its own, there was an uproar. The conversion of Firefox to Snap will also create controversy. But this time, Ubuntu shares the blame with Mozilla.
### Mozilla wants Snap
![][4]
Interestingly, it was [Mozilla that approached Canonical for this change][5]. Mozilla will maintain the Snap version of Firefox and the end users will get quick updates directly from the source.
After all, it takes a few days before a new Firefox release lands in Ubuntu. With the Snap move, your Firefox will be updated to the new version the same day.
### Concerns?
A few for sure. I know there are a few people completely averted to Snap, I am not one of them.
I have three major complaints with Snap packages: slow start up speed, poor system integration and high disk space.
Over the time, Snaps have improved on the disk space front. But despite all the improvements, Snap packages still take longer to start. This could be tolerable with an IDE but it may ruin the browsing experience.
This slow startup speed makes me wonder why it is called Snap because surely, it doesnt start in a snap.
Another thing that bothers me is the Snap auto-refresh. Snap apps are updated automatically. If Mozilla starts pushing updates more frequently, this [Firefox restart annoyance][6] in the middle of work will be more frequently as well.
![][7]
The change will impact you when you install or upgrade to Ubuntu 21.10. The change will eventually propagate to Ubuntu 22.04 LTS.
What do you think of this change? Yeah or neah?
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/ubuntu-firefox-snap-default/
作者:[Abhishek][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://news.itsfoss.com/author/root/
[b]: https://github.com/lujun9972
[1]: https://news.itsfoss.com/ubuntu-21-10-release-schedule/
[2]: https://www.omgubuntu.co.uk/2021/09/ubuntu-makes-firefox-snap-default
[3]: https://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+bug/1943840
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI1NCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[5]: https://discourse.ubuntu.com/t/feature-freeze-exception-seeding-the-official-firefox-snap-in-ubuntu-desktop/24210
[6]: https://news.itsfoss.com/mozilla-annoying-new-tab/
[7]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwOCIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=

View File

@ -0,0 +1,65 @@
[#]: subject: "Linux Mints Website Has a Much Needed Minty Fresh New Look"
[#]: via: "https://news.itsfoss.com/linux-mint-new-website-design/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Linux Mints Website Has a Much Needed Minty Fresh New Look
======
Linux Mint is one of the [best Linux distributions][1] available while offering a modern user experience.
However, Linux Mints original website looked dated and potentially unattractive to new-age computer users.
Many suggested a visual makeover to reflect Linux Mints taste through a modern website design. And, only recently the developers started working on a redesign in collaboration with the community members, asking for feedback and getting insights on proposed designs.
Finally, a design was finalized and applied to [Linux M][2][i][2][nts official website][2].
The website looks clean and informative, great on desktop, and perfectly fits mobile phone browsers!
![][3]
Every new Linux user should be able to evaluate their requirements by looking at the features offered easily.
The information is well-presented to convince users why they should try out Linux Mint on their desktop system.
![][4]
The key highlights of the website would be the homepage, download page, and donation page.
Of course, you can choose to explore more about Linux Mint and how everything works through individual resources (like our articles), but the official website should be the essential starting point, which it is now.
The accent color and the theme combination feels just like what Linux Mint needed! Navigating through various web pages and the menu is a breeze. I dont think there is any unnecessary element on the website; everything fits perfectly in the first look. The page load time is faster as well.
The blog/monthly news section continues to use the same design. And, Im not certain if they intend to refresh that by applying the same design anytime soon. But, I think that should happen to ensure consistency between their web pages.
_What do you think about Linux Mints new website design? Do you like it? Do you think this would help them get more attention from new-age users?_
_You are welcome to share your thoughts in the comments down below._
### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/linux-mint-new-website-design/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-linux-distributions/
[2]: https://linuxmint.com
[3]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[4]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUzMSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=

View File

@ -1,5 +1,5 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (zpl1025)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@ -1,496 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (13 of the best React JavaScript frameworks)
[#]: via: (https://opensource.com/article/20/1/react-javascript-frameworks)
[#]: author: (Amit Dua https://opensource.com/users/amitdua)
13 of the best React JavaScript frameworks
======
If you're using React.js or React Native to create user interfaces, try
these frameworks.
![Javascript code close-up with neon graphic overlay][1]
React.js and React Native are popular open source platforms for developing user interfaces (UIs); both rank well for desirability and use in StackOverflow's 2019 Developer Survey. React.js was developed by Facebook in 2011 as a JavaScript library to address the need for cross-platform, dynamic, and high-performing UIs, while React Native, which Facebook released in 2015, is used for building native applications using JavaScript.
The following are 13 of the best React JavaScript frameworks; all are open source—the first 11 (like React) are licensed under the MIT license and the latter two are licensed under Apache 2.0.
### 1\. Create React App
This command-line interface from Facebook developers is a must-have for every React Native project. The reason is that the [Create React App][2] is easy to use and prevents you from having to manually set up and configure your app, thereby saving you a lot of time and effort. With just a simple command, everything will be ready for you to create a React native project easily. You can use it to build a catalog and files, and the framework also includes tools to build, test, and launch your application.
```
# Install package
$ npm install -g create-react-native-web-app
 
# Run create-react-native-web-app &lt;project-directory&gt;
$ create-react-native-web-app myApp
 
# cd into your &lt;project-directory&gt;
$ cd myApp
 
# Run Web/Ios/Android development
# Web
$ npm run web
 
# IOS (simulator)
$ npm run ios
 
# Android (connected device)
$ npm run android
```
#### Why opt for Create React App
1. Top-notch tool developed with a configure bundle, transpiler, and test runner
2. No configuration and no extra files at the app structure
3. Fixed Development stack
4. Effective Fast developing tool
### 2\. Material Kit React
Inspired by Google's Material Design system, [Material Kit React][3] can be an excellent choice for building React UI components. The best thing about this library is that it offers a lot of components that are built to fit together and look incredible. There are over 1,000 fully coded components, and each one comes with separate layers organized in folders. This means you have thousands of options to choose from. There are several example pages as well, in case you want to get inspiration or share an idea or concept with someone.
#### Installing the Material Kit
```
`  $ npm install @material-ui/core`
```
#### Implementation
```
import React from 'react';
import Button from '@material-ui/core/Button';
const App = () =&gt; (
  &lt;Button variant="contained" color="primary"&gt;
    Hello World
  &lt;/Button&gt;
);
```
The Material-UI component work without any additional setup, and do not pollute the global scope.
#### Advantage
The React component supports easier and faster web development. With it, you can build your own design system, or start with Material Design.
### 3\. Shards React
This modern React UI kit has been built from scratch to achieve fast performance. It has a modern design system that lets you customize things the way you want. You can even download the source files to customize things at the code level. Also, the SCSS syntax used for styling enhances the development experience.
[Shards React][4] is based on Shards and uses React Datepicker, React Popper (a positioning engine), and noUISlider. It also supports incredible Material Design icons. There are some pre-made versions to help you gain some inspiration and get started.
#### Installation Shards with Yarn or NPM
```
# Yarn
yarn add shards-react
# NPM
npm i shards-react
```
#### Advantages
1. Shards is lightweight having a small footprint and weighting ~13kb minified and gzipped
2. Shards is responsive by default being able to adapt and reflow its layout to any screen size
3. Shards is well documented so you can start building beautiful interfaces as soon as possible
### 4\. Styled Components
This efficient CSS tool helps build small, reusable components that are responsible for an app's visual interface. With traditional CSS, you can accidentally overwrite the selectors used in other places on the website, but [Styled Components][5] can help you completely avoid this problem by using a CSS syntax directly inside your components.
#### Installation
```
`npm install --save styled-components`
```
#### Implementation
```
const Button = styled.button`
  background: background_type;
  border-radius: radius_value;
  border: abc;
  color: name_of_color;
  Margin: margin_value;
  padding: value;
```
#### Advantage
1. Make components more readable
2. Components rely on JavaScript for their style
3. Build custom components with CSS
4. Inline styling
5. Convert component even the custom component to a styled component by simply invoking styled()
### 5\. Redux
[Redux][6] is a state-management solution for JavaScript applications. While it is mostly used for React.js, you can also use it for other React-like frameworks.
#### Installation
```
sudo npm install redux
sudo npm install react-redux
```
#### Implementation
```
import { createStore } from "redux";
import rotateReducer from "reducers/rotateReducer";
function configureStore(state = { rotating: value}) {
  return createStore(rotateReducer,state);
}
export default configureStore;
```
#### Advantage
1. Predictable state update helps in defining the data flow of the application
2. Logic easier to test and time-travel debugging with reducer functions
3. Centralizing the state
### 6\. React Virtualized
This React Native JavaScript framework helps in large-list and tabular-data rendering. Using [React Virtualized][7], you can restrict the number of requests and Document Object Model (DOM) elements, thus enhancing the performance of React apps.
#### Installation
```
`npm install react-virtualized`
```
#### Implementation
```
import 'react-virtualized/styles.css'
import { Column, Table } from 'react-virtualized'
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'
import List from 'react-virtualized/dist/commonjs/List'
{
  alias: {
    'react-virtualized/List': 'react-virtualized/dist/es/List',
  },
  ...rest
}
```
#### Advantages
1. Display a large amount of data efficiently
2. Rendering a huge data set
3. Implements virtual rendering with a set of components
### 7\. React DnD
[ReactDnD][8] is responsible for the creation of complex drag-and-drop interfaces. There are dozens of drag-and-drop libraries, but React DnD stands out because it is built on top of modern HTML5's drag-and-drop API, making the process of creating interfaces easy.
#### Installation
```
`npm install react-dnd-preview`
```
#### Implementation
```
 import Preview from 'react-dnd-preview';
 
  const generatePreview = ({itemType, item, style}) =&gt; {
    return &lt;div class="item-list" style={style}&gt;{itemType}&lt;/div&gt;;
  };
 
  class App extends React.Component {
    ...
 
    render() {
      return (
        &lt;DndProvider backend={MyBackend}&gt;
          &lt;ItemList /&gt;
          &lt;Preview generator={generatePreview} /&gt;
          // or
          &lt;Preview&gt;{generatePreview}&lt;/Preview&gt;
        &lt;/DndProvider&gt;
      );
    }
  }
```
#### Advantages
1. Beautiful and natural movement of items bouquet
2. Powerful keyboard and screen reader support wheelchair
3. Extremely performant
4. Clean and powerful api
5. Plays extremely well with standard browser interactions
6. Unopinionated styling
7. No creation of additional wrapper dom nodes
### 8\. React Bootstrap
This UI Kit library replaces Bootstrap's JavaScript with React, giving you more control over the functions of each component. Because each component is built to be easily accessible, [React Bootstrap][9] can be beneficial for frontend framework building. There are thousands of bootstrap themes to choose from.
#### Installation
```
`npm install react-bootstrap bootstrap`
```
#### Implementation
```
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(&lt;App /&gt;, document.getElementById('root'));
registerServiceWorker();
```
#### Advantages
1. Can easily import required code/component
2. Saves typing and bugs by compressing the Bootstrap
3. Reduces typing efforts and conflicts by compressing the Bootstrap
4. It is easy to use
5. It encapsulates in elements
### 9\. React Suite
[React Suite][10] is another efficient React.js framework that contains a wide range of component libraries for enterprise system products. It supports all major browsers and platforms, making it suitable for just about any system. It also supports server-side rendering.
#### Installation
```
`npm i rsuite --save`
```
#### Implementation
```
import { Button } from 'rsuite';
import 'rsuite/styles/less/index.less';
ReactDOM.render(&lt;Button&gt;Button&lt;/Button&gt;, mountNode);
```
#### Advantages
1. Easily manage the application easily by the help of global accessing features
2. Redux library centralizes the state management
3. Redux is flexible with all the UI layers and has a large ecosystem
4. Redux reduces this complexity and provides global accessibility
### 10\. PrimeReact
The best thing about [PrimeReact][11] is that it provides components that cover almost all of a UI's basic requirements, such as input options, menus, data presentations, messages, etc. The framework also pays close attention to the mobile experience, thus helping you design touch-optimized elements.
#### Installation
```
npm install primereact --save
npm install primeicons --save
```
#### Implementation
```
import {Dialog} from 'primereact/dialog';
import {Accordion,AccordionTab} from 'primereact/accordion';
dependencies: {
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "react-transition-group": "^2.2.1",
    "classnames": "^2.2.5",
    "primeicons": "^2.0.0"
}
```
#### Advantages
1. Simplicity and Performance
2. Ease of Use
3. Spring Applications
4. Create rich user interfaces
5. Usability and simplicity
### 11\. React Router
[React Router][12] is quite popular in the React Native developer community because it is very easy to start working with. All you need is Git and the npm package manager installed on your PC, a basic knowledge of React, and a willingness to learn. There is nothing too complicated.
#### Installation
```
`$ npm install --save react-router`
```
#### Implementation
```
import { Router, Route, Switch } from "react-router";
 
// using CommonJS modules
var Router = require("react-router").Router;
var Route = require("react-router").Route;
var Switch = require("react-router").Switch;
```
#### Advantages
1. Dynamic route matching
2. CSS transitions on views when navigating
3. Standardized app structure and behavior
### 12\. Grommet
[Grommet][13] is used for creating responsive and accessible mobile-first web apps. The best thing about this Apache 2.0-licensed JavaScript framework is that it offers accessibility, modularity, responsiveness, and theming in one small package. Perhaps this is one of the major reasons it is widely used by companies like Netflix, GE, Uber, and Boeing.
#### Installation for yarn and npm
```
` $ npm install grommet styled-components --save`
```
#### Implementation
```
"grommet-controls/chartjs": {
          "transform": "grommet-controls/es6/chartjs/${member}",
          "preventFullImport": true,
          "skipDefaultConversion": true
```
#### Advantages
1. Create one toolkit as a packaged deal
2. Take the open-door policy to the extreme
3. Restructuring can help influence an established org
### 13\. Onsen UI
[Onsen UI][14] is another mobile app development framework that uses HTML5 and JavaScript and offers integration with Angular, Vue, and React. It is licensed under Apache 2.0.
Onsen offers tabs, a side menu, stack navigation, and other components. The best thing about the framework is that all of its components have iOS and Android Material Design support along with automatic styling, which changes the app's appearance depending on the platform.
#### Installation
```
`npm install onsenui`
```
#### Implementation
```
(function() {
    'use strict';
    var module = angular.module('app', ['onsen']);
    module.controller('AppController', function($scope) {
      // more to come here
    });
})();
```
#### Advantages
1. Onsen UI is built on free and open-source code
2. Doesn't force any type of DRM on apps developed with it
3. Compiles JavaScript and HTML5 code
4. Offers end users the native experience
* * *
What are your favorite React JavaScript frameworks? Please share them in the comments.
Learn more about React Native, a framework for building native apps using React and JavaScript.
Whether you are new to JavaScript or an experienced JavaScript developer, using libraries and...
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/1/react-javascript-frameworks
作者:[Amit Dua][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/amitdua
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_javascript.jpg?itok=60evKmGl (Javascript code close-up with neon graphic overlay)
[2]: https://github.com/facebook/create-react-app
[3]: https://github.com/creativetimofficial/material-kit-react
[4]: https://github.com/DesignRevision/shards-react
[5]: https://github.com/styled-components/styled-components
[6]: https://github.com/reduxjs/redux
[7]: https://github.com/bvaughn/react-virtualized
[8]: https://github.com/react-dnd/react-dnd/
[9]: https://github.com/react-bootstrap/react-bootstrap
[10]: https://github.com/rsuite/rsuite
[11]: https://github.com/primefaces/primereact
[12]: https://github.com/ReactTraining/react-router
[13]: https://github.com/grommet/grommet
[14]: https://github.com/OnsenUI/OnsenUI

View File

@ -1,101 +0,0 @@
[#]: subject: (Windows 11 System Requirement is Turning Heads. Time to migrate to Linux?)
[#]: via: (https://www.debugpoint.com/2021/06/windows-11-system-requirement/)
[#]: author: (Arindam https://www.debugpoint.com/author/admin1/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Windows 11 System Requirement is Turning Heads. Time to migrate to Linux?
======
Microsoft announced Windows 11 at the official online event. Heres in
this post we brief the Windows 11 system requirement and give you
thinking points on whether you should permanently migrate to Linux.
There are many debates and discussions going around after the announcement of Windows 11 from Microsoft. Many are “blown away” by the look and feel of the customization option that it brings, little they know that it might be “[inspired][1]” by other operating systems.
![Windows 11 Desktop][2]
Heres a quick recap of visible features
* New Start Menu, Taskbar, and Search Bar
* New Animations are added while moving and dragging the windows. Even Opening a new window, closing, and minimize tap have different animation than earlier versions of Windows.
* Featured add to perform multitask with windows like split-screen, creating groups of various task windows, etc.
* Touch controls are improved significantly.
* New sounds are added in this version. After the release of Windows 10 in 2015, no significant changes were made in the sounds. But in Windows 11, you will see various new sound options.
* You will have access to dark mode also.
* Rounded Corners: Pointy corners will not be available in Windows 11. Corners of various bars will be made round.
* New icons are added which will make it more attractive than the earlier versions.
* Various new Widgets are added in this version.
* You can run Android apps via Windows 11 store
### Windows 11 System Requirement
* Processor 1 gigahertz (GHz)orfaster with 2 or more cores on acompatible 64-bit processor or System on a Chip (SoC)
* Memory 4 GB RAM
* Storage 64 GB or larger storage device
* System firmware UEFI, Secure Boot capable
* TPM Trusted Platform Module (TPM) version 2.0
* Graphics card DirectX 12 compatible graphics / WDDM 2.x
Display &gt;9” with HD Resolution (720p)
* Internet connection Microsoft account and internet connectivity required for setup for Windows 11 Home
Looking at the specification, you might have noticed a couple of interesting items. Windows 11 recommends your system should have TPM a.k.a Trusted Platform Module (TPM) version 2.0. Trusted Platform Module (TPM) technology is designed to provide hardware-based, security-related functions. A TPM chip is a secure crypto-processor that is designed to carry out cryptographic operations. The chip includes multiple physical security mechanisms to make it tamper-resistant, and malicious software is unable to tamper with the security functions of the TPM.
And this is why Microsoft boasts about Windows 11 being more secure.
Not all the hardware that is available today has a TPM chip. And worse is, many may force to buy new hardware as well. As a thumb rule, if you have bought any Laptop, Desktop 2017 onwards, you should be fine.
[][1]
SEE ALSO:   Windows 11 Look Inspired by KDE Plasma and GNOME?
### Internet Required for set up?
From an end-user perspective, this is not a good idea at all. This forces everyone to create a Microsoft account for the initial setup. Think about millions of users who probably buy Laptops for basic usage, and now they required to create an account, with OneDrive and other online “BS”. And you end up consuming more data, give away your data, and so on.
This move is completely unnecessary from the Microsoft side. Internet connectivity should be optional and not mandatory for setting up your computer which you bought with a price.
### Should you be moving to Linux?
Yes, of course. Linux can run super-fast in all newer and older hardware. There are plenty of versions of the Linux operating system with a nice-looking desktop out there that you can easily install and use. You do not need to shell out additional money just to experience fancy Windows 11.
Linux has many variants which cater to different people with a variety of tastes. You do not need to settle for only one look and feel and functionality. You have the freedom to choose.
You do not need to buy expensive Antivirus which is recommended for Windows operating system. Linux doesnt get a virus that easily as it is designed in a different way, and not that popular. So, you are protected on that front and save more money.
Linux updates are much faster due to stability and the small size of updates. Hence you save money on your data plan as well.
And, you save thousands of hours by not looking at this:
![The Never ending wait which becomes part of your life][3]
### Closing Notes
Benchmarking a certain set of hardware as “old” is completely subjective in terms of software. You can easily run Debian, or Lubuntu in ten-year-old or more hardware for basic tasks. If someone tells you that your hardware is old, doesnt make it so. Windows 11 may compel some users to think about their personal hardware strategy in the longer term. It is a market leader in the Desktop operating system and it is a business model for them and OEMs. Fair enough. But if you are a Windows user and reading this, I would recommend you to start experimenting with simple and friendly Linux distributions such as [Linux Mint][4], right now. So that you have options to choose from and have control over your spending in the longer run.
Cheers.
* * *
--------------------------------------------------------------------------------
via: https://www.debugpoint.com/2021/06/windows-11-system-requirement/
作者:[Arindam][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://www.debugpoint.com/author/admin1/
[b]: https://github.com/lujun9972
[1]: https://www.debugpoint.com/2021/06/windows-11-inspiration-linux-kde-plasma/
[2]: https://www.debugpoint.com/blog/wp-content/uploads/2021/06/Windows-11-Desktop-1024x575.jpg
[3]: https://www.debugpoint.com/blog/wp-content/uploads/2021/06/The-Never-ending-wait-which-becomes-part-of-your-life.jpg
[4]: https://www.debugpoint.com/2021/02/cinnamon-arch-linux-install/

View File

@ -1,166 +0,0 @@
[#]: subject: (Ubuntu 21.10 Impish Indri New Features and Release Date)
[#]: via: (https://www.debugpoint.com/2021/07/ubuntu-21-10/)
[#]: author: (Arindam https://www.debugpoint.com/author/admin1/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Ubuntu 21.10 Impish Indri New Features and Release Date
======
Final release of 2021, Ubuntu 21.10 Impish Indri development is in
progress. In this post, we sum up the new features known so far and
planned release dates.
This post includes information about ongoing development. The information may change frequently, and this page is regularly updated until the final release.
This page contains the following topics
* [Ubuntu 21.10 Code name history][1]
* [New Features in desktop flavor][2]
* [Ubuntu Official flavor information][3]
* [Release schedule][4]
* [Daily-build .ISO download][5]
* [Canary build .ISO download][6]
Before we list out the features, you should remember that, we are at a very early stage of the development considering October as of publishing this. And the final pieces may change as we move closer to the final release.
Historically, October releases are somewhat quieter but impactful. They create the base for next LTS in every alternate year. So having said that, this is an important release due to many factors.
### The Code Name
Following the trend, Ubuntu 21.10 is code named “impish indri” as we are at “I” based names. The “Indri” refers to _“babakoto, is one of the largest living lemurs, with a head-and-body length of about 6472 cm and a weight of between 6 to 9.5 kg. It has a black and white coat and maintains an upright posture when climbing or clinging” (from Wikipedia)_. Well, the final mascot is yet to be revealed.
So, all the packages and repo is tagged with “impish” for this version of Ubuntu.
Lets take a look at other new features.
### Ubuntu 21.10 New Features
![Ubuntu 21.10 Desktop \(daily build\)][7]
* Ubuntu 21.10 would feature **Linux Kernel 5.14**. This is currently in development and will be released before the feature freeze.
* If you are wondering of about GNOME, well yes, Ubuntu 21.10 features [GNOME 40 desktop][8] but with a twist. The **GNOME 40** version brings some fundamental changes to GNOME desktop, which you are already aware of by now. But with the usual left fixed dock! So, the customized GNOME 40 with left fixed doc, eliminates the bottom dock of vanilla GNOME 40.
* So, initially it would feel a bit strange with have **left fixed dock** with horizontal workspaces, overview and scrolling. But it would be interesting to observe user reactions and feedback once it releases.
* Version wise, this release would feature **GNOME 40.3** (its due by July 2021).
* A brand **new Desktop Installer** which would replace the decade old Ubiquity. This is created in collaboration with Google in Flutter and gives a nice and easy way of installing Ubuntu. We covered more about this installer in detail when it was launched. You can read the coverage [here][9].
![New Installer Ubuntu 21.10][10]
* The new installer is still in Canary build and not arrived in daily build as of publishing this. And when I tested, it has many bugs which are simple ones. I hope they would be sorted out before final release.
* The default theme would be set to **Yaru Light**. As per the Ubuntu team, it is difficult to maintain a mixed theme with both and dark and light together.
* In the prior Ubuntu 21.04, the Wayland display server is made default. In this release, **NVIDIA** driver users also would be able to Wayland, hopefully.
* With the **wallpaper** competition is back, we expect a stunning default wallpaper with “Indri” mascot. Already there are beautiful wallpapers submitted by the community, and they look promising.
* The applications and packages sees their respective version upgrades in this release. Heres a quick summary.
1. Firefox 89
2. LibreOffice 7.1 (I am still hopeful whether [LibreOffice 7.2][11] is an option)
3. Thunderbird 78.12
### Official Flavors
The official Ubuntu desktop flavors would have their respective version upgrades. Heres a quick update.
* Xubuntu with Xfce 4.16
* Ubuntu MATE with MATE 1.24
* Kubuntu with KDE Plasma 5.22 (I dont think Plasma 5.23 would be ready before BETA)
### Ubuntu 21.10 Release Date
Ubuntu 21.10 releases on October 14, 2021. Here is the schedule of this release.
* **Feature Freeze**: August 19, 2021
* **Beta Release**: September 23, 2021
* **Final Releas**e: October 14, 2021
### Daily Build Downloads for Ubuntu 21.10
Default desktop image .ISO for daily build is available in below link. The following images are unstable so, do not use this as your serious work. Try for testing only.
[download ubuntu 21.10 daily build GNOME][12]
#### Other flavors
Ubuntu Flavor | Link for Daily build .iso image (64 bit)
---|---
Ubuntu 21.10 Desktop (GNOME) | <https://cdimage.ubuntu.com/daily-live/current/>
Xubuntu 21.10 | <https://cdimage.ubuntu.com/xubuntu/daily-live/current/>
Ubuntu MATE 21.10 | <https://cdimage.ubuntu.com/ubuntu-mate/daily-live/current/>
Ubuntu Kylin 21.10 | <https://cdimage.ubuntu.com/ubuntukylin/daily-live/current/>
Lubuntu 21.10 | <https://cdimage.ubuntu.com/lubuntu/daily-live/current/>
Kubuntu 21.10 | <https://cdimage.ubuntu.com/kubuntu/daily-live/current/>
Ubuntu Budgie 21.10 | <https://cdimage.ubuntu.com/ubuntu-budgie/daily-live/current/>
### Untested Canary build
The daily canary build can be downloaded from the below link. This is super unstable and did not pass automatic testing. So, unless absolutely necessary, do not use this .iso.
<http://cdimage.ubuntu.com/daily-canary/pending/>
### Closing Notes
I am specifically interested on the new desktop installer. Because it gives a repair option and a brand-new way of installing Ubuntu. We know there are many powerful installers out there like Calamares but it would be interesting to see Ubuntus new Flutter based app. And the adaptation of GNOME 40 is really a thing to observe with more users.
I will keep this post updated with the latest info when available with details.
* _[Official change log and schedule][13]_
* _[Launchpad source][14]_
* * *
--------------------------------------------------------------------------------
via: https://www.debugpoint.com/2021/07/ubuntu-21-10/
作者:[Arindam][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://www.debugpoint.com/author/admin1/
[b]: https://github.com/lujun9972
[1]: tmp.Bd5zVlb4BJ#code-name
[2]: tmp.Bd5zVlb4BJ#new-features
[3]: tmp.Bd5zVlb4BJ#official-flavors
[4]: tmp.Bd5zVlb4BJ#release-schedule
[5]: tmp.Bd5zVlb4BJ#daily-build-download
[6]: tmp.Bd5zVlb4BJ#canary-build-download
[7]: https://www.debugpoint.com/blog/wp-content/uploads/2021/07/Ubuntu-21.10-Desktop-daily-build-1024x535.jpeg
[8]: https://www.debugpoint.com/2021/03/gnome-40-release/
[9]: https://www.debugpoint.com/2021/02/new-ubuntu-desktop-installer/
[10]: https://www.debugpoint.com/blog/wp-content/uploads/2021/07/New-Installer-Ubuntu-21.10.jpeg
[11]: https://www.debugpoint.com/2021/05/libreoffice-7-2/
[12]: https://cdimage.ubuntu.com/daily-live/current/
[13]: https://discourse.ubuntu.com/t/impish-indri-release-schedule/18540
[14]: https://launchpad.net/ubuntu/impish

View File

@ -2,7 +2,7 @@
[#]: via: "https://opensource.com/article/21/8/memory-programming-c"
[#]: author: "Marty Kalin https://opensource.com/users/mkalindepauledu"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: translator: "unigeorge"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
@ -688,7 +688,7 @@ via: https://opensource.com/article/21/8/memory-programming-c
作者:[Marty Kalin][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
译者:[unigeorge](https://github.com/unigeorge)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -1,83 +0,0 @@
[#]: subject: "Replace smart quotes with the Linux sed command"
[#]: via: "https://opensource.com/article/21/9/sed-replace-smart-quotes"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Replace smart quotes with the Linux sed command
======
Banish "smart" quotes with your favorite version of sed.
![Coding on a computer][1]
In typography, a pair of quotation marks were traditionally oriented toward one another. They look like this:
“smart quotes”
As computers became popular in the mid-twentieth century, the orientation was often abandoned. The original character set of computers didn't have much room to spare, so it makes sense that two double-quotes and two single-quotes were reduced down to just one of each in the ASCII specification. These days the common character set is Unicode, with plenty of space for lots of fancy quotation marks and apostrophes, but many people have become used to the minimalism of just one character for both opening and closing quotes. Besides that, computers actually see the different kinds of quotation marks and apostrophes as distinct characters. In other words, to a copmuter the right double quote is different from the left double quote or a straight quote.
### Replacing smart quotes with sed
Computers aren't typewriters. When you press a key on your keyboard, you're not pressing a lever with an inkstamp attached to it. You're just pressing a button that sends a signal to your computer, which the computer interprets as a request to display a specific predefined character. The request depends on your keyboard map. As a Dvorak typist, I've witnessed the confusion on people's faces when they discover "asdf" on my keyboard produces "aoeu" on the screen. You may also have pressed special combinations of keys to produce characters, such as ™ or ß or ≠, that's not even printed on your keyboard.
Each letter or character, whether it's printed on your keyboard or not, has a code. Character encoding can be expressed in different ways, but to a computer the Unicode sequences u2018 and u2019 produce **** and ****, while the codes u201c and u201d produce the **“** and **”** characters. Knowing these "secret" codes means you can replace them programmatically using a command like [sed][2]. Any version of sed will do, so you can use GNU sed or BSD sed or even [Busybox][3] sed.
Here's the simple shell script I use:
```
#!/bin/sh
# GNU All-Permissive License
SDQUO=$(echo -ne '\u2018\u2019')
RDQUO=$(echo -ne '\u201C\u201D')
$SED -i -e "s/[$SDQUO]/\'/g" -e "s/[$RDQUO]/\"/g" "${1}"
```
Save this script as `fixquotes.sh` and then create a separate test file containing smart quotes:
```
Single quote
“Double quote”
```
Run the script, and then use the [cat][4] command to see the results:
```
$ sh ./fixquotes.sh test.txt
$ cat test.txt
'Single quote'
"Double quote"
```
### Install sed
If youre using Linux, BSD, or macOS, then you already have GNU or BSD `sed` installed. These are two unique reimplementations of the original `sed` command, and for the script in this article they are functionally the same (that's not true for all scripts, though).
On Windows, you can [install GNU sed][5] with [Chocolatey][6].
Vim offers great benefits to writers, regardless of whether they are technically minded or not.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/sed-replace-smart-quotes
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer)
[2]: https://opensource.com/article/20/12/sed
[3]: https://opensource.com/article/21/8/what-busybox
[4]: https://opensource.com/article/19/2/getting-started-cat-command
[5]: https://chocolatey.org/packages/sed
[6]: https://opensource.com/article/20/3/chocolatey

View File

@ -1,378 +0,0 @@
[#]: subject: "Build a data sharding service with DistSQL"
[#]: via: "https://opensource.com/article/21/9/distsql"
[#]: author: "Meng Haoran https://opensource.com/users/haoran-meng"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Build a data sharding service with DistSQL
======
Database sharding demonstrates the additional functionality of DistSQL.
![Person standing in front of a giant computer screen with numbers, data][1]
If you're reading this, then you're probably familiar with the data query and programming language, SQL (Structured Query Language). It's also used as the standard language for management systems for accessing data, querying, updating, and managing relational database systems. Like standard SQL, DistSQL, or Distributed SQL, it is a built-in SQL language unique to ShardingSphere that provides incremental functional capabilities beyond standard SQL. Leveraging ShardingSphere's powerful SQL parsing engine, DistSQL provides a syntax structure and syntax validation system like that of standard SQL, making DistSQL more flexible while maintaining regularity. ShardingSphere's Database Plus concept aims at creating an open source distributed database system that is both functional and relevant to the actual database business. DistSQL is built on top of the traditional database to provide SQL capabilities that are both standards-compliant and feature ShardingSphere's functionality to enhance conventional database management.
### Original design intention of DistSQL
Over its years of rapid development, ShardingSphere has become unique in the database middleware space as the kernel has gradually stabilized, and the core functionality has continuously been honed. As an open source leader in Asia, ShardingSphere keeps pursuing its exploration of a distributed database ecosystem. Redefining the boundary between middleware and database to allow developers to leverage Apache ShardingSphere as if they were using a database natively is DistSQL's design goal. It is also an integral part of ShardingSphere's ability to transform from a developer-oriented framework and middleware to an operations-oriented infrastructure product.
### DistSQL syntax system
DistSQL has been designed from the outset to be standards-oriented, considering the habits of both database developers and operators. The syntax of DistSQL is based on the standard SQL language, maintaining readability and ease of use while retaining the maximum amount of ShardingSphere's own features and providing the highest possible number of customization options for users to cope with different business scenarios.
Developers familiar with SQL and ShardingSphere can get started quickly.
Standard SQL provides different types of syntaxes such as DQL, DDL, DML, DCL, etc., to define various functional SQL statements. DistSQL defines a syntax system of its own, as well.
In ShardingSphere, the DistSQL syntax is currently divided into three main types: RDL, RQL, and RAL.
* RDL (Resource &amp; Rule Definition Language) - Resource rule definition language for creating, modifying, and deleting resources and rules.
* RQL (Resource &amp; Rule Query Language) - Resource rule query language for querying and presenting resources and rules.
* RAL (Resource &amp; Rule Administrate Language) - Resource rule administration language for incremental functional operations such as hint, transaction type switching, and query of a sharding execution plan.
DistSQL's syntax builds a bridge for ShardingSphere to move towards a distributed database. It is still being improved as more ideas are implemented, so DistSQL will become increasingly powerful. Developers who are interested are welcome to join ShardingSphere and contribute ideas and code to DistSQL.
For more detailed syntax rules, please refer to the official [documentation][2].
For the project's community, please refer to the official [Slack channel][3].
### DistSQL in practice
Having understood the design concept and syntax system of DistSQL, let's demonstrate how to build a data sharding service based on ShardingSphere.
#### Environment preparation
* Start MySQL services
* Create a MySQL database for sharding
* Start the Zookeeper service
* Turn on the distributed governance configuration and start [ShardingSphere-Proxy][4]
#### Practical demonstration
1\. Connect to the launched ShardingSphere-Proxy using the MySQL command line.
2\. Create and query the distributed database `sharding_db`:
```
mysql&gt; CREATE DATABASE sharding_db;
Query OK, 0 ROWS affected (0.04 sec)
mysql&gt; SHOW DATABASES;
+-------------+
| SCHEMA_NAME |
+-------------+
| sharding_db |
+-------------+
1 ROW IN SET (0.04 sec)
```
3\. Use the newly created database:
```
mysql&gt; USE sharding_db;
No connection. Trying TO reconnect...
Connection id: 2
CURRENT DATABASE: *** NONE ***
DATABASE changed
```
4\. Execute RDL to configure two data source resources, `ds_1` and `ds_2`, for sharding:
```
mysql&gt; ADD RESOURCE ds_1 (
    -&gt; HOST=127.0.0.1,
    -&gt; PORT=3306,
    -&gt; DB=ds_1,
    -&gt; USER=root,
    -&gt; PASSWORD=root123456
    -&gt; );
Query OK, 0 ROWS affected (0.53 sec)
mysql&gt;
mysql&gt; ADD RESOURCE ds_2 (
    -&gt; HOST=127.0.0.1,
    -&gt; PORT=3306,
    -&gt; DB=ds_2,
    -&gt; USER=root,
    -&gt; PASSWORD=root123456
    -&gt; );
Query OK, 0 ROWS affected (0.02 sec)
```
5\. Execute RQL to query the newly added data source resources:
```
    mysql&gt; SHOW RESOURCES FROM sharding_db;
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | name | TYPE  | host      | port | db   | attribute                                                                                                                                                   |
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | ds_1 | MySQL | 127.0.0.1 | 3306 | ds_1 | {"maxLifetimeMilliseconds":1800000,"readOnly":FALSE,"minPoolSize":1,"idleTimeoutMilliseconds":60000,"maxPoolSize":50,"connectionTimeoutMilliseconds":30000} |
    | ds_2 | MySQL | 127.0.0.1 | 3306 | ds_2 | {"maxLifetimeMilliseconds":1800000,"readOnly":FALSE,"minPoolSize":1,"idleTimeoutMilliseconds":60000,"maxPoolSize":50,"connectionTimeoutMilliseconds":30000} |
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    2 ROWS IN SET (0.13 sec)
```
6\. Execute RDL to create a sharding rule for the `t_order` table:
```
mysql&gt; CREATE SHARDING TABLE RULE t_order(
    -&gt; RESOURCES(ds_1,ds_2),
    -&gt; SHARDING_COLUMN=order_id,
    -&gt; TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
    -&gt; GENERATED_KEY(COLUMN=order_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
    -&gt; );
Query OK, 0 ROWS affected (0.06 sec)
```
7\. Execute RQL to query the sharding rules:
```
    mysql&gt; SHOW SHARDING TABLE RULES FROM sharding_db;
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    | TABLE   | actualDataNodes | actualDataSources | databaseStrategyType | databaseShardingColumn | databaseShardingAlgorithmType | databaseShardingAlgorithmProps | tableStrategyType | tableShardingColumn | tableShardingAlgorithmType | tableShardingAlgorithmProps | keyGenerateColumn | keyGeneratorType | keyGeneratorProps |
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    | t_order |                 | ds_1,ds_2         |                      |                        |                               |                                | hash_mod          | order_id            | hash_mod                   | sharding-COUNT=4            | order_id          | snowflake        | worker-id=123     |
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    1 ROW IN SET (0.01 sec)
```
In addition to querying all sharding rules under the current database, RQL can also query individual tables for sharding rules with the following statement:
`SHOW SHARDING TABLE RULE t_order FROM sharding_db`
Creating and querying the `t_order` sharding table:
```
mysql&gt; CREATE TABLE `t_order`(
    -&gt; `order_id` INT NOT NULL,
    -&gt; `user_id` INT NOT NULL,
    -&gt; `status` VARCHAR(45) DEFAULT NULL,
    -&gt; PRIMARY KEY (`order_id`)
    -&gt; )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 ROWS affected (0.28 sec)
mysql&gt; SHOW TABLES;
+-----------------------+
| Tables_in_sharding_db |
+-----------------------+
| t_order               |
+-----------------------+
1 ROW IN SET (0.01 sec)
```
After successfully creating the sharding table `t_order` on the ShardingSphere-Proxy side, ShardingSphere automatically creates the sharding table based on the sharding rules of the `t_order` table by connecting to the underlying databases `ds_1` and `ds_2` via the client-side.
```
mysql&gt; USE ds_1;
DATABASE changed
mysql&gt; SHOW TABLES;
+----------------+
| Tables_in_ds_1 |
+----------------+
| t_order_0      |
| t_order_2      |
+----------------+
2 ROWS IN SET (0.01 sec)
[/code] [code]
mysql&gt; USE ds_2;
DATABASE changed
mysql&gt; SHOW TABLES;
+----------------+
| Tables_in_ds_2 |
+----------------+
| t_order_1      |
| t_order_3      |
+----------------+
2 ROWS IN SET (0.00 sec)
```
Once the sharding table is created, continue to execute the SQL statement on the ShardingSphere-Proxy side to insert the data:
```
mysql&gt; INSERT INTO t_order VALUES(1, 1, 'ok');
Query OK, 1 ROW affected (0.06 sec)
mysql&gt; INSERT INTO t_order VALUES(2, 2, 'disabled');
Query OK, 1 ROW affected (0.00 sec)
mysql&gt; INSERT INTO t_order VALUES(3, 3, 'locked');
Query OK, 1 ROW affected (0.01 sec)
mysql&gt; SELECT * FROM t_order;
+----------+---------+----------+
| order_id | user_id | STATUS   |
+----------+---------+----------+
|        1 |       1 | ok       |
|        2 |       2 | disabled |
|        3 |       3 | locked   |
+----------+---------+----------+
3 ROWS IN SET (0.06 sec)
```
Query the execution plan via RAL:
```
mysql&gt; preview SELECT * FROM t_order;
+-----------------+------------------------------------------------+
| datasource_name | SQL                                            |
+-----------------+------------------------------------------------+
| ds_1            | SELECT * FROM t_order_0 ORDER BY order_id ASC  |
| ds_1            | SELECT * FROM t_order_2 ORDER BY order_id ASC  |
| ds_2            | SELECT * FROM t_order_1 ORDER BY order_id ASC  |
| ds_2            | SELECT * FROM t_order_3 ORDER BY order_id ASC  |
+-----------------+------------------------------------------------+
4 ROWS IN SET (0.02 sec)
```
This completes the ShardingSphere data sharding service using DistSQL. Compared to the previous version of the ShardingSphere proxy, which was profile-driven, DistSQL is more developer-friendly and flexible in managing resources and rules. Moreover, the SQL-driven approach enables seamless interfacing between DistSQL and standard SQL.
```
schemaName: sharding_db
dataSources:
  ds_0:
    url: jdbc:mysql://127.0.0.1:3306/ds_1?serverTimezone=UTC&amp;useSSL=false
    username: root
    password: root123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_1:
    url: jdbc:mysql://127.0.0.1:3306/ds_2?serverTimezone=UTC&amp;useSSL=false
    username: root
    password: root123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
\- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_inline
      keyGenerateStrategy:
        column: order_id
        keyGeneratorName: snowflake
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_item_inline
      keyGenerateStrategy:
        column: order_item_id
        keyGeneratorName: snowflake
  bindingTables:
   - t_order,t_order_item
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
    t_order_item_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_item_${order_id % 2}
  keyGenerators:
    snowflake:
      type: SNOWFLAKE
      props:
        worker-id: 123
[/code] [code]
1\. CREATE a distributed DATABASE
CREATE DATABASE sharding_db;
2\. ADD DATA resources
ADD RESOURCE ds_1 (
HOST=127.0.0.1,
PORT=3306,
DB=ds_1,
USER=root,
PASSWORD=root123456
);
ADD RESOURCE ds_2 (
HOST=127.0.0.1,
PORT=3306,
DB=ds_2,
USER=root,
PASSWORD=root123456
);
3\. CREATE sharding rules
CREATE SHARDING TABLE RULE t_order(
RESOURCES(ds_1,ds_2),
SHARDING_COLUMN=order_id,
TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
GENERATED_KEY(COLUMN=order_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
);
```
In the above example, only a small part of the DistSQL syntax is demonstrated. In addition to creating and querying resources and rules via `CREATE` and `SHOW` statements, DistSQL also provides additional operations such as `ALTRE DROP` and supports configuration control of data sharding's core functions, read and write separation, data encryption, and database discovery.
### Conclusion
As one of the new features released in Apache ShardingSphere's 5.0.0-beta, DistSQL will continue to build on this release to improve syntax and increasingly powerful functions. DistSQL has opened up endless possibilities for ShardingSphere to explore the distributed database space. In the future, DistSQL will be used as a link to connect more functions and provide one-click operations.
For example, it'll allow the analysis of the overall database status with one click, connect with elastic migration, provide one-click data expansion and shrinkage, and connect with control to realize one-click master-slave switch and change database status. Open source and JavaScript enthusiasts are warmly welcomed to join the Slack community or check the project's GitHub page to learn more about ShardingSphere's latest developments.
* * *
_This article is adapted from the author's [original publication][5]._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/distsql
作者:[Meng Haoran][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/haoran-meng
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_metrics_analytics_desktop_laptop.png?itok=9QXd7AUr (Person standing in front of a giant computer screen with numbers, data)
[2]: https://shardingsphere.apache.org/document/current/en/features/dist-sql/syntax/
[3]: https://join.slack.com/t/apacheshardingsphere/shared_invite/zt-sbdde7ie-SjDqo9~I4rYcR18bq0SYTg
[4]: https://shardingsphere.apache.org/document/current/cn/quick-start/shardingsphere-proxy-quick-start/
[5]: https://shardingsphere.apache.org/blog/en/material/jul_26_an_introduction_to_distsql/

View File

@ -1,110 +0,0 @@
[#]: subject: "Raspberry Pi Zero vs Zero W: Whats the Difference?"
[#]: via: "https://itsfoss.com/raspberry-pi-zero-vs-zero-w/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Raspberry Pi Zero vs Zero W: Whats the Difference?
======
Raspberry Pi created a revolution when it launched the $25 mini computer ten years ago. Over the time, several variants of Raspberry Pi have been launched. Some upgrade a previous model and some are crafted for specific purposes.
Of all the Raspberry models, Pi Zero and Pi Zero W are the cheapest ones aimed for small scale and IoT projects. Both devices are almost similar to each other but with a subtle and important difference.
**So, what is the difference between Raspberry Pi Zero and Zero W? The W in Zero W stands for Wireless and it depicts its wireless capability over the Pi Zero model. Thats the single biggest difference between the two similar models.**
Lets take a look at a bit more in detail.
### Key Difference Between Pi Zero and Pi Zero W
![][1]
While Raspberry Pi Zero was built with a goal that provides more utility with half of the size of the A+ board.
And, Raspberry Pi Zero W was introduced later to include wireless connectivity built-in without needing a separate accessory/module to enable Bluetooth and Wi-Fi.
This is the key difference between the two with the rest of the specifications remaining identical.
So, if you want the support for:
* 802.11 b/g/n wireless LAN
* Bluetooth 4.1
* Bluetooth Low Energy (BLE)
Raspberry Pi Zero W will be the definite choice to go with.
Also, Raspberry Pi Zero W offers a variant with header pins included which is “Raspberry Pi Zero WH”.
Preview | Product | Price |
---|---|---|---
[![CanaKit Raspberry Pi Zero W \(Wireless\) Complete Starter Kit - 16 GB Edition][2]][3] | [CanaKit Raspberry Pi Zero W (Wireless) Complete Starter Kit - 16 GB Edition][3] | $32.99[][4] | [Buy on Amazon][5]
### Raspberry Pi Zero and Raspberry Pi Zero W Specifications
![Raspberry Pi Zero W][6]
The [specifications for Raspberry Pi Zero W][7] and Zero are almost identical.
You get a 1 GHz single-core CPU coupled with 512 MB RAM. For connectivity, you get a mini HDMI port, micro USB OTG support, micro USB power, and a CSI Camera connector (to plug in a camera module).
These boards also feature a [HAT][8] (Hardware Attached on Top)-compatible 40 pin header, but generally, without the pins that let you easily plug the interfaces.
You can choose to explore the capabilities using [various Raspberry Pi OS][9] available. In either case, just stick to the Raspberry Pi OS.
### Raspberry Pi Zero series: Is it worth It?
![Raspberry Pi Zero][10]
Raspberry Pi Zero is a single-board computer that is popular for its form factor. Even though you have plenty of [Raspberry Pi zero alternatives][11], Raspberry Pi Zero is the recommended choice for all the good reasons.
Of course, unless you have specific requirements.
In addition to the size of the board, the pricing, power requirement, and processing power are some of the key highlights of this board under **$20**.
So, if you are looking for the essential features under a budget, the Raspberry Zero series should work for you.
**Recommended Read:**
![][12]
#### [27 Super Cool Raspberry Pi Zero W Projects for DIY Enthusiasts][13]
The small form factor of the Raspberry Pi Zero W enables a new range of projects. Here are some cool projects you can build with your tiny Raspberry Pi Zero W.
### Is Raspberry Pi Zero series affordable?
Raspberry Pi Zero costs **$5** and the Raspberry Pi Zero W would cost you around **$10**. ****Of course, depending on its availability and region, the cost will differ. If you want the Raspberry Pi Zero W with header pins, it should cost you around **$14**.
There are other devices that can be used as an [alternative to Raspberry Pi Zero][11] and they have similar price tag.
--------------------------------------------------------------------------------
via: https://itsfoss.com/raspberry-pi-zero-vs-zero-w/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-vs-zero-w.png?resize=800%2C450&ssl=1
[2]: https://i1.wp.com/m.media-amazon.com/images/I/517BwcAPmTL._SL160_.jpg?ssl=1
[3]: https://www.amazon.com/dp/B072N3X39J?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (CanaKit Raspberry Pi Zero W (Wireless) Complete Starter Kit - 16 GB Edition)
[4]: https://www.amazon.com/gp/prime/?tag=chmod7mediate-20 (Amazon Prime)
[5]: https://www.amazon.com/dp/B072N3X39J?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (Buy on Amazon)
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-w.png?resize=600%2C400&ssl=1
[7]: https://itsfoss.com/raspberry-pi-zero-w/
[8]: https://github.com/raspberrypi/hats
[9]: https://itsfoss.com/raspberry-pi-os/
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-zero-1.png?resize=600%2C400&ssl=1
[11]: https://itsfoss.com/raspberry-pi-zero-alternatives/
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/10/raspberry-pi-zero-w-projects.png?fit=800%2C450&ssl=1
[13]: https://itsfoss.com/raspberry-pi-zero-projects/

View File

@ -1,125 +0,0 @@
[#]: subject: "Screen Recording in Linux With OBS and Wayland"
[#]: via: "https://itsfoss.com/screen-record-obs-wayland/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Screen Recording in Linux With OBS and Wayland
======
There are [tons of screen recorders available for Linux][1]. But when it comes to supporting [Wayland][2], almost all of them do not work.
This is problematic because many new distribution releases are switching to Wayland display manager by default once again. And if something as basic as a screen recorder does not work, it leaves a bad experience.
[GNOMEs built-in screen recorder][3] works but it is hidden, has no GUI and no way to configure and control the recordings. There is another tool called [Kooha][4] but it keeps on displaying a timer on the screen.
[Switching between Xorg and Wayland][5] just for screen recording is not very convenient.
Amidst all this, I was happy to learn that Wayland support landed in OBS Studio with version 27 release thanks to Pipewire. But even there, its not straightforward and hence I am going to show you the steps for screen recording on Wayland using [OBS Studio][6].
### Using OBS to screen record on Wayland
![][7]
Lets see how it is done.
#### Step 1: Install OBS Studio
You should install OBS Studio version 27 first. It is already included in Ubuntu 21.10 which I am suing in this tutorial.
To install OBS Studio 27 on Ubuntu 18.04, 20.04, Linux Mint 20 etc, use the [official OBS Studio][8] [][8][PPA][8].
Open a terminal and use the following commands one by one:
```
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt update
sudo apt install obs-studio
```
If there is an older version of OBS Studio installed already, it will be upgraded to the newer version.
For Fedora, Arch and other distributions, please check your package manager or unofficial repositories for installing the latest version of OBS Studio.
#### Step 2: Check if Wayland capture is working
Please make sure that you are using Wayland. Now start OBS Studio and go through all the stuff it shows on the first run. I am not going to show that.
The main step is to add Pipewire as a screen capture source. Click on the + symbol under the Sources list.
![Add screen capture source in OBS Studio][9]
Do you see anything that reads Screen Capture (PipeWire)?
![Do you see PipeWire option in the screen sources?][10]
**If the answer is no, quit OBS Studio**. This is normal. OBS Studio does not switch to use Wayland automatically in Ubuntu at least. There is a fix for that.
Open a terminal and use the following command:
```
export QT_QPA_PLATFORM=wayland
```
In the same terminal, run the following command to start OBS Studio:
```
obs
```
It will show some message on the terminal. Ignore them. Your focus should be on the OBS Studio GUI. Try to add screen capture once again. You should see the PipeWire option now.
![][10]
You explicitly asked OBS Studio to use Wayland this time with the QT_QPA_PLATFORM variable.
Select PipeWire as the source and then it asks you to choose a display screen. Select it and click on the Share button.
![][11]
Now it should show your screen recursively infinite number of times. If you see that, you could start recording the screen in Wayland now.
![][12]
#### Step 3: Make changes permanent
That was good. You just verified that you can record your screen on Wayland. But setting the environment variable and starting OBS from the terminal each time is not convenient.
What you can do is to **export the variable to your ~/.bash_profile (for you) or /etc/profile (for all users on the system).**
```
export QT_QPA_PLATFORM=wayland
```
Log out and log back in. Now OBS will automatically start using this parameter and you can use it to record your screen in Wayland.
I hope you find this quick tip helpful. If you still have questions or suggestions, please let me know in the comment section.
--------------------------------------------------------------------------------
via: https://itsfoss.com/screen-record-obs-wayland/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-linux-screen-recorders/
[2]: https://wayland.freedesktop.org/
[3]: https://itsfoss.com/gnome-screen-recorder/
[4]: https://itsfoss.com/kooha-screen-recorder/
[5]: https://itsfoss.com/switch-xorg-wayland/
[6]: https://obsproject.com/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-screen-record-wayland.webp?resize=800%2C450&ssl=1
[8]: https://launchpad.net/~obsproject/+archive/ubuntu/obs-studio
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-add-screen-capture-source.png?resize=800%2C537&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-wayland-support.png?resize=800%2C538&ssl=1
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-screen.png?resize=800%2C578&ssl=1
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/start-screen-recording-obs-wayland.jpg?resize=800%2C537&ssl=1

View File

@ -0,0 +1,460 @@
[#]: subject: "Crunch numbers in Python with NumPy"
[#]: via: "https://opensource.com/article/21/9/python-numpy"
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Crunch numbers in Python with NumPy
======
This article discusses installing NumPy, and then creating, reading, and
sorting NumPy arrays.
![old school calculator][1]
NumPy, or **Num**erical **Py**thon, is a library that makes it easy to do statistical and set operations on linear series and matrices in Python. It is orders of magnitude faster than Python lists, [which I covered in my notes on Python Data Types][2]. NumPy is used quite frequently in data analysis and scientific calculations.
I'm going to go over installing NumPy, and then creating, reading, and sorting NumPy arrays. NumPy arrays are also called _ndarrays_, short for **n-dimensional arrays**.
### Installing NumPy
Installing the NumPy package is really simple using `pip`, and it can be installed just like you would install any other package.
```
pip install numpy
```
With the NumPy package installed, just import it into your Python file.
```
import numpy as np
```
Importing `numpy` as `np` is a standard convention, but instead of using `np` you can use any other alias that you want.
### Why use NumPy? Because it is orders of magnitude faster than Python lists.
NumPy is orders of magnitude faster than normal Python lists when it comes to handling a large number of values. To see exactly how fast it is, I'm going to first measure the time it takes for `min()` and `max()` operations on a normal Python list.
I will first create a Python list with 999,999,999 items.
```
&gt;&gt;&gt; my_list = range(1, 1000000000)
&gt;&gt;&gt; len(my_list)
999999999
```
Now I'll measure the time for finding the minimum value in this list.
```
&gt;&gt;&gt; start = time.time()
&gt;&gt;&gt; min(my_list)
1
&gt;&gt;&gt; print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))
Time elapsed in milliseconds: 27007.00879096985
```
That took about 27,007 milliseconds or about **27 seconds**. Thats a long time. Now I'll try to find the time for finding the maximum value.
```
&gt;&gt;&gt; start = time.time()
&gt;&gt;&gt; max(my_list)
999999999
&gt;&gt;&gt; print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))
Time elapsed in milliseconds: 28111.071348190308
```
That took about 28,111 milliseconds, which is about **28 seconds**.
Now I'll try to find the time to find the minimum and maximum value using NumPy.
```
&gt;&gt;&gt; my_list = np.arange(1, 1000000000)
&gt;&gt;&gt; len(my_list)
999999999
&gt;&gt;&gt; start = time.time()
&gt;&gt;&gt; my_list.min()
1
&gt;&gt;&gt; print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))
Time elapsed in milliseconds: 1151.1778831481934
&gt;&gt;&gt;
&gt;&gt;&gt; start = time.time()
&gt;&gt;&gt; my_list.max()
999999999
&gt;&gt;&gt; print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))
Time elapsed in milliseconds: 1114.8970127105713
```
That took about 1151 milliseconds for finding the minimum value, and 1114 milliseconds for finding the maximum value. These are around **1 second**.
As you can see, using NumPy reduces the time to find the minimum and maximum of a list of around a billion values **from around 28 seconds to 1 second**. This is the power of NumPy.
### Creating ndarrays using Python lists
There are several ways to create an ndarray in NumPy.
You can create an ndarray by using a list of elements.
```
&gt;&gt;&gt; my_ndarray = np.array([1, 2, 3, 4, 5])
&gt;&gt;&gt; print(my_ndarray)
[1 2 3 4 5]
```
With the above ndarray defined, I'll check out a few things. First, the type of the variable defined above is `numpy.ndarray`. This is the type of all NumPy ndarrays.
```
&gt;&gt;&gt; type(my_ndarray)
&lt;class 'numpy.ndarray'&gt;
```
Another thing to note here would be _shape_. The shape of an ndarray is the length of each dimension of the ndarray. As you can see, the shape of `my_ndarray` is `(5,)`. This means that `my_ndarray` contains one dimension with 5 elements.
```
&gt;&gt;&gt; np.shape(my_ndarray)
(5,)
```
The number of dimensions in the array is called its _rank_. So the above ndarray has a rank of 1.
I'll define another ndarray `my_ndarray2` as a multi-dimensional ndarray. What will its shape be then? See below.
```
&gt;&gt;&gt; my_ndarray2 = np.array([(1, 2, 3), (4, 5, 6)])
&gt;&gt;&gt; np.shape(my_ndarray2)
(2, 3)
```
This is a rank 2 ndarray. Another attribute to check is the `dtype`, which is the data type. Checking the `dtype` for our ndarray gives us the following:
```
&gt;&gt;&gt; my_ndarray.dtype
dtype('int64')
```
The `int64` means that our ndarray is made up of 64-bit integers. NumPy cannot create an ndarray of mixed types, and must contain only one type of element. If you define an ndarray containing a mix of element types, NumPy will automatically typecast all the elements to the highest element type available that can contain all the elements.
For example, creating a mix of `int`s and `float`s will create a `float64` ndarray.
```
&gt;&gt;&gt; my_ndarray2 = np.array([1, 2.0, 3])
&gt;&gt;&gt; print(my_ndarray2)
[1. 2. 3.]
&gt;&gt;&gt; my_ndarray2.dtype
dtype('float64')
```
Also, setting one of the elements as `string` will create string ndarray of `dtype` equal to `<U21`, meaning our ndarray contains unicode strings.
```
&gt;&gt;&gt; my_ndarray2 = np.array([1, '2', 3])
&gt;&gt;&gt; print(my_ndarray2)
['1' '2' '3']
&gt;&gt;&gt; my_ndarray2.dtype
dtype('&lt;U21')
```
The `size` attribute will show the total number of elements that are present in our ndarray.
```
&gt;&gt;&gt; my_ndarray = np.array([1, 2, 3, 4, 5])
&gt;&gt;&gt; my_ndarray.size
5
```
### Creating ndarrays using NumPy methods
There are several NumPy methods available for creating ndarrays in case you dont want to create them directly using a list.
You can use `np.zeros()`  to create an ndarray full of zeroes. It takes a shape as a parameter, which is a list containing the number of rows and columns. It can also take an optional `dtype` parameter which is the data type of the ndarray.
```
&gt;&gt;&gt; my_ndarray = np.zeros([2,3], dtype=int)
&gt;&gt;&gt; print(my_ndarray)
[[0 0 0]
 [0 0 0]]
```
You can use `np.ones()` to create an ndarray full of ones.
```
&gt;&gt;&gt; my_ndarray = np.ones([2,3], dtype=int)
&gt;&gt;&gt; print(my_ndarray)
[[1 1 1]
 [1 1 1]]
```
You can use `np.full()` to fill an ndarray with a specific value.
```
&gt;&gt;&gt; my_ndarray = np.full([2,3], 10, dtype=int)
&gt;&gt;&gt; print(my_ndarray)
[[10 10 10]
 [10 10 10]]
```
You can use `np.eye()` to create an identity matrix/ndarray, which is a square matrix with ones all along the main diagonal. A square matrix is a matrix with the same number of rows and columns.
```
&gt;&gt;&gt; my_ndarray = np.eye(3, dtype=int)
&gt;&gt;&gt; print(my_ndarray)
[[1 0 0]
 [0 1 0]
 [0 0 1]]
```
You can use `np.diag()` to create a matrix with the specified values along the diagonal, and zeroes in the rest of the matrix.
```
&gt;&gt;&gt; my_ndarray = np.diag([10, 20, 30, 40, 50])
&gt;&gt;&gt; print(my_ndarray)
[[10  0  0  0  0]
 [ 0 20  0  0  0]
 [ 0  0 30  0  0]
 [ 0  0  0 40  0]
 [ 0  0  0  0 50]]
```
You can use `np.arange()` to create an ndarray with a specific range of values. It is used by specifying a start and end (exclusive) range of integers and a step size.
```
&gt;&gt;&gt; my_ndarray = np.arange(1, 20, 3)
&gt;&gt;&gt; print(my_ndarray)
[ 1  4  7 10 13 16 19]
```
### Reading ndarrays
The values of an ndarray can be read using indexing, slicing, or boolean indexing.
#### Reading ndarrays using indexing
In indexing, you can read the values using the integer indices of the elements of the ndarray, much like you would read a Python list. Just like Python lists, the indices start from zero.
For example, in the ndarray defined as below:
```
&gt;&gt;&gt; my_ndarray = np.arange(1, 20, 3)
```
The fourth value will be `my_ndarray[3]`, or `10`. The last value will be `my_ndarray[-1]`, or `19`.
```
&gt;&gt;&gt; my_ndarray = np.arange(1, 20, 3)
&gt;&gt;&gt; print(my_ndarray[0])
1
&gt;&gt;&gt; print(my_ndarray[3])
10
&gt;&gt;&gt; print(my_ndarray[-1])
19
&gt;&gt;&gt; print(my_ndarray[5])
16
&gt;&gt;&gt; print(my_ndarray[6])
19
```
#### Reading ndarrays using slicing
You can also use slicing to read chunks of the ndarray. Slicing works by specifying a start index and an end index using a colon (`:`) operator. Python will then fetch the slice of the ndarray between that start and end index.
```
&gt;&gt;&gt; print(my_ndarray[:])
[ 1  4  7 10 13 16 19]
&gt;&gt;&gt; print(my_ndarray[2:4])
[ 7 10]
&gt;&gt;&gt; print(my_ndarray[5:6])
[16]
&gt;&gt;&gt; print(my_ndarray[6:7])
[19]
&gt;&gt;&gt; print(my_ndarray[:-1])
[ 1  4  7 10 13 16]
&gt;&gt;&gt; print(my_ndarray[-1:])
[19]
```
Slicing creates a reference, or view, of an ndarray. This means that modifying the values in a slice will also change the values of the original ndarray.
For example:
```
&gt;&gt;&gt; my_ndarray[-1:] = 100
&gt;&gt;&gt; print(my_ndarray)
[  1   4   7  10  13  16 100]
```
For slicing ndarrays with rank more than 1, the `[row-start-index:row-end-index, column-start-index:column-end-index]` syntax can be used.
```
&gt;&gt;&gt; my_ndarray2 = np.array([(1, 2, 3), (4, 5, 6)])
&gt;&gt;&gt; print(my_ndarray2)
[[1 2 3]
 [4 5 6]]
&gt;&gt;&gt; print(my_ndarray2[0:2,1:3])
[[2 3]
 [5 6]]
```
#### Reading ndarrays using boolean indexing
Another way to read ndarrays is using boolean indexing. In this method, you specify a filtering condition within square brackets and a section of the ndarray that matches that criteria is returned.
For example, to get all the values in an ndarray greater than 5, you might specify a boolean indexing operation as `my_ndarray[my_ndarray > 5]`. This operation will return an ndarray that contains all values greater than 5.
```
&gt;&gt;&gt; my_ndarray = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
&gt;&gt;&gt; my_ndarray2 = my_ndarray[my_ndarray &gt; 5]
&gt;&gt;&gt; print(my_ndarray2)
[ 6  7  8  9 10]
```
For example, to get all the even values in an ndarray, you might use a boolean indexing operation as follows:
```
&gt;&gt;&gt; my_ndarray2 = my_ndarray[my_ndarray % 2 == 0]
&gt;&gt;&gt; print(my_ndarray2)
[ 2  4  6  8 10]
```
And to get all the odd values, you might use this:
```
&gt;&gt;&gt; my_ndarray2 = my_ndarray[my_ndarray % 2 == 1]
&gt;&gt;&gt; print(my_ndarray2)
[1 3 5 7 9]
```
### Vector and scalar arithmetic with ndarrays
NumPy ndarrays allow vector and scalar arithmetic operations. In vector arithmetic, an element-wise arithmetic operation is performed between two ndarrays. In scalar arithmetic, an arithmetic operation is performed between an ndarray and a constant scalar value.
Consider the two ndarrays below.
```
&gt;&gt;&gt; my_ndarray = np.array([1, 2, 3, 4, 5])
&gt;&gt;&gt; my_ndarray2 = np.array([6, 7, 8, 9, 10])
```
If you add the above two ndarrays, it would produce a new ndarray where each element of the two ndarrays would be added. For example, the first element of the resultant ndarray would be the result of adding the first elements of the original ndarrays, and so on.
```
&gt;&gt;&gt; print(my_ndarray2 + my_ndarray)
[ 7  9 11 13 15]
```
Here, `7` is the sum of `1` and `6`, which are the first two elements of the ndarrays I've added together. Similarly, `15` is the sum of `5` and `10`, which are the last elements.
Consider the following arithmetic operations:
```
&gt;&gt;&gt; print(my_ndarray2 - my_ndarray)
[5 5 5 5 5]
&gt;&gt;&gt;
&gt;&gt;&gt; print(my_ndarray2 * my_ndarray)
[ 6 14 24 36 50]
&gt;&gt;&gt;
&gt;&gt;&gt; print(my_ndarray2 / my_ndarray)
[6.         3.5        2.66666667 2.25       2.        ]
```
Adding a scalar value to an ndarray has a similar effect—the scalar value is added to all the elements of the ndarray. This is called _broadcasting_.
```
&gt;&gt;&gt; print(my_ndarray + 10)
[11 12 13 14 15]
&gt;&gt;&gt;
&gt;&gt;&gt; print(my_ndarray - 10)
[-9 -8 -7 -6 -5]
&gt;&gt;&gt;
&gt;&gt;&gt; print(my_ndarray * 10)
[10 20 30 40 50]
&gt;&gt;&gt;
&gt;&gt;&gt; print(my_ndarray / 10)
[0.1 0.2 0.3 0.4 0.5]
```
### Sorting ndarrays
There are two ways available to sort ndarrays—in-place or out-of-place. In-place sorting sorts and modifies the original ndarray, and out-of-place sorting will return the sorted ndarray but not modify the original one. I'll try out both examples.
```
&gt;&gt;&gt; my_ndarray = np.array([3, 1, 2, 5, 4])
&gt;&gt;&gt; my_ndarray.sort()
&gt;&gt;&gt; print(my_ndarray)
[1 2 3 4 5]
```
As you can see, the `sort()` method sorts the ndarray in-place and modifies the original array.
There is another method called `np.sort()` which sorts the array out of place.
```
&gt;&gt;&gt; my_ndarray = np.array([3, 1, 2, 5, 4])
&gt;&gt;&gt; print(np.sort(my_ndarray))
[1 2 3 4 5]
&gt;&gt;&gt; print(my_ndarray)
[3 1 2 5 4]
```
As you can see, the `np.sort()` method returns a sorted ndarray but does not modify it.
### Conclusion
I've covered quite a bit about NumPy and ndarrays. I talked about creating ndarrays, the different ways of reading them, basic vector and scalar arithmetic, and sorting. There is a lot more to explore with NumPy, including set operations like `union()` and `intersection()`, statistical operations like `min()` and `max()`, etc.
I hope the examples I demonstrated above were useful. Have fun exploring NumPy.
* * *
_This article was originally published on the [author's personal blog][3] and has been adapted with permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/python-numpy
作者:[Ayush Sharma][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/ayushsharma
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/math_money_financial_calculator_colors.jpg?itok=_yEVTST1 (old school calculator)
[2]: https://notes.ayushsharma.in/2018/09/data-types-in-python
[3]: https://notes.ayushsharma.in/2018/10/working-with-numpy-in-python

View File

@ -0,0 +1,188 @@
[#]: subject: "Debugging by starting a REPL at a breakpoint is fun"
[#]: via: "https://jvns.ca/blog/2021/09/16/debugging-in-a-repl-is-fun/"
[#]: author: "Julia Evans https://jvns.ca/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Debugging by starting a REPL at a breakpoint is fun
======
Hello! I was talking to a Python programmer friend yesterday about debugging, and I mentioned that I really like debugging using a REPL. He said hed never tried it and that it sounded fun, so I thought Id write a quick post about it.
This debugging method doesnt work in a lot of languages, but it does work in Python and Ruby and kiiiiiind of in C (via gdb).
### whats a REPL?
REPL stands for “read eval print loop”. A REPL is a program that:
1. reads some input from you like `print(f"2 + 2 = {2+2}")` (**read**)
2. evaluates the input (**eval**)
3. print out the result (**print**)
4. and then goes back to step 1 (**loop**)
Heres an example of me using the IPython REPL to run a print statement. (also it demonstrates f-strings, my favourite Python 3 feature)
```
$ ipython3
Python 3.9.5 (default, May 24 2021, 12:50:35)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.24.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: print(f"2 + 2 = {2+2}")
2 + 2 = 4
In [2]:
```
### you can start a REPL at a breakpoint
There are 2 ways to use a REPL when debugging.
**Way 1**: Open an empty REPL (like IPython, pry, or a browser Javascript console) to test out something.
This is great but its not what Im talking about in this post.
**Way 2**: Set a breakpoint in your program, and start a REPL at that breakpoint.
This is the one were going to be talking about. I like doing this because it gives me both:
1. all the variables in scope at the breakpoint, so I can print them out interactively
2. easy access to all the functions in my program, so I can call them to try to find issues
### how to get a REPL in Python: `ipdb.set_trace()`
Heres a program called `test.py` that sets a breakpoint on line 5 using `import ipdb; ipdb.set_trace()`.
```
import requests
def make_request():
result = requests.get("https://google.com")
import ipdb; ipdb.set_trace()
make_request()
```
And heres what it looks like when you run it: you get a REPL where you can inspect the `result` variable or do anything else you want.
```
python3 test.py
--Return--
None
> /home/bork/work/homepage/test.py(5)make_request()
4 result = requests.get("https://google.com")
----> 5 import ipdb; ipdb.set_trace()
6
ipdb> result.headers
{'Date': 'Thu, 16 Sep 2021 13:11:19 GMT', 'Expires': '-1', 'Cache-Control': 'private, max-age=0', 'Content-Type': 'text/html; charset=ISO-8859-1', 'P3P': 'CP="This is not a P3P policy! See g.co/p3phelp for more info."', 'Content-Encoding': 'gzip', 'Server': 'gws', 'X-XSS-Protection': '0', 'X-Frame-Options': 'SAMEORIGIN', 'Set-Cookie': '1P_JAR=2021-09-16-13; expires=Sat, 16-Oct-2021 13:11:19 GMT; path=/; domain=.google.com; Secure, NID=223=FXhKNT7mgxX7Fjhh6Z6uej9z13xYKdm9ZuAU540WDoIwYMj9AZzWTgjsVX-KJF6GErxfMijl-uudmjrJH1wgH3c1JjudPcmDMJovNuuAiJqukh1dAao_vUiqL8ge8pSIXRx89vAyYy3BDRrpJHbEF33Hbgt2ce4_yCZPtDyokMk; expires=Fri, 18-Mar-2022 13:11:19 GMT; path=/; domain=.google.com; HttpOnly', 'Alt-Svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"', 'Transfer-Encoding': 'chunked'}
```
You have to install `ipdb` to make this work, but I think its worth it `import pdb; pdb.set_trace()` will work too (and is built into Python) but `ipdb` is much nicer. I just learned that you can also use `breakpoint()` in Python 3 to get a breakpoint, but that puts you in `pdb` too which I dont like.
### how to get a REPL in Ruby: `binding.pry`
Heres the same thing in Ruby I wrote a `test.rb` program:
```
require 'net/http'
require 'pry'
def make_request()
result = Net::HTTP.get_response('example.com', '/')
binding.pry
end
make_request()
```
and heres what it looks like when I run it:
```
$ ruby test.rb
From: /home/bork/work/homepage/test.rb:6 Object#make_request:
4: def make_request()
5: result = Net::HTTP.get_response('example.com', '/')
=> 6: binding.pry
7: end
[1] pry(main)> result.code
=> "200"
```
### you can also do get a REPL in the middle of an HTTP request
Rails also lets you start a REPL in the middle of a HTTP request and poke around and see whats happening. I assume you can do this in Flask and Django too Ive only really done this in Sinatra (in Ruby).
### GDB is sort of like a REPL for C
I was talking to another friend about REPLs, and we agreed that GDB is a little bit like a REPL for C.
Now, obviously this is sort of not true C is a compiled language, and you cant just type in arbitrary C expressions in GDB and have them work.
But you can do a surprising number of things like:
* call functions
* inspect structs if your program has debugging symbols (`p var->field->subfield`)
This stuff only works in gdb because the gdb developers put in a lot of work doing Very Weird Things to make it easier to get a REPL-like experience. I wrote a blog post a few years called [how does gdb call functions?][1] about how surprising it is that gdb can call functions, and how it does that.
This is the only way I use `gdb` when looking at C programs I never set watchpoints or do anything fancy, I just set a couple of breakpoints in the program and then poke around at those points.
### where this method works
languages where this works:
* Python
* Ruby
* probably PHP, but I dont know
* C, sort of, in a weird way (though you might disagree :))
languages where this doesnt work:
* most compiled languages
* in Javascript, I think even though you can get a REPL with `node inspect` and `debugger`, the REPL doesnt integrate well with async functions which makes it less useful. I dont really understand this yet though. (pythons REPL also doesnt let you use `await`, but its not as big of a deal because async programming in Python isnt as core a part of the language as in JS)
### REPL debugging is easy for me to remember how to do
There are (at least) 4 different ways of debugging:
1. Lots of print statements
2. a debugger
3. getting a REPL at a breakpoint
4. inspect your program with external tools like strace
I think part of the reason I like this type of REPL debugging more than using a more traditional debugger is its so easy to remember how to do it! I can just set a breakpoint, and then run code to try to figure out whats wrong.
With debuggers, I always forget how to use the debugger (probably partly because I switch programming languages a lot) and I get confused about what features it has and how they work, so I never use it.
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2021/09/16/debugging-in-a-repl-is-fun/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/

View File

@ -0,0 +1,865 @@
[#]: subject: "How I patched Python to include this great Ruby feature"
[#]: via: "https://opensource.com/article/21/9/python-else-less"
[#]: author: "Miguel Brito https://opensource.com/users/miguendes"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How I patched Python to include this great Ruby feature
======
What I learned from adding "else-less" functionality to Python, as
inspired by Ruby.
![Python programming language logo with question marks][1]
Ruby, [unlike Python][2], makes lots of things implicit, and there's a special kind of _if_ expression that demonstrates this well. It's often referred to as an "inline-if" or "conditional modifier", and this special syntax is able to return one value when a condition is true, but another value (`nil`, specifically) when a condition is false. Here's an example:
```
$ irb
irb(main):&gt; RUBY_VERSION
=&gt; "2.7.1"
irb(main):&gt; a = 42 if true
=&gt; 42
irb(main):&gt; b = 21 if false
=&gt; nil
irb(main):&gt; b
=&gt; nil
irb(main):&gt; a
=&gt; 42
```
In Python, you can't do that without explicitly adding an `else` clause to the expression. In fact, as of [this PR][3], the interpreter tells you immediately that `else` is mandatory:
```
$ python
Python 3.11.0a0
&gt;&gt;&gt; a = 42 if True
  File "&lt;stdin&gt;", line 1
    ;a = 42 if True
    ^^^^^^^^^^
SyntaxError: expected 'else' after 'if' expression
```
However, I find Ruby's `if` actually very convenient.
![return if python][4]
Python accepts else-less if statements, similar to Ruby.
This convenience became more evident when I had to go back to Python and write things like this:
```
`>>> my_var = 42 if some_cond else None`
```
So I thought to myself, what would it be like if Python had a similar feature? Could I do it myself? How hard would that be?
### Looking into Python's source code
Digging into CPython's code and changing the language's syntax sounded not trivial to me. Luckily, during the same week, I found out on Twitter that [Anthony Shaw][5] had just written a [book on CPython Internals][6] and it was available for pre-release. I didn't think twice and bought the book. I've got to be honest, I'm the kind of person who buys things and doesn't use them immediately. As I had other plans in mind, I let it "gather dust" in my home folder until I had to work with that Ruby service again. It reminded me of the CPython Internals book and how challenging hacking the guts of Python would be.
The first thing was to go through the book from the very start and try to follow each step. The book focuses on Python 3.9, so in order to follow it, one needs to check out the 3.9 tag, and that's what I did. I learned about how the code is structured and then how to compile it. The next chapters show how to extend the grammar and add new things, such as a new operator.
As I got familiar with the code base and how to tweak the grammar, I decided to give it a spin and make my own changes to it.
### The first (failed) attempt
As I started finding my way around CPython's code from the latest main branch, I noticed that lots of things had changed since Python 3.9, yet some fundamental concepts didn't.
My first attempt was to dig into the grammar definition and find the if expression rule. The file is currently named `Grammar/python.gram`. Locating it was not difficult. An ordinary **CTRL+F** for the `else` keyword was enough.
```
file: Grammar/python.gram
...
expression[expr_ty] (memo):
   | invalid_expression
   | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
   | disjunction
   | lambdef
....
```
Now with the rule in hand, my idea was to add one more option to the current `if` expression where it would match `a=disjunction 'if' b=disjunction` and the `c` expression would be `NULL`.
This new rule should be placed immediately after the complete one, otherwise, the parser would match `a=disjunction 'if' b=disjunction` always, returning a `SyntaxError`.
```
...
expression[expr_ty] (memo):
   | invalid_expression
   | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
   | a=disjunction 'if' b=disjunction { _PyAST_IfExp(b, a, NULL, EXTRA) }
   | disjunction
   | lambdef
....
```
### Regenerating the parser and compiling Python from source
CPython comes with a `Makefile` containing lots of useful commands. One of them is the [`regen-pegen` command][7] which converts `Grammar/python.gram` into `Parser/parser.c`.
Besides changing the grammar, I had to modify the AST for the _if_ expression. AST stands for Abstract Syntax Tree, and it is a way of representing the syntactic structure of the grammar as a tree. For more information about ASTs, I highly recommend the [Crafting Interpreters book][8] by [Robert Nystrom][9].
Moving on, if you observe the rule for the _if_ expression, it goes like this:
```
`   | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }`
```
The means when the parser finds this rule, it calls the `_PyAST_IfExp`, which gives back a `expr_ty` data structure. So this gave me a clue that to implement the new rule's behavior, I'd need to change `_PyAST_IfExp`.
To find where it is located, I used my `rip-grep` skills and searched for it inside the source root:
```
$ rg _PyAST_IfExp -C2 .
[OMITTED]
Python/Python-ast.c
2686-
2687-expr_ty
2688:_PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
2689- col_offset, int end_lineno, int end_col_offset, PyArena *arena)
2690-{
[OMITTED]
```
The implementation goes like this:
```
expr_ty
_PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
   expr_ty p;
   if (!test) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'test' is required for IfExp");
       return NULL;
   }
   if (!body) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'body' is required for IfExp");
        return NULL;
   }
   if (!orelse) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'orelse' is required for IfExp");
        return NULL;
   }
   p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
   if (!p)
        return NULL;
   p-&gt;kind = IfExp_kind;
   p-&gt;v.IfExp.test = test;
   p-&gt;v.IfExp.body = body;
   p-&gt;v.IfExp.orelse = orelse;
   p-&gt;lineno = lineno;
   p-&gt;col_offset = col_offset;
   p-&gt;end_lineno = end_lineno;
   p-&gt;end_col_offset = end_col_offset;
   return p;
}
```
Since I passed **orelse**NULL, I thought it was just a matter of changing the body of `if (!orelse)`None to `orelse`. It would look like this:
```
   if (!orelse) {
\- PyErr_SetString(PyExc_ValueError,
\- "field 'orelse' is required for IfExp");
\- return NULL;
\+ orelse = Py_None;
   }
```
Now it was time to test it. I compiled the code with `make -j8 -s` and fired up the interpreter:
```
$ make -j8 -s
Python/Python-ast.c: In function _PyAST_IfExp:
Python/Python-ast.c:2703:16: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         orelse = Py_None;
```
Despite the glaring obvious warnings, I decided to ignore it just to see what would happen.
```
$ ./python
Python 3.11.0a0 (heads/ruby-if-new-dirty:f92b9133ef, Aug 2 2021, 09:13:02) [GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; a = 42 if True
&gt;&gt;&gt; a
42
&gt;&gt;&gt; b = 21 if False
[1] 16805 segmentation fault (core dumped) ./python
```
Ouch! It worked for the `if True` case, but assigning `Py_None` to `expr_ty orelse` caused a `segfault`.
Time to go back to see what went wrong.
### The second attempt
It wasn't too difficult to figure out where I messed up. `orelse` is an `expr_ty`, and I assigned to it a `Py_None` which is a `PyObject *`. Again, thanks to `rip-grep`, I found its definition:
```
$ rg constant -tc -C2
Include/internal/pycore_asdl.h
14-typedef PyObject * string;
15-typedef PyObject * object;
16:typedef PyObject * constant;
```
Now, how did I find out `Py_None` was a constant?
While reviewing the `Grammar/python.gram` file, I found that one of the rules for the new pattern matching syntax is defined like this:
```
# Literal patterns are used for equality and identity constraints
literal_pattern[pattern_ty]:
   | value=signed_number !('+' | '-') { _PyAST_MatchValue(value, EXTRA) }
   | value=complex_number { _PyAST_MatchValue(value, EXTRA) }
   | value=strings { _PyAST_MatchValue(value, EXTRA) }
   | 'None' { _PyAST_MatchSingleton(Py_None, EXTRA) }
```
However, this rule is a `pattern_ty`, not an `expr_ty`. But that's fine. What really matters is to understand what `_PyAST_MatchSingleton` actually is. Then, I searched for it in `Python/Python-ast.c:`
```
file: Python/Python-ast.c
...
pattern_ty
_PyAST_MatchSingleton(constant value, int lineno, int col_offset, int
                        end_lineno, int end_col_offset, PyArena *arena)
...
```
I looked for the definition of a `None` node in the grammar. To my great relief, I found it!
```
atom[expr_ty]:
   | NAME
   | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) }
   | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
   | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) }
....
```
At this point, I had all the information I needed. To return an `expr_ty` representing `None`, I needed to create a node in the AST which is constant by using the `_PyAST_Constant` function.
```
   | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
\- | a=disjunction 'if' b=disjunction { _PyAST_IfExp(b, a, NULL, EXTRA) }
\+ | a=disjunction 'if' b=disjunction { _PyAST_IfExp(b, a, _PyAST_Constant(Py_None, NULL, EXTRA), EXTRA) }
   | disjunction
```
Next, I must revert `Python/Python-ast.c` as well. Since I'm feeding it a valid `expr_ty`, it will never be `NULL`.
```
file: Python/Python-ast.c
...
   if (!orelse) {
\- orelse = Py_None;
\+ PyErr_SetString(PyExc_ValueError,
\+ "field 'orelse' is required for IfExp");
\+ return NULL;
   }
...
```
I compiled it again:
```
$ make -j8 -s &amp;&amp; ./python
Python 3.11.0a0 (heads/ruby-if-new-dirty:25c439ebef, Aug 2 2021, 09:25:18) [GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; c = 42 if True
&gt;&gt;&gt; c
42
&gt;&gt;&gt; b = 21 if False
&gt;&gt;&gt; type(b)
&lt;class 'NoneType'&gt;
&gt;&gt;&gt;
```
It works!
Now, I needed to do one more test. Ruby functions allow returning a value if a condition matches, and if not, the rest of the function body gets executed. Like this:
```
&gt; irb
irb(main):&gt; def f(test)
irb(main):&gt;   return 42 if test
irb(main):&gt;   puts 'missed return'
irb(main):&gt;   return 21
irb(main):&gt; end
=&gt; :f
irb(main):&gt; f(false)
missed return
=&gt; 21
irb(main):&gt; f(true)
=&gt; 42
```
At this point, I wondered if that would work with my modified Python. I rushed to the interpreter again and wrote the same function:
```
&gt;&gt;&gt; def f(test):
... return 42 if test
... print('missed return')
... return 21
...
&gt;&gt;&gt; f(False)
&gt;&gt;&gt; f(True)
42
&gt;&gt;&gt;
```
The function returns `None` if _test_ is `False`... To help me debug this, I summoned the [ast module][10]. The official docs define it like so:
> The ast module helps Python applications to process trees of the Python abstract syntax grammar. The abstract syntax itself might change with each Python release; this module helps to find out programmatically what the current grammar looks like.
I printed the AST for this function:
```
&gt;&gt;&gt; fc = '''
... def f(test):
... return 42 if test
... print('missed return')
... return 21
... '''
&gt;&gt;&gt; print(ast.dump(ast.parse(fc), indent=4))
Module(
   body=[
        FunctionDef(
            name='f',
            args=arguments(
                posonlyargs=[],
                args=[
                  arg(arg='test')],
                kwonlyargs=[],
                kw_defaults=[],
                defaults=[]),
            body=[
                Return(
                  value=IfExp(
                  test=Name(id='test', ctx=Load()),
                  ;body=Constant(value=42),
                  orelse=Constant(value=None))),
                Expr(
                  value=Call(
                    func=Name(id='print', ctx=Load()),
                      args=[
                        Constant(value='missed return')],
                      keywords=[])),
                  Return(
                      value=Constant(value=21))],
            decorator_list=[])],
   type_ignores=[])
```
Now things made more sense. My change to the grammar was just "syntax sugar". It turns an expression like this: `a if b` into this: `a if b else None`. The problem here is that Python returns no matter what, so the rest of the function is ignored.
You can look at the [bytecode][11] generated to understand what exactly is executed by the interpreter. And for that, you can use the [`dis` module][12]. According to the docs:
> The dis module supports the analysis of CPython bytecode by disassembling it.
```
&gt;&gt;&gt; import dis
&gt;&gt;&gt; dis.dis(f)
  2 0 LOAD_FAST 0 (test)
              2 POP_JUMP_IF_FALSE 4 (to 8)
              4 LOAD_CONST 1 (42)
              6 RETURN_VALUE
        &gt;&gt; 8 LOAD_CONST 0 (None)
            10 RETURN_VALUE
```
What this basically means is that in case the _test_ is false, the execution jumps to 8, which loads the `None` into the top of the stack and returns it.
### Supporting "return-if"
To support the same Ruby feature, I need to turn the expression `return 42 if test` into a regular `if` statement that returns if `test` is true.
To do that, I needed to add one more rule. This time, it would be a rule that matches the `return <value> if <test>` piece of code. Not only that, I needed a `_PyAST_` function that creates the node for me. I'll then call it `_PyAST_ReturnIfExpr:`
```
file: Grammar/python.gram
return_stmt[stmt_ty]:
\+ | 'return' a=star_expressions 'if' b=disjunction { _PyAST_ReturnIfExpr(a, b, EXTRA) }
   | 'return' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
```
As mentioned previously, the implementation for all these functions resides in `Python/Python-ast.c`, and their definition is in `Include/internal/pycore_ast.h`, so I put `_PyAST_ReturnIfExpr` there:
```
file: Include/internal/pycore_ast.h
 stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int
                      end_lineno, int end_col_offset, PyArena *arena);
+stmt_ty _PyAST_ReturnIfExpr(expr_ty value, expr_ty test, int lineno, int col_of
fset, int
\+ end_lineno, int end_col_offset, PyArena *arena);
 stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
                      end_lineno, int end_col_offset, PyArena *arena);
[/code] [code]
file: Python/Python-ast.c
+stmt_ty
+_PyAST_ReturnIfExpr(expr_ty value, expr_ty test, int lineno, int col_offset, int end_lineno, int
\+ end_col_offset, PyArena *arena)
+{
\+ stmt_ty ret, p;
\+ ret = _PyAST_Return(value, lineno, col_offset, end_lineno, end_col_offset, arena);
+
\+ asdl_stmt_seq *body;
\+ body = _Py_asdl_stmt_seq_new(1, arena);
\+ asdl_seq_SET(body, 0, ret);
+
\+ p = _PyAST_If(test, body, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
+
\+ return p;
+}
+
 stmt_ty
```
I examined the implementation of `_PyAST_ReturnIfExpr`. I wanted to turn `return <value> if <test>` into `if <test>: return <value>`.
Both `return` and the regular `if` are statements, so in CPython, they're represented as `stmt_ty`. The `_PyAST_If` expectes a `expr_ty test` and a body, which is a sequence of statements. In this case, the `body` is `asdl_stmt_seq *body`.
As a result, what I really wanted here was an `if` statement with a body where the only statement is a `return <value>` one.
CPython disposes of some convenient functions to build `asdl_stmt_seq *`, and one of them is `_Py_asdl_stmt_seq_new`. So I used it to create the body and added the return statement I created a few lines before with `_PyAST_Return`.
Once that was done, the last step was to pass the `test` as well as the `body` to `_PyAST_If`.
And before I forget, you may be wondering what on earth is the `PyArena *arena`. **Arena** is a CPython abstraction used for memory allocation. It allows efficient memory usage by using memory mapping [mmap()][13] and placing it in contiguous [chunks of memory][6].
Time to regenerate the parser and test it one more time:
```
&gt;&gt;&gt; def f(test):
... return 42 if test
... print('missed return')
... return 21
...
&gt;&gt;&gt; import dis
&gt;&gt;&gt; f(False)
&gt;&gt;&gt; f(True)
42
```
It doesn't work. Check the bytecodes:
```
&gt;&gt;&gt; dis.dis(f)
  2 0 LOAD_FAST 0 (test)
            2 POP_JUMP_IF_FALSE 4 (to 8)
            4 LOAD_CONST 1 (42)
            6 RETURN_VALUE
        &gt;&gt; 8 LOAD_CONST 0 (None)
        10 RETURN_VALUE
&gt;&gt;&gt;
```
It's the same bytecode instructions again!
### Going back to the compilers class
At that point, I was clueless. I had no idea what was going on until I decided to go down the rabbit hole of expanding the grammar rules.
The new rule I added went like this: `'return' a=star_expressions 'if' b=disjunction { _PyAST_ReturnIfExpr(a, b, EXTRA) }`.
My only hypothesis was that `a=star_expressions 'if' b=disjunction` was being resolved to the else-less rule I added in the beginning.
By going over the grammar one more time, I figured that my theory held. `star_expressions` would match `a=disjunction 'if' b=disjunction { _PyAST_IfExp(b, a, NULL, EXTRA) }`.
The only way to fix this was by getting rid of the `star_expressions`. So I changed the rule to:
```
 return_stmt[stmt_ty]:
\- | 'return' a=star_expressions 'if' b=disjunction { _PyAST_ReturnIfExpr(a, b, EXTRA) }
\+ | 'return' a=disjunction guard=guard !'else' { _PyAST_ReturnIfExpr(a, guard, EXTRA) }
  | 'return' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
```
You might be wondering, what are `guard,` `!else`, and `star_expressions`?
This `guard` is a rule that is part of the pattern matching rules. The new pattern matching feature added in Python 3.10 allows things like this:
```
match point:
   case Point(x, y) if x == y:
        print(f"Y=X at {x}")
        case Point(x, y):
        print(f"Not on the diagonal")
```
And the rule goes by this:
```
`guard[expr_ty]: 'if' guard=named_expression { guard }`
```
With that, I added one more check. To avoid it failing with `SyntaxError`, I needed to make sure the rule matched only code like this: `return value if cond`. Thus, to prevent code such as `return an if cond else b` being matched prematurely, I added a `!' else` to the rule.
Last but not least, the `star_expressions` allow me to return destructured iterables. For example:
```
&gt;&gt;&gt; def f():
  ...: a = [1, 2]
  ...: return 0, *a
  ...:&amp;
&gt;&gt;&gt; f()
(0, 1, 2)
```
In this case, `0, * a` is a tuple, which falls under the category of `star_expressions`. The regular if-expression doesn't allow using `star_expressions` with it, AFAIK, so changing the new `return` rule won't be an issue.
### Does it work yet?
After fixing the return rule, I regenerated the grammar one more time and compiled it:
```
&gt;&gt;&gt; def f(test):
... return 42 if test
... print('missed return')
... return 21
...
&gt;&gt;&gt; f(False)
missed return
21
&gt;&gt;&gt; f(True)
42
```
It works!
Looking at the bytecode:
```
&gt;&gt;&gt; import dis
&gt;&gt;&gt; dis.dis(f)
  2 0 LOAD_FAST 0 (test)
            2 POP_JUMP_IF_FALSE 4 (to 8)
            4 LOAD_CONST 1 (42)
            6 RETURN_VALUE
  3 &gt;&gt; 8 LOAD_GLOBAL 0 (print)
            10 LOAD_CONST 2 ('missed return')
            12 CALL_FUNCTION 1
            14 POP_TOP
  4 16 LOAD_CONST 3 (21)
            18 RETURN_VALUE
&gt;&gt;&gt;
```
That's precisely what I wanted. Is the AST is the same as the one with regular `if`?
```
&gt;&gt;&gt; import ast
&gt;&gt;&gt; print(ast.dump(ast.parse(fc), indent=4))
Module(
   body=[
        FunctionDef(
            name='f',
            args=arguments(
                posonlyargs=[],
                args=[
                  arg(arg='test')],
                kwonlyargs=[],
                kw_defaults=[],
                defaults=[]),
            body=[
                If(
                    test=Name(id='test', ctx=Load()),
                    body=[
                      Return(
                      value=Constant(value=42))],
                      orelse=[]),
                Expr(
                  value=Call(
                          func=Name(id='print', ctx=Load()),
                          args=[
                            Constant(value='missed return')],
                          keywords=[])),
                Return(
                  value=Constant(value=21))],
            decorator_list=[])],
   type_ignores=[])
&gt;&gt;&gt;
```
Indeed it is!
```
If(
   test=Name(id='test', ctx=Load()),
   body=[
        Return(
            value=Constant(value=42))],
   orelse=[]),
```
This node is the same as the one that would be generated by:
```
`if test: return 42`
```
### If it's not tested, it's broken?
To conclude this journey, I thought it'd be a good idea to add some unit tests as well. Before writing anything new, I wanted to get an idea of what I had broken.
With the code tested manually, I ran all tests using the `test` module `python -m test -j8`. The `-j8` means it uses eight processes to run the tests in parallel:
```
`$ ./python -m test -j8`
```
To my surprise, only one test failed!
```
== Tests result: FAILURE ==
406 tests OK.
1 test failed:
   test_grammar
```
Because I ran all tests, it's hard to navigate the output, so I can run only this one again in isolation:
```
======================================================================
FAIL: test_listcomps (test.test_grammar.GrammarTests)
\----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/miguel/projects/cpython/Lib/test/test_grammar.py", line 1732, in test_listcomps
   check_syntax_error(self, "[x if y]")
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/miguel/projects/cpython/Lib/test/support/__init__.py", line 497, in check_syntax_error
   with testcase.assertRaisesRegex(SyntaxError, errtext) as cm:
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: SyntaxError not raised
\----------------------------------------------------------------------
Ran 76 tests in 0.038s
FAILED (failures=1)
test test_grammar failed
test_grammar failed (1 failure)
== Tests result: FAILURE ==
1 test failed:
   test_grammar
1 re-run test:
   test_grammar
Total duration: 82 ms
Tests result: FAILURE
```
And there it is! It expected a syntax error when running a `[x if y]` expression. I can safely remove it and re-run the tests again:
```
== Tests result: SUCCESS ==
1 test OK.
Total duration: 112 ms
Tests result: SUCCESS
```
Now that everything is OK, it's time to add a few more tests. It's important to test not only the new "else-less if" but also the new `return` statement.
By navigating through the `test_grammar.py` file, I can find a test for pretty much every grammar rule. The first one I look for is `test_if_else_expr`. This test doesn't fail, so it only tests for the happy case. To make it more robust, I needed to add two new tests to check `if True` and `if False` cases:
```
     self.assertEqual((6 &lt; 4 if 0), None)
        self.assertEqual((6 &lt; 4 if 1), False)
```
I ran everything again, and all tests passed this time.
Note: `bool` in Python is a [subclass of integer][14], so you can use `1` to denote `True` and `0` for `False`.
```
Ran 76 tests in 0.087s
OK
== Tests result: SUCCESS ==
1 test OK.
Total duration: 174 ms
Tests result: SUCCESS
```
Lastly, I needed the tests for the `return` rule. They're defined in the `test_return` test. Just like the `if` expression one, this test passed with no modification.
To test this new use case, I created a function that receives a `bool` argument and returns if the argument is true. When it's false, it skips the return, just like the manual tests I had been doing up to this point:
```
        def g4(test):
             a = 1
             return a if test
             a += 1
             return a
        self.assertEqual(g4(False), 2)
        self.assertEqual(g4(True), 1)
```
I saved the file and re-ran `test_grammar` one more time:
```
\----------------------------------------------------------------------
Ran 76 tests in 0.087s
OK
== Tests result: SUCCESS ==
1 test OK.
Total duration: 174 ms
Tests result: SUCCESS
```
Looks good! The `test_grammar` test passed. Just in case, I re-ran the full test suite:
```
`$ ./python -m test -j8`
```
After a while, all tests passed, and I'm very happy with the result.
### Limitations
If you know Ruby well, by this point, you've probably noticed that what I did here was not 100% the same as a conditional modifier. For example, in Ruby, you can run actual expressions in these modifiers:
```
irb(main):002:0&gt; a = 42
irb(main):003:0&gt; a += 1 if false
=&gt; nil
irb(main):004:0&gt; a
=&gt; 42
irb(main):005:0&gt; a += 1 if true
=&gt; 43
```
I cannot do the same with my implementation:
```
&gt;&gt;&gt; a = 42
&gt;&gt;&gt; a += 1 if False
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
&gt;&gt;&gt; a += 1 if True
&gt;&gt;&gt; a
43
```
What this reveals is that the `return` rule I created is just a workaround. If I want to make it as close as possible to Ruby's conditional modifier, I'll need to make it work with other statements as well, not just `return`.
Nevertheless, this is fine. My goal with this experiment was just to learn more about Python internals and see how I would navigate a little-known code base written in C and make the appropriate changes to it. And I have to admit that I'm pretty happy with the results!
### Conclusion
Adding a new syntax inspired by Ruby is a really nice exercise to learn more about the internals of Python. Of course, if I had to convert this as a PR, the core developers would probably find a few shortcomings, as I have already described in the previous section. However, since I did this just for fun, I'm very happy with the results.
The source code with all my changes is on my CPython fork under the [branch ruby-if-new][15].
* * *
_This article was originally published on the [author's personal blog][16] and has been adapted with permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/python-else-less
作者:[Miguel Brito][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/miguendes
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python_programming_question.png?itok=cOeJW-8r (Python programming language logo with question marks)
[2]: https://www.python.org/dev/peps/pep-0020/#id2
[3]: https://github.com/python/cpython/pull/27506
[4]: https://opensource.com/sites/default/files/ihe46r0jv.gif
[5]: https://tonybaloney.github.io/
[6]: https://realpython.com/products/cpython-internals-book/
[7]: https://github.com/python/cpython/blob/3.10/Makefile.pre.in#L850_L856
[8]: https://craftinginterpreters.com/
[9]: https://journal.stuffwithstuff.com/
[10]: https://docs.python.org/3/library/ast.html
[11]: https://en.wikipedia.org/wiki/Bytecode
[12]: https://docs.python.org/3/library/dis.html
[13]: http://man7.org/linux/man-pages/man2/mmap.2.html
[14]: https://docs.python.org/3/c-api/bool.html
[15]: https://github.com/miguendes/cpython/tree/ruby-if-new
[16]: https://miguendes.me/what-if-python-had-this-ruby-feature

View File

@ -0,0 +1,124 @@
[#]: subject: "Watch commands and tasks with the Linux watch command"
[#]: via: "https://opensource.com/article/21/9/linux-watch-command"
[#]: author: "Moshe Zadka https://opensource.com/users/moshez"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Watch commands and tasks with the Linux watch command
======
See how the watch command can let you know when a task has been
completed or a command has been executed.
![Clock, pen, and notepad on a desk][1]
There are many times when you need to wait for something to finish, such as:
* A file download.
* Creating or extracting a [tar][2] file.
* An [Ansible][3] job.
Some of these processes have some sort of progress indication, but sometimes the process is run through a layer of abstraction, and the only way to measure the progress is through its side effects. Some of these might be:
* A file being downloaded keeps growing.
* A directory extracted from a tarball fills up with files.
* The Ansible job builds a [container][4].
You can query all of these things with commands like these:
```
$ ls -l downloaded-file
$ find . | wc -l
$ podman ps
$ docker ps
```
But running these commands over and over, even if it is with the convenience of [Bash history][5] and the **Up Arrow**, is tedious.
Another approach is to write a little Bash script to automate these commands for you:
```
while :
do
  docker ps
  sleep 2
done
```
But such scripts can also become tedious to write. You could write a little generic script and package it, so it's always available to you. Luckily, other open source developers have already been there and done that.
The result is the command `watch`.
### Installing watch
The `watch` command is part of the [`procps-ng` package][6], so if you're on Linux, you already have it installed.
On macOS, install `watch` using [MacPorts][7] or [Homebrew][8]. On Windows, use [Chocolatey][9].
### Using watch
The `watch` command periodically runs a command and shows its output. It has some text-terminal niceties, so only the latest output is on the screen.
The simplest usage is: `watch <command>`.
For example, prefixing the `docker ps` command with `watch` works like this:
```
`$ watch docker ps`
```
The `watch` command, and a few creative Unix command-line tricks, can generate ad-hoc dashboards. For example, to count audit events:
```
`$ watch 'grep audit: /var/log/kern.log |wc -l'`
```
In the last example, it is probably useful if there's a visual indication that the number of audit events changed. If change is expected, but you want something to look "different," `watch --differences` works well. It highlights any differences from the last run. This works especially well if you are grepping in multiple files, so you can easily see which one changed.
If changes are not expected, you can ask for them to be highlighted "permanently" to know which ones to investigate by using `watch --differences=permanent`. This is often more useful.
### Controlling frequency
Finally, sometimes the command might be resource-intensive and should not be run too frequently. The `-n` parameter controls the frequency. Watch uses two seconds by default, but `watch -n 10` might be appropriate for something more resource-intensive, like grepping for a pattern in any file in a subdirectory:
```
`$ watch -n 10 'find . -type f | xargs grep suspicious-pattern'`
```
### Watch a command with watch
The `watch` command is useful for many ad-hoc system administration tasks where you need to wait for some time-consuming step, without a progress bar, before moving on to the next one. Though this is not a great situation to be in, `watch` can make it slightly better—and give you time to start working on those notes for the retrospective! Download the **[cheat sheet][10] **to keep helpful syntax and options close at hand.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/linux-watch-command
作者:[Moshe Zadka][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/moshez
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/desk_clock_job_work.jpg?itok=Nj4fuhl6 (Clock, pen, and notepad on a desk)
[2]: https://opensource.com/article/17/7/how-unzip-targz-file
[3]: https://opensource.com/resources/what-ansible
[4]: https://opensource.com/resources/what-docker
[5]: https://opensource.com/article/20/6/bash-history-control
[6]: https://opensource.com/article/21/8/linux-procps-ng
[7]: https://opensource.com/article/20/11/macports
[8]: https://opensource.com/article/20/6/homebrew-mac
[9]: https://opensource.com/article/20/3/chocolatey
[10]: https://opensource.com/downloads/watch-cheat-sheet

View File

@ -0,0 +1,190 @@
[#]: subject: "How to Install Kali Linux in VMware"
[#]: via: "https://itsfoss.com/install-kali-linux-vmware/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How to Install Kali Linux in VMware
======
Kali Linux is the de facto standard of [Linux distributions used for learning and practicin][1][g][1] [hacking and penetration testing][1].
And, if youve been tinkering around with Linux distros long enough, you might have tried it out just out of curiosity.
However, no matter what you use it for, it is not a replacement for a regular full-fledged desktop Linux operating system. Hence, it is recommended (at least for beginners) to install Kali Linux using a virtual machine program like VMware.
With a virtual machine, you can use Kali Linux as a regular application in your Windows or Linux system. Its almost the same as running VLC or Skype in your system.
There are a few free virtualization tools available for you. You can [install Kali Linux on Oracle VirtualBox][2] or use VMWare Workstation.
This tutorial focuses on VMWare.
### Installing Kali Linux on VMware on Windows and Linux
Non-FOSS alert!
VM Ware is not open source software.
For this tutorial, I presume that you are using Windows, considering most VMware users prefer using Windows 10/11.
However, the _**tutorial is also valid for Linux except the VMWare installation on Windows part**_. You can [easily install VMWare on Ubuntu][3] and other Linux distributions.
#### Step 1: Install VMWare Workstation Player (on Windows)
If you already have VMware installed on your system, you can skip the steps to install Kali Linux.
Head to [VMWares official workstation player webpage][4] and then click on the “**Download Free**” button.
![][5]
Next, you get to choose the version (if you want something specific or encountering bugs in the latest version) and then click on “**Go to Downloads.**“
![][6]
And then you get the download buttons for both Windows and Linux versions. You will have to click on the button for Windows 64-bit because that is what we need here.
![][7]
There is no support for 32-bit systems, in case you were wondering.
Finally, when you get the .exe file downloaded, launch it to start the installation process. You need to hit “Next” to get started installing VMware.
![][8]
Next, you will have to agree to the policies and conditions to continue.
![][9]
Now, you get to choose the path of your installation. Ideally, keep it at the default settings. But, if you need better keyboard response / in-screen keyboard performance in the virtual machine, you may want to enable the “**Enhanced Keyboard Driver**.”
![][10]
Proceeding to the next step, you can choose to disable checking for updates every time you start the program (can be annoying) and disable sending data to VMware as part of its user experience improvement program.
![][11]
If you want quick access using desktop and start menu shortcuts, you can check those settings or toggle them off, which I prefer.
![][12]
Now, you have to continue to start the installation.
![][13]
This may take a while, and when completed, you get greeted with another window that lets you finish the process and gives you the option to enter a license key. If you want to get the commercial license for your use-case, you need the VMware Workstation Pro edition, or else, the player is free for personal use.
![][14]
Attention!
Please make sure that virtualization is enabled in your system. Recent Windows versions require that you enable the virtualization explicitly to use virtual machines.
#### Step 2: Install Kali Linux on VMware
To get started, you need to download the image file of Kali Linux. And, when it comes to Kali Linux, they offer a separate ISO file if you plan to use it on a virtual machine.
![][15]
Head to its [official download page][16] and download the prebuilt VMware image available.
![][17]
You can download the **.7z** file directly or utilize Torrent (which is generally faster). In either case, you can also check the file integrity with the SHA256 value provided.
Once downloaded, you need to extract the file to any path of your choice.
![][18]
Open VMware Workstation Player and then click on “**Open a Virtual Machine**.” Now, look for the folder you extracted. And navigate through it till you find a file with the “**.vmx**” extension.
For instance: **Kali-Linux-2021.3-vmware-amd64.vmx**
![][19]
Select the .vmx file to open the virtual machine. And, it should appear right in your VMware player.
You can choose to launch the virtual machine with the default settings. Or, if you want to tweak the hardware allocated to the virtual machine, feel free to change the settings before you launch it.
![][20]
Depending on your computer hardware, you should allocate more memory and at least half of your processor cores to get a smooth performance.
In this case, I have 16 Gigs of RAM and a quad-core processor. Hence, it is safe to allocate nearly 7 GB of RAM and two cores for this virtual machine.
![][21]
While you can assign more resources, but it might affect the performance of your host operating system when working on a task. So, it is recommended to keep a balance between the two.
Now, save the settings and hit “**Play virtual machine**” to start Kali Linux on VMware.
When it starts loading up, you may be prompted with some tips to improve performance by tweaking some virtual machine settings.
You do not have to do that, but if you notice performance issues, you can disable side-channel mitigations (needed for enhanced security) to uplift the performance of the VM.
Also, you may be prompted to download and [install VMware tools for Linux][22]; you need to do this to get a good VM experience.
Once you do that, you will be greeted with Kali Linuxs login screen.
![][23]
Considering that you launched a prebuilt VMware folder, you need to enter the default login and password to proceed.
**Username**: kali
**Password:** kali
![][24]
Thats it! Youre done installing Kali Linux on VMware. Now, all you have to do is start exploring!
### Where to go from here?
Here are a few tips you can utilize:
* If clipboard sharing and file sharing is not working, [install VMWare tools][22] on the guest system (Kali Linux).
* If you are new to it, check out this [list of Kali Linux tools][25].
Feel free to share your thoughts if you find this tutorial helpful. Do you prefer to install Kali Linux without using a VMware image ready to go? Let me know in the comments below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-kali-linux-vmware/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/linux-hacking-penetration-testing/
[2]: https://itsfoss.com/install-kali-linux-virtualbox/
[3]: https://itsfoss.com/install-vmware-player-ubuntu-1310/
[4]: https://www.vmware.com/products/workstation-player.html
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-player-download.png?resize=732%2C486&ssl=1
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-player-download-1.png?resize=800%2C292&ssl=1
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-player-download-final.png?resize=800%2C212&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-setup-1.png?resize=692%2C465&ssl=1
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-setup-license.png?resize=629%2C443&ssl=1
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-setup-2.png?resize=638%2C440&ssl=1
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-workstation-tracking.png?resize=618%2C473&ssl=1
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-workstation-shortcuts.png?resize=595%2C445&ssl=1
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-player-install.png?resize=620%2C474&ssl=1
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-player-installed.png?resize=589%2C441&ssl=1
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-image-kali.png?resize=800%2C488&ssl=1
[16]: https://www.kali.org/get-kali/
[17]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-kali-linux-image-download.png?resize=800%2C764&ssl=1
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/extract-vmware-image.png?resize=617%2C359&ssl=1
[19]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-kali-linux-image-folder.png?resize=800%2C498&ssl=1
[20]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/virtual-machine-settings-kali.png?resize=800%2C652&ssl=1
[21]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/kali-vm-settings.png?resize=800%2C329&ssl=1
[22]: https://itsfoss.com/install-vmware-tools-linux/
[23]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/kali-linux-vm-login.png?resize=800%2C540&ssl=1
[24]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/vmware-kali-linux.png?resize=800%2C537&ssl=1
[25]: https://itsfoss.com/best-kali-linux-tools/

View File

@ -0,0 +1,82 @@
[#]: subject: "Open source game achievements"
[#]: via: "https://fedoramagazine.org/open-source-game-achievements/"
[#]: author: "Dennis Payne https://fedoramagazine.org/author/dulsi/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Open source game achievements
======
![][1]
Photo by [Michał Parzuchowski][2] on [Unsplash][3]
Learn how Gamerzilla brings an achievement system to open source games and enables all developers to implement achievements separate from the game platform.
Some open source games rival the quality of commercial games. While it is hard to match the quality of triple-a games, open source games compete effectively against the indie games. But, gamer expectations change over time. Early games included a high score. Achievements expanded over time to promote replay. For example, you may have completed a level but you didnt find all the secrets or collect all the coins. The Xbox 360 introduced the first multi-game online achievement system. Since that introduction, many game platforms added an achievement system.
Open source games are largely left out of the achievement systems. You can publish an open source game on Steam, but it costs money and they focus on working with companies not the free software community. Additionally, this locks players into a non-free platform.
Commercial game developers are not well served either, since some players enjoy achievements and refuse to purchase from other stores due to the inability to share their accomplishments. This lock-in gives the power to the platform holder. Each platform has a different system forcing the developer to implement support and testing multiple times. Smaller platform are likely to be skipped entirely. Furthermore, the platform holder has access to the achievement data on all companies using their system which could be used for competitive advantage.
### Architecture of Gamerzilla
[Gamerzilla][4] is an open source game achievement system which attempts to correct this situation. The design considered both open source and commercial games. You can run your own Gamerzilla server, use one provided by a game store, or even distributions, or other groups could run them. Where you buy the game doesnt matter. The achievement data uploads to your Gamerzilla server.
Game achievements require two things, a game, and a Gamerzilla server. As game collections grow, however, that setup has a disadvantage. Each game needs to have credentials to upload to the Gamerzilla server. Many gamers turn to game launchers due to their large number of games and ability to synchronize with one or more stores. By adding Gamerzilla support to the launcher, the individual games no longer need to know your credentials. Session results will relay from the game launcher to the Gamerzilla server.
At one time, freegamedev.net provided the Hubzilla social networking system. We created an addon allowing us to jump start Gamerzilla development. Unfortunately server upgrades broke the service so freegamedev.net stopped offering it.
For Gamerzilla servers, two implementations exist. Maintaining Hubzilla is a complex task, so we developed a standalone Gamerzilla service using *.*Net and React. The API used by games remains the same so it doesnt matter which implementation you connect to.
Game launchers development and support often lags. To facilitate adding support, we created libgamerzilla. The library handles all the interaction between the game launcher, games, and the Gamerzilla server. Right now only _GameHub_ has an implementation with Gamerzilla support and merging into the project is pending. On Fedora Linux, libgamerzilla-server package serves as a temporary solution. It does not launch games but listens for achievements and relays them to your server.
Game support continues growing. As with game launchers, developers use libgamerzilla to handle the Gamerzilla integration. The library, written in C, is in use in a variety of languages like Python and nim. Games which already have an achievement system typically take only a few days to add support. For other games ,collecting all the information to award the achievements occupies the bulk of the implementation time.
### Setting up a server
The easiest server to setup is the Hubzilla addon. That, however, requires a working Hubzilla site which is not the simplest thing to setup. The new .Net and React server can be setup relatively easily on Fedora Linux, although there are a lot of steps. The [readme][5] details all the steps. The long set of steps is, in part, due to the lack of a built release. This means you need to build the .Net and the React code. Once built, React code serves up directly in Apache. A new service runs the .Net piece. Apache proxies all requests to the Gamerzilla API for the new service.
With the setup steps done, Gamerzilla runs but there are no users. There needs to be an easy way to create an administrator and register new users. Unfortunately this piece does not exist yet. At this time, users must be entered directly using the sqlite3 command line tool. The instructions are in the [readme][5]. Users can be publicly visible or not. The approval flag allows new users to not use the system immediately but web registration still needs to be implemented The user piece is designed with replacement in mind. It would not be hard to replace backend/Service/UserService.cs to integrate with an existing site. Gaming web sites could use this to offer Gamerzilla achievements to their users.
Currently the backend uses a sqlite database. No performance testing has been done. We expect that larger installations may need to modify the system to use a more robust database system.
### Testing the system
There is no game launcher easily available at the moment. If you install libgamerzilla-server, you will have the command _gamerzillaserver_ available from the command line. The first time you run it, you enter your url and login information. Subsequent executions will simply read the information from the configuration file. There is currently no way to correct a mistake except deleting the file at _.local/share/ga_merzillaserver/server.cfg and running _gamerzillaserver_ again.
Most games have no built releases with Gamerzilla support. [Pinball Disc Room on itch.io][6] does have support built in the Linux version. The web version has no achievements There are only two achievements in the game, one for surviving for ten seconds and the other for unlocking and using the tunnel. With a little practice you can get an achievement. You need to check your Gamerzila server as the game provides no visual notification of the achievement.
Currently no game packaged in Fedora Linux supports Gamerzilla. SuperTuxKart merged support but is still awaiting a new release. Seahorse adventures and Shippy 1984 added achievements but new releases are not packaged yet. Some games with support, we maintain independently as the developers ignore pull requests or other attempt to contact them.
### Future work
Gamerzilla needs more games. A variety of games currently support the system. An addition occurs nearly every month. If you have a game you like, ask the developer to support Gamerzilla. If you are making a game and need help adding support, please let us now.
Server development proceeds at a slow pace and we hope to have a functional registration system soon. After that we may setup a permanent hosting site. Right now you can see our [test server][7]. Some people expressed concern with the .Net backend. The API is not very complex and could be rewritten in Python fairly easily.
The largest unknown remains game launchers. GameHub wants a generic achievement interface. We could try to work with them to get that implemented. Adding support to the itch.io app could increase interest in the system. Another possibility is to do away with the game launcher entirely. Perhaps adding something like the gamerzillaserver to Gnome might be possible. You would then configure your url and login information on a settings page. Any game launched could then record achievements.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/open-source-game-achievements/
作者:[Dennis Payne][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/dulsi/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/09/game_acheivements-816x345.jpg
[2]: https://unsplash.com/@mparzuchowski?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/jenga?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: http://identicalsoftware.com/gamerzilla/
[5]: https://github.com/dulsi/gamerzilla.net#readme
[6]: https://dulsi.itch.io/pinball-disc-room
[7]: http://108.49.106.217/

View File

@ -0,0 +1,114 @@
[#]: subject: "Organize your Magic: The Gathering decks with Magic Assistant"
[#]: via: "https://opensource.com/article/21/9/magic-the-gathering-assistant"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Organize your Magic: The Gathering decks with Magic Assistant
======
The open source application Magic Assistant makes managing your Magic
collection easy.
![Holding a Magic the Gathering deckmaster card][1]
The world's first trading card game was _Magic: The Gathering,_ first published in 1993.
It remains popular today because of its great flexibility. With more than 25,000 unique cards published over nearly three decades, there are enough cards for players to build hundreds of different decks for surprisingly unique gameplay experiences.
Along with this flexibility, however, there comes a cost: many _Magic: The Gathering_ players collect lots of cards so they can construct lots of different decks, which in turn lets them focus on different win conditions and try out different strategies.
It can be quite a job to keep track of 1,000 cards when you only need 60 to 100 for a deck, but the open source application Magic Assistant makes managing your _Magic_ collection easy.
### Installing Magic Assistant
[Magic Assistant][2] is a Java application, so it's cross-platform. Regardless of whether you're on the open source operating system [Linux,][3] macOS, or Windows, you can download Magic Assistant, double-click on its launcher icon, and use it to manage your cards.
After the application first launches, there are sure to be updates to the card database available. Multiple new _Magic_ sets are released each year, so accept the offer to update and go grab a cup of coffee while new cards are added.
### Importing cards
To catalog your cards with Magic Assistant, either you can rummage through the card database manually to add cards to your local collection, or you can import an existing list. The simplest format for a list of _Magic_ cards is a text file containing the number of copies you own and the name of a card on a line by itself:
```
2x Mimic 1x Mordenkainen's Polymorph 2x Ray of Frost 4x Sol Ring
```
However, the application supports many formats, including a CSV from _Magic: The Gathering Online,_ TCGPlayer table, MTG Studio, Apprentice, DeckBox, and more.
To import your cards, select the Import option from the File menu.
![Sample entry field for importing cards into a deck or collection][4]
Importing cards (Seth Kenlon, [CC BY-SA 4.0][5])
Importing cards adds them to the default collection database (called **main**). This database represents the entirety of your collection. You can then use cards from your collection to build decks and cubes. There's no limit on how many collections you can have, so you can organize your cards in whatever way you prefer.
### Browsing your collection
A collection is organized by its metadata by default. That means you can browse your collection by any number of attributes, including mana cost, card type, color, keyword abilities, and format legality. All of these options are available as tabs at the bottom of the collection interface.
![A view of sorting tabs with several card categories][6]
Interface tabs (Seth Kenlon, [CC BY-SA 4.0][5])
### Building a deck or cube
One way to get better at _Magic: The Gathering_—and get a better feel for how you like to experience the game—is to build decks. On the one hand, it's great to hold physical cards, but, on the other hand, it can be a lot of work to sort through hundreds of cards kept in several different boxes or binders. With Magic Assistant, it's easy to sort through your cards based on whatever attribute you need, so building decks with it is a pleasure.
To build a new deck (Magic Assistant has no concept of a cube, but functionally a cube is arguably no different than a deck), right-click on the Deck category in the Card Navigator panel, then select New to create a new deck.
There are two kinds of decks you can build. You can build a virtual deck, which is purely theorycrafting, with no implication that the deck exists physically. When you create a virtual deck, you can take a card you own only one actual copy of and use it in several decks. You could not build the decks in real life, obviously, because you would be overusing some number of cards, but as a deck idea or recipe, it works well.
Alternately, you can build a "real" deck, which affects your collection the same way a physical deck does. If you put three copies of Sol Ring into a deck, then your collection shows that you have three fewer copies of Sol Ring available.
Choose what kind of deck you're building, and give your deck a name for your own reference in the New window.
![Sample entry field for creating a new deck, with name and parent container][7]
Deckbuilding tool (Seth Kenlon, [CC BY-SA 4.0][5])
To add cards to your a deck, locate the card in your collection, right-click on it, and select Move to or Copy to, followed by the deck you want it to appear in. A virtual deck never lets you move cards to it. Instead, it prompts you to copy the card, because a virtual card never removes a card from your collection.
![Using Copy to to add a card to a specific deck][8]
Adding a card to a deck (Seth Kenlon, [CC BY-SA 4.0][5])
When you have multiple copies of a card and copy that card into a deck, Magic Assistant adds all copies. To decrease or increase the number of copies of a card in a deck, right-click on the card in your deck and choose Decrease count or Increase count.
### Deck reports
After you've built a deck, you can view reports detailing the statistics for the cards you've assembled. You can get charts to view card types, creature types, mana curve, color distribution, and more.
![A pie chart showing the different types of cards, and a chart with greater detail][9]
Charts and graphs (Seth Kenlon, [CC BY-SA 4.0][5])
### Open source tools for everything
There's an open source application for nearly everything, so it's no surprise that there's a robust card collection manager like Magic Assistant to help _Magic: The Gathering_ players. If you play the original trading card game, try this one out. It can help you keep track of which cards you have available for building decks. And just as important, it may encourage you to build more decks more often, because it's so easy to do when all the cards are at your fingertips.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/magic-the-gathering-assistant
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wayne-low-unsplash.jpg?itok=eqvfc71L (Holding a Magic the Gathering deckmaster card)
[2]: https://sourceforge.net/projects/mtgbrowser/
[3]: https://opensource.com/resources/linux
[4]: https://opensource.com/sites/default/files/mtgassistant-import.jpeg (Importing cards into a deck or collection)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://opensource.com/sites/default/files/mtgassistant-tab.jpeg (Interface tabs)
[7]: https://opensource.com/sites/default/files/mtgassistant-deck_0.jpeg (Deckbuilding tool)
[8]: https://opensource.com/sites/default/files/mtgassistant-add_0.jpeg (Using Copy to to add a card to a specific deck)
[9]: https://opensource.com/sites/default/files/mtgassistant-chart.jpeg (Charts and graphs)

View File

@ -0,0 +1,129 @@
[#]: subject: "Start using YAML now"
[#]: via: "https://opensource.com/article/21/9/intro-yaml"
[#]: author: "Ayush Sharma https://opensource.com/users/ayushsharma"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Start using YAML now
======
What is YAML, and why is it about time we started using it?
![woman on laptop sitting at the window][1]
YAML (YAML Ain't Markup Language) is a human-readable data serialization language. Its syntax is simple and human-readable. It does not contain quotation marks, opening and closing tags, or braces. It does not contain anything which might make it harder for humans to parse nesting rules. You can scan your YAML document and immediately know what's going on.
### YAML features
YAML has some super features which make it superior to other serialization formats:
* Easy to skim.
* Easy to use.
* Portable between programming languages.
* Native data structures of Agile languages.
* Consistent model to support generic tools.
* Supports one-pass processing.
* Expressive and extensible.
I will show you YAML's power further with some examples.
Can you figure out what's going on below?
```
\-------
# My grocery list
groceries:
    - Milk
     - Eggs
     - Bread
     - Butter
...
```
The above example contains a simple list of groceries to buy, and it's a fully-formed YAML document. In YAML, strings aren't quoted, and lists need simple hyphens and spaces. A YAML document starts with **\---** and ends with **...**, but they are optional. Comments in YAML begin with a **#**.
Indentation is key in YAML. Indentation must contain spaces, not tabs. And while the number of spaces required is flexible, it's a good idea to keep them consistent.
### Basic Elements
#### Collections
YAML has two types of collections: _Lists_ (for sequences) and _dictionaries_ (for mappings). Lists are key-value pairs where every value is on a new line, beginning with a hyphen and space. Dictionaries are key-value pairs where every value is a mapping containing a key, a colon and space, and a value.
For example:
```
# My List
groceries:
    - Milk
     - Eggs
     - Bread
     - Butter
# My dictionary
contact:
 name: Ayush Sharma
 email: [myemail@example.com][2]
```
Lists and dictionaries are often combined to provide more complex data structures. Lists can contain dictionaries, and dictionaries can contain lists.
#### Strings
Strings in YAML don't need quotation marks. Multi-line strings are defined using **|** or **&gt;**. The former preserves newlines, but the latter does not.
For example:
```
my_string: |
    This is my string.
     It can contain many lines.
     Newlines are preserved.
my_string_2: &gt;
    This is my string.
     This can also contain many lines.
     Newlines aren't preserved and all lines are folded.
```
#### Anchors
YAML can have repeatable blocks of data using node anchors. The **&amp;** character defines a block of data that is later referenced using *****. For example:
```
billing_address: &amp;add1
 house: B1
 street: My Street
shipping_address: *add1
```
At this point, you know enough YAML to get started. You can play around with the online YAML parser to test yourself. If you work with YAML daily, then [this handy cheatsheet][3] will be helpful.
* * *
_This article was originally published on the [author's personal blog][4] and has been adapted with permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/intro-yaml
作者:[Ayush Sharma][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/ayushsharma
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
[2]: mailto:myemail@example.com
[3]: https://yaml.org/refcard.html
[4]: https://notes.ayushsharma.in/2021/08/introduction-to-yaml

View File

@ -0,0 +1,235 @@
[#]: subject: "How to Install Ubuntu Desktop on Raspberry Pi 4"
[#]: via: "https://itsfoss.com/install-ubuntu-desktop-raspberry-pi/"
[#]: author: "Avimanyu Bandyopadhyay https://itsfoss.com/author/avimanyu/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How to Install Ubuntu Desktop on Raspberry Pi 4
======
_**Brief: This thorough tutorial shows you how to install Ubuntu Desktop on Raspberry Pi 4 device.**_
The revolutionary Raspberry Pi is the most popular single board computer. It has its very own Debian based operating system called [Raspbian][1].
There are several other [operating systems available for Raspberry Pi][2] but almost all of them are lightweight. This was appropriate for the small factor and low end hardware of the Pi devices.
This changes with the introduction of Raspberry Pi 4B that flaunts 8 GB RAM and supports 4K display. The aim is to use Raspberry Pi as a regular desktop and it succeeds in doing so to a larger extent.
Before the 4B model, you could [install the Ubuntu server on Raspberry Pi][3] but the desktop version was not available. However, **Ubuntu now provides official desktop image for Pi 4 models**.
In this tutorial, I am going to show the steps for installing Ubuntu desktop on Raspberry Pi 4.
First, a quick look at the prerequisites.
### Prerequisites for running Ubuntu on Raspberry Pi 4
![][4]
Heres what you need:
1. A Linux or Windows system with active internet connection.
2. [Raspberry Pi Imager][5] : The official open source tool from Raspberry that gets you the distro image on your SD card.
3. Micro SD Card: Consider using at least a 16 GB storage for your card, albeit a 32 GB version is recommended.
4. A USB based Micro SD Card Reader (if your computer does not have a card reader).
5. Essential Raspberry Pi 4 accessories such as an HDMI compatible display, [Micro HDMI to Standard HDMI (A/M) Cable][6], [Power Supply (Official Adapter Recommended)][7], USB Wired/Wireless Keyboard and Mouse/Touchpad.
It is good practice to [read in detail about the Pi requirements][8] beforehand.
Now, without further delay, let me quickly walk you through the image preparation for the SD Card.
### Preparing the Ubuntu Desktop image for Raspberry Pi
Raspberry Pi provides a GUI application for writing the ISO image to the SD Card. **This tool can also download compatible operating systems like Ubuntu, Raspbian etc automatically**.
![Official tool to download and put operating system on SD card][9]
You can download this tool for Ubuntu, Windows and macOS from the official website:
[Download Raspberry Pi Imager][10]
On Ubuntu and other Linux distributions, you can also install it with Snap:
```
sudo snap install rpi-imager
```
Once installed, run the imager tool. When you see the screen below, select “CHOOSE OS”:
![Pi imager: choose the preferred operating system][11]
Under “Operating System”, select “Other general purpose OS”:
![Pi imager: other general purpose operating systems][12]
Now, select “Ubuntu”:
![Pi imager distro: Ubuntu][13]
Next, select “Ubuntu Desktop 21.04 (RPI 4/400)” as shown below:
![Pi imager distro version: Ubuntu 21.04][14]
Note
If you do not have a good, consistent internet collection, you can [download the Ubuntu for Raspberry Pi image separately from Ubuntus website][15]. In the Imager tool, while choosing the OS, go to the bottom and select “Use custom” option. You can also use Etcher for writing the image to the SD card.
Insert the micro SD card inside your Card reader and wait for it to mount. Select “CHOOSE STORAGE” under “Storage”:
![Pi imager choose storage \(SD card\)][16]
You should be seeing only your micro SD card storage and youd recognize it instantly based on the size. Here, Ive used a 32 GB card:
![Pi imager choose SD card][17]
Now click on “WRITE”:
![Pi imager image write][18]
Ill assume you have the contents of the SD card backed up. If its a new card, you can just proceed:
![Pi imager image write confirmation query][19]
Since this is a [sudo][20] privilege, you must enter your password. If you run `sudo rpi-imager` from a terminal, this would not appear:
![Pi imager image write authentication asking for password][21]
If your SD card is a bit old, it would take some time. But if it is a recent one with high speeds, it wouldnt take long:
![Pi imager writing image][22]
I also wouldnt recommend skipping verification. Make sure the image write went successful:
![Pi imager verifying changes][23]
Once it is over, you will get the following confirmation:
![Pi imager write successful][24]
Now, safely-remove the SD card from your system.
### Using the micro SD card with Ubuntu on Raspberry Pi
Half of the battle is won. Unlike the regular Ubuntu install, you have not created a live environment. Ubuntu is already installed on the SD card and is almost read to use. Lets see what remains here.
#### Step 1: Insert the SD card into Pi
For first time users, it can take a bit confusing sometimes to figure out where on earth is that card slot! Not to worry. It is located below the board on the left-hand side. Heres an inverted view with a card inserted:
![Pi 4B board inverted and micro SD card inserted][25]
Keep sliding the card in this orientation slowly into the slot below the board, gently until it no longer goes any further. You may also hear a little clicking sound for confirmation. This means it has just fit in perfectly:
![Raspberry Pi SD slot left side middle and below the pi board][26]
You might notice two little pins adjusting themselves in the slot (shown above) as you put it inside, but thats ok. Once inserted, the card would look like a bit protruded. Thats how it is supposed to look like:
![Pi SD card inserted with a little portion visible][27]
#### Step 2: Setting Up the Raspberry Pi
I do not need to go in detail here, I presume.
Ensure that the power cable connector, micro HDMI cable connector, keyboard and mouse connectors (wired/non-wired) are securely connected to the Pi board in the relevant ports.
Make sure the display and power plug are properly connected as well, before you go ahead and turn on the power socket. I wouldnt recommend plugging in the adapter to a live electrical socket. Look up [electrical arcing][28].
Once youve ensured the above two steps, you can [power on the Raspberry Pi device][29].
#### Step 3: The first run of Ubuntu desktop on Raspberry Pi
Once you power on the Raspberry Pi, youll be asked to some basic configuration on your first run. You just have to follow the onscreen instructions.
Select your language, keyboard layout, connect to WiFi etc.
![Select language][30]
![Select keyboard layout][31]
![Select WiFi][32]
Youll be asked to select the time zone:
![Select time zone][33]
And then create the user and password:
![Enter desired username and password][34]
It will configure a couple of things and may take some time in doing so.
![Finishing Ubuntu setup][35]
![Finishing Ubuntu setup][36]
It may take some time after this, your system will reboot and youll find yourself at the Ubuntu login screen:
![][37]
You can start enjoying Ubuntu desktop on Raspberry Pi now.
![Ubuntu desktop on Raspberry Pi][38]
### Conclusion
I noticed **a temporary anomaly**: A red flickering border on the left-hand side of my display while doing the installation. This flickering (also of different colors) was noticeable on random parts of the screen as well. But it went away after restarting and the first boot.
It was much needed that Ubuntu to start providing support for popular ARM devices like Raspberry Pi and I am happy to see it running on a Raspberry Pi.
I hope you find this tutorial helpful. If you have questions or suggestions, please let me know in the comments.
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-ubuntu-desktop-raspberry-pi/
作者:[Avimanyu Bandyopadhyay][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/avimanyu/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/tutorial-how-to-install-raspberry-pi-os-raspbian-wheezy/
[2]: https://itsfoss.com/raspberry-pi-os/
[3]: https://itsfoss.com/install-ubuntu-server-raspberry-pi/
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-desktop-raspberry-pi.png?resize=800%2C450&ssl=1
[5]: https://github.com/raspberrypi/rpi-imager
[6]: https://www.raspberrypi.org/products/micro-hdmi-to-standard-hdmi-a-cable/
[7]: https://www.raspberrypi.org/products/type-c-power-supply/
[8]: https://itsfoss.com/things-you-need-to-get-your-raspberry-pi-working/
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-imager-tool.webp?resize=680%2C448&ssl=1
[10]: https://www.raspberrypi.org/software/
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-choose-os.webp?resize=681%2C443&ssl=1
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-other-general-purpose-os.webp?resize=679%2C440&ssl=1
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-os-ubuntu.webp?resize=677%2C440&ssl=1
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-os-ubuntu-21-04.webp?resize=677%2C440&ssl=1
[15]: https://ubuntu.com/download/raspberry-pi
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-choose-storage.webp?resize=677%2C438&ssl=1
[17]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-choose-sd-card.webp?resize=790%2C450&ssl=1
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-image-write.webp?resize=676%2C437&ssl=1
[19]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-image-write-confirm.webp?resize=679%2C440&ssl=1
[20]: https://itsfoss.com/add-sudo-user-ubuntu/
[21]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-image-write-password.webp?resize=380%2C227&ssl=1
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-writing-image.webp?resize=673%2C438&ssl=1
[23]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-verifying-changes.webp?resize=677%2C440&ssl=1
[24]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-imager-write-successful.webp?resize=675%2C442&ssl=1
[25]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-inverted-micro-sd-card-inserted.webp?resize=800%2C572&ssl=1
[26]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/raspberry-pi-sd-slot-left-side-middle-below-board.webp?resize=632%2C324&ssl=1
[27]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/pi-sd-card-inserted.webp?resize=650%2C432&ssl=1
[28]: https://www.electricianatlanta.net/what-is-electrical-arcing-and-why-is-it-dangerous/
[29]: https://itsfoss.com/turn-on-raspberry-pi/
[30]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run.webp?resize=800%2C451&ssl=1
[31]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-2.webp?resize=800%2C600&ssl=1
[32]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-3.webp?resize=800%2C600&ssl=1
[33]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-4.webp?resize=800%2C600&ssl=1
[34]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-5.webp?resize=800%2C600&ssl=1
[35]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-6.webp?resize=800%2C600&ssl=1
[36]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-first-run-7.webp?resize=800%2C600&ssl=1
[37]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-raspberry-pi-login-screen.webp?resize=800%2C600&ssl=1
[38]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/ubuntu-21-04-post-setup-desktop.webp?resize=800%2C450&ssl=1

View File

@ -1,250 +0,0 @@
[#]: subject: "How to Easily Install Debian Linux"
[#]: via: "https://itsfoss.com/install-debian-easily/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "guevaraya "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
如何简单安装 Debian Linux 系统
======
安装 Debian 的简易程度依赖于选择什么镜像。
如果你使用 Debain 官网的默认镜像,安装 Debian 就比较费劲。你会遇到这种界面,让你从外部介质先安装网络驱动。
![Installing Debian from default ISO is problematic for new users][1]
当然你也可以花时间去排除这个故障,但这让事情变得无意义的复杂。
不用担心,让我来展示如何轻巧的简单安装 Debian。
### 简单安装 Debian桌面系统
在你查看步骤之前,请确认以下准备工作:
* 一个至少 4Gb 大小的U盘
* 一个可以联网的系统(可以和要安装的操作系统一样)
* 要安装的 Debian 系统将会清理掉系统上所有数据,因此请拷贝重要数据到其他外部磁盘
你需要什么规格的 Debian 系统?取决于你想用什么类型的[桌面环境][2]。例如GNOME 桌面系统可以在4GB RAM上运行但最好在8GB RAM 流畅一些。如果你是4GB或更小的 RAM还是建议尝试 KDECinnamon 或 Xfce 桌面系统。
Debian 也都支持 [32位和64位的指令架构][3]。你需要根据你的CPU指令架构选择对应的 Debian 镜像。
你的系统应该至少要有 25 GB的硬盘空间可用。越多越好。
警告!
这个方法会移除磁盘上其他操作系统的已有数据。
你可能需要保存你后面还需要用的个人信息,文档,照片等到外部 U 盘或云盘。
这个教程是我安装附带 GNOME Debian 11 Bullseye 的步骤。这些步骤其实和其他桌面环境都大同小异。
_**这个教程在 UEFI 系统的 GPT分区得到验证。如果你是[MBR替换GPT分区][4],或[传统的BIOS替换UEFI][5]创建Live USB的步骤有一点不同。**_
#### 步骤 1获取正确的 Debian 的 ISO 镜像
在安装 Debian 过程中的一半事情是选择合适的 ISO 镜像。奇怪的是,确实作为一个新 Debian 用户很难从官网容易的找到 ISO镜像。
如果你点击 Debian 官网的下载按钮,它会下载一个为用户提供最佳兼容的最小安装包。请不太要用它。
反而,你需要用 Live ISO。这有一个技巧有独立非免费的 Live 版本(包含网络驱动)
你需要下载非免费的 live ISO 镜像。这里的其他程序可以不必从官网下载,有各种 torrents 连接或直接下载各种架构的安装包。
这些链接就在这里
[32和64位的主仓地址][7]
[Debian 11 官方下载][8]
[Debian 11 种子地址][9]
你将看到桌面环境的几个文件的名字。选择一种你的对应的桌面环境。直接下载的话,直接点击.iso结尾的链接。
![下载非免费版的 Live Debian 的ISO][10]
一旦你有了对应的 ISO 下载包,剩下就是和其他 Linux 发行版的安装流程一样了
#### 步骤 2: 创建一个 Debian 的 Live USB
将USB插入你的系统。最好在用之前最好格式化一下它最终也会被格式化的。
你可以根据你的选择使用任何版本的 Live USB 创建工具。如果你使用 Windows请用 Rufus。我们现在在这用 Etcher因为这个工具在 Windows 和 Linux 都可以用。
从它的官网下载 Etcher
[下载 Etcher][11]
我有一个专门的[在linux下使用 Etcher 的教程][12]。而这我就不深入介绍了。仅仅下载可执行程序,浏览 Debian 的 ISO镜像确认选择正确的 USB 驱动器然后点击 Flash 按钮。
![用 Etcher 创建 Debian 的 Live USB][13]
不一会就创建好 live USB。一旦创建好就可以开机引导了。
#### 步骤 3:从 live USB 引导启动
重启即将要安装 Debian 的系统。当她显示制造商标识的时候按下F2/F10 或 F12 键进入开机引导选择界面。你可能也会[进入到 UEFI 固件设置界面][14]。
有些系统已经开启了安全启动功能就不允许从 Live USB 开机引导。如果是这种情况,请[从BIOS设置里禁用安全启动][15]
不同的的制造商在界面上一些差异。
![][16]
一点你在 BIOS 里做了修改,按下 F10 保存并推出。你的系统将会重新启动。
再次看到,当看到制造商的标识后按下 F2/F10 或 F12 查看引导配置。你应该可以看到从 USB 引导的类似选项,然后选中。
![][17]
一会儿就会看到如下图的显示界面,选择第一个选项。
![Debian live 选择界面][18]
#### 步骤 4: 开始 Debian 安装
当你进入 live Debian 会话,如果你用 GNONE 桌面话,它呈现一个欢迎界面并带有选择你的键盘和语言。当你看到这些界面只需要点击下一步。
![Debian live 欢迎界面][19]
选择欢迎界面之后,按下 windows徽标/Super 键进入活动区。你应该可以看到 Debian 的安装按钮。
![开始 Debian 安装][20]
它会打开一个友好的[<ruby>卡拉马雷斯<rt>Calamares</rt></ruby>图形安装器][21]。从这里开始事情就比较简单了,
![Debian 11 Calamares graphical installer][22]
它会让你选择你的地理位置和时区。
![Select your location and time zone][23]
下一个界面,会让你选择键盘类型。这儿请 **注意**。你的键盘会根据位置自动选择。例如,我的位置是印度它会自动选择印地语的印度键盘。我不得不将其改为英语印度类型。
![选择键盘类型][24]
下一个界面是关于硬盘分区表和 Debian 安装哪里。这里是在你的系统只安装 Debian。
简单选择便是直接 “Erase Disk”。Debian 将把除过 ESP 分区和交互分区的其他分区都放在根挂载点上。实际上,下面显示了你选择了安装配置后的磁盘分布。
![磁盘分区][25]
如果你想手动选择,你也需要手工划分区,选择 roothomeboot 或 swap 分配多少。只有你知道自己在做什么你才可以去手工配置。
下一界面你需要提供用户名和密码。但它不会设置root的密码并将其保持为空。
![设置用户名和密码][26]
这也意味着你可以用 sudo 新创建用户。在“复杂 Debian 安装”中,你也可以设置 root 密码但前提是你必须用手动添加普通用户到 sudoer 列表。看看,这个安装过程是不是对新手来说很简单?
在实际真正安装之前,它会呈现你已经选择的汇总信息。如果没有问题,就可以点击安装按钮。
![安装配置的汇总信息][27]
现在只需要等待安装完成。
![安装 Debian][28]
几分钟后就会完成安装。当安装完成,它会提示重启。
![完成 Debian 安装][29]
如果一切顺利重启系统,你应该可以看到 Debian 的 grub 界面。
![Debian 启动画面][30]
### 疑难解答小贴士 (如果系统没有启动到 Debian)
我遇到情况是,我的 Dell 系统不能识别并引导任何操作系统。很奇怪,我已经能看到 Debian 已经创建了一个 ESP 分区。
如果你也是同样的情况去BIOS配置里。检测启动流程如果你看不到任何东西就点击新增一个启动选项。
![增加新的启动选项][31]
它会提供一个增加 EFI 文件的选项。
![选择 EFi 文件][32]
只有在安装过程中 Debian 创建了 ESP 分区,就有一个带文件的 EFI 目录被创建出来。
![选择 EFI 目录][33]
它会显示一个 Debian 文件夹包含其他文件夹。选择 Debian 文件夹。
![选择 Debian][34]
在 Debian 文件夹,你将看到 grubx64.efi, shimx64.efi。请选择 shimx64.efi。
![选择 shim.efi][35]
你需要选择一个合适的名字。最后的界面应该如下:
![增加 efi 文件的新启动选项][36]
现在你可能有了下面这个启动选项。我命名为 Debian它显示了两个 Debian 驱动选择(我猜其中一个是从 efi 文件来的)。按下 F10 保存退出 BIOS 的配置。
![新增的启动选项][37]
现在启动你的系统,你可以看到 grub 界面带有 Debian 的启动选项。你现在可以体验 Debian 了。
![][30]
### Debian 可以安装到哪里?
我这里的目的是让事情变得简单。并不是说你不能从默认的官网下载安装包来安装。只是它需要花更多的精力。
这个教程对你安装有帮助吗?你如果还是有问题,请在下面留言给我,我会尽力提供帮助。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-debian-easily/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[巴龙](https://github.com/guevaraya)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Debian-firmware.png?resize=800%2C600&ssl=1
[2]: https://itsfoss.com/what-is-desktop-environment/
[3]: https://itsfoss.com/32-bit-64-bit-ubuntu/
[4]: https://itsfoss.com/check-mbr-or-gpt/
[5]: https://itsfoss.com/check-uefi-or-bios/
[6]: https://www.debian.org/
[7]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/
[8]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/amd64/iso-hybrid/
[9]: https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/11.0.0-live+nonfree/amd64/bt-hybrid/
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/downloading-Debian-live-non-free-iso.png?resize=800%2C490&ssl=1
[11]: https://www.balena.io/etcher/
[12]: https://itsfoss.com/install-etcher-linux/
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/creating-live-debian-usb-with-etcher-800x518.png?resize=800%2C518&ssl=1
[14]: https://itsfoss.com/access-uefi-settings-windows-10/
[15]: https://itsfoss.com/disable-secure-boot-windows/
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2014/05/Disable_Secure_Boot_Windows8.jpg?resize=700%2C525&ssl=1
[17]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/boot-from-windows-disk-ventoy.jpg?resize=800%2C611&ssl=1
[18]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/debian-live-boot-screen.png?resize=617%2C432&ssl=1
[19]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/debian-live-welcome-screen.png?resize=800%2C450&ssl=1
[20]: https://itsfoss.com/wp-content/uploads/2021/08/start-Debian-installation-800x473.webp
[21]: https://calamares.io/
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-1.png?resize=800%2C441&ssl=1
[23]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-2-800x441.webp
[24]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-4-800x441.webp
[25]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-5.png?resize=800%2C441&ssl=1
[26]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-6.png?resize=800%2C441&ssl=1
[27]: https://itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-7-800x500.webp
[28]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-8.png?resize=800%2C500&ssl=1
[29]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/08/Installing-Debian-9.png?resize=800%2C500&ssl=1
[30]: https://itsfoss.com/wp-content/uploads/2021/08/debian-boot-screen.webp
[31]: https://itsfoss.com/wp-content/uploads/2021/08/add-new-boot-option.webp
[32]: https://itsfoss.com/wp-content/uploads/2021/08/add-efi-file-for-boot-option.webp
[33]: https://itsfoss.com/wp-content/uploads/2021/08/select-efi-file-boot-option.webp
[34]: https://itsfoss.com/wp-content/uploads/2021/08/select-debian-folder-for-uefi.webp
[35]: https://itsfoss.com/wp-content/uploads/2021/08/select-shim-boot.webp
[36]: https://itsfoss.com/wp-content/uploads/2021/08/new-boot-option.webp
[37]: https://itsfoss.com/wp-content/uploads/2021/08/new-boot-option-added.webp

View File

@ -0,0 +1,82 @@
[#]: subject: "Replace smart quotes with the Linux sed command"
[#]: via: "https://opensource.com/article/21/9/sed-replace-smart-quotes"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
用 Linux sed 命令替换智能引号
======
用你喜欢的 sed 版本去除“智能”引号。
![Coding on a computer][1]
In typography, a pair of quotation marks were traditionally oriented toward one another. They look like this:
在排版学中,一对引号传统上是朝向彼此的。它们看起来像这样:
“智能引号”
随着计算机在二十世纪中期的普及,这种方向往往被放弃了。计算机的原始字符集没有太多的空间,所以在 ASCII 规范中,两个双引号和两个单引号被缩减为各一个是合理的。如今,通用的字符集是 Unicode有足够的空间容纳许多花哨的引号和撇号但许多人已经习惯了开头和结尾引号都只有一个字符的极简主义。此外计算机实际上将不同种类的引号和撇号视为不同的字符。换句话说对计算机来说右双引号与左双引号或直引号是不同的。
### 用 sed 替换智能引号
计算机并不是打字机。当你按下键盘上的一个键时,你不是在按一个带有印章的控制杆。你只是按下一个按钮,向你的计算机发送一个信号,计算机将其解释为一个显示特定预定义字符的请求。这个请求取决于你的键盘映射。作为一个 Dvorak 打字员,我目睹了人们在发现我的键盘上的 “asdf” 在屏幕上产生 “aoeu” 时脸上的困惑。你也可能按了一些特殊的组合键来产生字符,如 ™ 或 ß 或 ≠,这甚至没有印在你的键盘上。
每个字母或字符不管它是否印在你的键盘上都有一个编码。字符编码可以用不同的方式表达但对计算机来说Unicode 序列 u2018 和 u2019 产生 **** 和 ****,而代码 u201c 和 u201d 产生 **“** 和 **”** 字符。知道这些“秘密”代码意味着你可以使用 [sed][2] 这样的命令以编程方式替换它们。任何版本的 sed 都可以,所以你可以使用 GNU sed 或 BSD sed甚至是 [Busybox][3] sed。
下面是我使用的简单的 shell 脚本:
```
#!/bin/sh
# GNU All-Permissive License
SDQUO=$(echo -ne '\u2018\u2019')
RDQUO=$(echo -ne '\u201C\u201D')
$SED -i -e "s/[$SDQUO]/\'/g" -e "s/[$RDQUO]/\"/g" "${1}"
```
将此脚本保存为 `fixquotes.sh`,然后创建一个包含智能引号的单独测试文件:
```
Single quote
“Double quote”
```
运行该脚本,然后使用 [cat][4] 命令查看结果:
```
$ sh ./fixquotes.sh test.txt
$ cat test.txt
'Single quote'
"Double quote"
```
### 安装 sed
如果你使用的是 Linux、BSD 或 macOS那么你已经安装了 GNU 或 BSD 的 `sed`。这是原始 `sed` 命令的两个独特的重新实现,对于本文中的脚本来说,它们在功能上是一样的(不过并不是所有的脚本都是这样)。
在 Windows 上,你可以用 [Chocolatey][6] [安装 GNU sed][5]。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/9/sed-replace-smart-quotes
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者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/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer)
[2]: https://opensource.com/article/20/12/sed
[3]: https://opensource.com/article/21/8/what-busybox
[4]: https://opensource.com/article/19/2/getting-started-cat-command
[5]: https://chocolatey.org/packages/sed
[6]: https://opensource.com/article/20/3/chocolatey

View File

@ -2,33 +2,33 @@
[#]: via: "https://fedoramagazine.org/how-to-check-for-update-info-and-changelogs-with-rpm-ostree-db/"
[#]: author: "Mateus Rodrigues Costa https://fedoramagazine.org/author/mateusrodcosta/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How to check for update info and changelogs with rpm-ostree db
如何用 rpm-ostree db 检查更新信息和更新日志
======
![][1]
Photo by [Dan-Cristian Pădureț][2] on [Unsplash][3]
照片由 [Dan-Cristian Pădureț][2] 发布在 [Unsplash][3]。
This article will teach you how to check for updates, check the changed packages, and read the changelogs with _rpm-ostree db_ and its subcommands.
这篇文章将教你如何使用 _rpm-ostree db_ 及其子命令检查更新、检查更改的软件包和阅读更新日志。
The commands will be demoed on a Fedora Silverblue installation and should work on any OS that uses _rpm-ostree_.
这些命令将在 Fedora Silverblue 上进行演示,并且应该在任何使用 _rpm-ostree_ 的操作系统上工作。
### Introduction
### 简介
Lets say you are interested in immutable systems. Using a base system that is read-only while you build your use cases on top of containers technology sounds very attractive and it persuades you to select a distro that uses _rpm-ostree_.
假设你对不可更改的系统感兴趣。在基于容器技术构建用例时使用只读的基本系统听起来非常有吸引力,它会说服你选择使用 _rpm-ostree_ 的发行版。
You now find yourself on [Fedora Silverblue][4] (or another similar distro) and you want to check for updates. But you hit a problem. While you can find the updated packages on Fedora Silverblue with GNOME Software, you cant actually read their changelogs. You also cant [use _dnf updateinfo_ to read them on the command line][5], since theres no DNF on the host system.
你现在发现自己在 [Fedora Silverblue][4](或其他类似的发行版)上,你想检查更新。但你遇到了一个问题。虽然你可以通过 GNOME Software 找到 Fedora Silverblue 上的更新包,但你实际上无法阅读它们的更新日志。你也不能[使用 _dnf updateinfo_ 在命令行上读取它们][5],因为主机系统上没有 DNF。
So, what should you do? Well, _rpm-ostree_ has subcommands that can help in this situation.
那么你应该怎么做呢_rpm-ostree_ 有一些子命令可以在这种情况下提供帮助。
### Checking for updates
### 检查更新
The first step is to check for updates. Simply run _rpm-ostree upgrade check_:
第一步是检查更新。只需运行 _rpm-ostree upgrade -check_
```
$ rpm-ostree upgrade --check
@ -41,9 +41,9 @@ AvailableUpdate:
Diff: 4 upgraded
```
Notice that while it doesnt tell the updated packages in the output, it does show the Commit for the update as _d8bab818f5abcfb58d2c038614965bf26426d55667e52018fcd295b9bfbc88b4_. This will be useful later.
请注意,虽然它没有在输出中告诉更新的软件包,但它显示了更新的 Commit 为 _d8bab818f5abcfb58d2c038614965bf26426d55667e52018fcd295b9bfbc88b4_。这在后面会很有用。
Next thing you need to do is find the Commit for the current deployment you are running. Run _rpm-ostree status_ to get the BaseCommit of the current deployment:
接下来你需要做的是找到你正在运行的当前部署的 Commit。运行 _rpm-ostree status_ 以获得当前部署的 BaseCommit
```
$ rpm-ostree status
@ -58,9 +58,9 @@ Deployments:
...
```
For this example BaseCommit is _e279286dcd8b5e231cff15c4130a4b1f5a03b6735327b213ee474332b311dd1e_.
对于这个例子BaseCommit 是 _e279286dcd8b5e231cff15c4130a4b1f5a03b6735327b213ee474332b311dd1e_
Now you can find the diff of the two commits with _rpm-ostree db diff [commit1] [commit2]_. In this command _commit1_ will be the BaseCommit from the current deployment and _commit2_ will be the Commit from the upgrade checking command.
现在你可以用 _rpm-ostree db diff [commit1] [commit2]_ 找到这两个提交的差异。在这个命令中_commit1_ 将是当前部署的 BaseCommit_commit2_ 将是升级检查命令中的 Commit。
```
$ rpm-ostree db diff e279286dcd8b5e231cff15c4130a4b1f5a03b6735327b213ee474332b311dd1e d8bab818f5abcfb58d2c038614965bf26426d55667e52018fcd295b9bfbc88b4
@ -70,7 +70,7 @@ Upgraded:
soundtouch 2.1.1-6.fc34 -> 2.1.2-1.fc34
```
The diff output shows that _soundtouch_ was updated and indicates the version numbers. View the changelogs by adding _changelogs_ to the previous command:
diff 输出显示 _soundtouch_ 被更新了,并指出了版本号。通过在前面的命令中加入 _-changelogs_ 来查看更新日志:
```
$ rpm-ostree db diff e279286dcd8b5e231cff15c4130a4b1f5a03b6735327b213ee474332b311dd1e d8bab818f5abcfb58d2c038614965bf26426d55667e52018fcd295b9bfbc88b4 --changelogs
@ -86,13 +86,13 @@ Upgraded:
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
```
This output shows the commit notes as well as the version numbers.
这个输出显示了提交说明以及版本号。
### Conclusion
### 总结
Using _rpm-ostree db_ you are now able to have the functionality equivalent to _dnf check-update_ and _dnf updateinfo_.
使用 _rpm-ostree db_,你现在可以拥有相当于 _dnf check-update__dnf updateinfo_ 的功能。
This will come in handy if you want to inspect detailed info about the updates you install.
如果你想检查你所安装的更新的详细信息,这将非常有用。
--------------------------------------------------------------------------------
@ -100,7 +100,7 @@ via: https://fedoramagazine.org/how-to-check-for-update-info-and-changelogs-with
作者:[Mateus Rodrigues Costa][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,125 @@
[#]: subject: "Screen Recording in Linux With OBS and Wayland"
[#]: via: "https://itsfoss.com/screen-record-obs-wayland/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
在 Linux 中使用 OBS 和 Wayland 进行屏幕录制
======
有[大量可用于 Linux 的屏幕录像机][1]。但是当涉及到支持 [Wayland][2] 时,几乎所有的都不能用。
这是个问题,因为许多新发布的版本都再次默认切换到 Wayland 显示管理器。而如果像屏幕录像机这样基本的东西不能工作,就会给人留下不好的体验。
[GNOME 的内置屏幕录像机][3]可以工作,但它是隐藏的,没有 GUI也没有办法配置和控制记录内容。还有一个叫 [Kooha][4] 的工具,但它一直在屏幕上显示一个计时器。
只是为了录制屏幕而[在 Xorg 和 Wayland 之间切换][5],这不是很方便。
在这一切中,我很高兴地得知,由于 Pipewire 的帮助,在 OBS Studio v27 中支持了 Wayland。但即使是这样也不是很简单因此我将向你展示使用 [OBS Studio][6] 在 Wayland 上录制屏幕的步骤。
### 使用 OBS 在 Wayland 上进行屏幕录制
![][7]
让我们来看看它是如何完成的。
#### 第一步:安装 OBS Studio
你应该先安装 OBS Studio v27。它已经包含在 Ubuntu 21.10 中,我会在本教程中使用它。
要在 Ubuntu 18.04、20.04、Linux Mint 20 等系统上安装 OBS Studio 27请使用[官方的 OBS Studio PPA][8]。
打开终端,逐一使用以下命令:
```
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt update
sudo apt install obs-studio
```
如果已经安装了 OBS Studio 的旧版本,它将被升级到较新的版本。
对于 Fedora、Arch 和其他发行版,请检查你的包管理器或非官方仓库以安装最新版本的 OBS Studio。
#### 第二步:检查 Wayland 捕获是否工作
请确认你正在使用 Wayland。现在启动 OBS Studio查看它在第一次运行时显示的所有内容。我不打算展示这些。
主要步骤是添加 Pipewire 作为屏幕捕捉源。点击 “Sources” 列表下的 “+” 符号。
![Add screen capture source in OBS Studio][9]
你有没有看到 “Screen Capture (PipeWire)” 的字样?
![Do you see PipeWire option in the screen sources?][10]
**如果答案是否定的,请退出 OBS Studio**。这很正常。至少在 Ubuntu 下OBS Studio 不会自动切换到使用 Wayland。对此有一个修复方法。
打开一个终端,使用以下命令:
```
export QT_QPA_PLATFORM=wayland
```
在同一个终端,运行以下命令,启动 OBS Studio
```
obs
```
它将在终端上显示一些信息。不要理会它们。你的注意力应该放在 OBS Studio GUI 上。再次尝试添加屏幕捕捉。你现在应该看到 PipeWire 选项了。
![][10]
你这次用 QT_QPA_PLATFORM 变量明确要求 OBS Studio 使用 Wayland。
选择 PipeWire 作为源,然后它要求你选择一个显示屏幕。选择它并点击分享按钮。
![][11]
现在它应该无限次递归地显示你的屏幕。如果你看到了,你现在就可以开始在 Wayland 中录制屏幕了。
![][12]
#### 第三步:让改变成为永久性的
这很好。你刚刚验证了你可以在 Wayland 上录制屏幕。但每次设置环境变量并从终端启动 OBS 并不方便。
你可以做的是**把这个变量导出到你的 ~/.bash_profile对你而言或 /etc/profile对系统中的所有用户而言。**
```
export QT_QPA_PLATFORM=wayland
```
退出并重新登录。现在 OBS 会自动开始使用这个参数,你可以用它来录制 Wayland 的屏幕。
我希望这个快速技巧对你有帮助。如果你还有问题或建议,请在评论区告诉我。
--------------------------------------------------------------------------------
via: https://itsfoss.com/screen-record-obs-wayland/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-linux-screen-recorders/
[2]: https://wayland.freedesktop.org/
[3]: https://itsfoss.com/gnome-screen-recorder/
[4]: https://itsfoss.com/kooha-screen-recorder/
[5]: https://itsfoss.com/switch-xorg-wayland/
[6]: https://obsproject.com/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-screen-record-wayland.webp?resize=800%2C450&ssl=1
[8]: https://launchpad.net/~obsproject/+archive/ubuntu/obs-studio
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-add-screen-capture-source.png?resize=800%2C537&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-wayland-support.png?resize=800%2C538&ssl=1
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/09/obs-studio-screen.png?resize=800%2C578&ssl=1
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/09/start-screen-recording-obs-wayland.jpg?resize=800%2C537&ssl=1