Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu Wang 2020-05-20 22:10:16 +08:00
commit 9c3f44bafa
10 changed files with 629 additions and 645 deletions

View File

@ -0,0 +1,163 @@
[#]: collector: (lujun9972)
[#]: translator: (LazyWolfLin)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-12232-1.html)
[#]: subject: (How I containerize a build system)
[#]: via: (https://opensource.com/article/20/4/how-containerize-build-system)
[#]: author: (Ravi Chandran https://opensource.com/users/ravichandran)
对构建系统进行容器化的指南
======
> 搭建一个通过容器分发应用的可复用系统可能很复杂,但这儿有个好方法。
![](https://img.linux.net.cn/data/attachment/album/202005/19/085248ausakkjfu05akqr2.jpg)
一个用于将源代码转换成可运行的应用的构建系统是由工具和流程共同组成。在转换过程中还涉及到代码的受众从软件开发者转变为最终用户,无论最终用户是运维的同事还是部署的同事。
在使用容器搭建了一些构建系统后,我觉得有一个不错的可复用的方法值得分享。虽然这些构建系统被用于编译机器学习算法和为嵌入式硬件生成可加载的软件镜像,但这个方法足够抽象,可用于任何基于容器的构建系统。
这个方法是以一种易于使用和维护的方式搭建或组织构建系统,但并不涉及处理特定编译器或工具容器化的技巧。它适用于软件开发人员构建软件,并将可维护镜像交给其他技术人员(无论是系统管理员、运维工程师或者其他一些头衔)的常见情况。该构建系统被从终端用户中抽象出来,这样他们就可以专注于软件。
### 为什么要容器化构建系统?
搭建基于容器的可复用构建系统可以为软件团队带来诸多好处:
* **专注**:我希望专注于应用的开发。当我调用一个工具进行“构建”时,我希望这个工具集能生成一个随时可用的二进制文件。我不想浪费时间在构建系统的查错上。实际上,我宁愿不了解,或者说不关心构建系统。
* **一致的构建行为**:无论在哪种使用情况下,我都想确保整个团队使用相同版本的工具集并在构建时得到相同的结果。否则,我就得不断地处理“我这咋就是好的”的麻烦。在团队项目中,使用相同版本的工具集并对给定的输入源文件集产生一致的输出是非常重要。
* **易于部署和升级**:即使向每个人都提供一套详细说明来安装一个项目的工具集,也可能会有人翻车。问题也可能是由于每个人对自己的 Linux 环境的个性化修改导致的。在团队中使用不同的 Linux 发行版(或者其他操作系统),情况可能还会变得更复杂。当需要将工具集升级到下一版本时,问题很快就会变得更糟糕。使用容器和本指南将使得新版本升级非常简单。
对我在项目中使用的构建系统进行容器化的这些经验显然很有价值,因为它可以缓解上述问题。我倾向于使用 Docker 作为容器工具,虽然在相对特殊的环境中安装和网络配置仍可能出现问题,尤其是当你在一个使用复杂代理的企业环境中工作时。但至少现在我需要解决的构建系统问题已经很少了。
### 漫步容器化的构建系统
我创建了一个[教程存储库][2],随后你可以克隆并检查它,或者按照本文内容进行操作。我将逐个介绍存储库中的文件。这个构建系统非常简单(它运行 `gcc`),从而可以让你专注于这个构建系统结构上。
### 构建系统需求
我认为构建系统中有两个关键点:
* **标准化构建调用**:我希望能够指定一些形如 `/path/to/workdir` 的工作目录来构建代码。我希望以如下形式调用构建:
./build.sh /path/to/workdir
为了使得示例的结构足够简单(以便说明),我将假定输出也在 `/path/to/workdir` 路径下的某处生成。(否则,将增加容器中显示的卷的数量,虽然这并不困难,但解释起来比较麻烦。)
* **通过 shell 自定义构建调用**:有时,工具集会以出乎意料的方式被调用。除了标准的工具集调用 `build.sh` 之外,如果需要还可以为 `build.sh` 添加一些选项。但我一直希望能够有一个可以直接调用工具集命令的 shell。在这个简单的示例中有时我想尝试不同的 `gcc` 优化选项并查看效果。为此,我希望调用:
./shell.sh /path/to/workdir
这将让我得到一个容器内部的 Bash shell并且可以调用工具集和访问我的工作目录`workdir`),从而我可以根据需要尝试使用这个工具集。
### 构建系统的架构
为了满足上述基本需求,这是我的构架系统架构:
![Container build system architecture][3]
在底部的 `workdir` 代表软件开发者用于构建的任意软件源码。通常,这个 `workdir` 是一个源代码的存储库。在构建之前,最终用户可以通过任何方式来操纵这个存储库。例如,如果他们使用 `git` 作为版本控制工具的话,可以使用 `git checkout` 切换到他们正在工作的功能分支上并添加或修改文件。这样可以使得构建系统独立于 `workdir` 之外。
顶部的三个模块共同代表了容器化的构建系统。最左边的黄色模块代表最终用户与构建系统交互的脚本(`build.sh` 和 `shell.sh`)。
在中间的红色模块是 Dockerfile 和相关的脚本 `build_docker_image.sh`。开发运营者(在这个例子中指我)通常将执行这个脚本并生成容器镜像(事实上我多次执行它直到一切正常为止,但这是另一回事)。然后我将镜像分发给最终用户,例如通过<ruby>容器信任注册库<rt>container trusted registry</rt></ruby>进行分发。最终用户将需要这个镜像。另外,他们将克隆构建系统的存储库(即一个与[教程存储库][2]等效的存储库)。
当最终用户调用 `build.sh` 或者 `shell.sh` 时,容器内将执行右边的 `run_build.sh` 脚本。接下来我将详细解释这些脚本。这里的关键是最终用户不需要为了使用而去了解任何关于红色或者蓝色模块或者容器工作原理的知识。
### 构建系统细节
把教程存储库的文件结构映射到这个系统结构上。我曾将这个原型结构用于相对复杂构建系统,因此它的简单并不会造成任何限制。下面我列出存储库中相关文件的树结构。文件夹 `dockerize-tutorial` 能用构建系统的其他任何名称代替。在这个文件夹下,我用 `workdir` 的路径作参数调用 `build.sh``shell.sh`
```
dockerize-tutorial/
├── build.sh
├── shell.sh
└── swbuilder
    ├── build_docker_image.sh
    ├── install_swbuilder.dockerfile
    └── scripts
        └── run_build.sh
```
请注意,我上面特意没列出 `example_workdir`,但你能在教程存储库中找到它。实际的源码通常存放在单独的存储库中,而不是构建工具库中的一部分;本教程为了不必处理两个存储库,所以我将它包含在这个存储库中。
如果你只对概念感兴趣,本教程并非必须的,因为我将解释所有文件。但是如果你继续本教程(并且已经安装 Docker首先使用以下命令来构建容器镜像 `swbuilder:v1`
```
cd dockerize-tutorial/swbuilder/
./build_docker_image.sh
docker image ls  # resulting image will be swbuilder:v1
```
然后调用 `build.sh`
```
cd dockerize-tutorial
./build.sh ~/repos/dockerize-tutorial/example_workdir
```
下面是 [build.sh][4] 的代码。这个脚本从容器镜像 `swbuilder:v1` 实例化一个容器。而这个容器实例映射了两个卷:一个将文件夹 `example_workdir` 挂载到容器内部路径 `/workdir` 上,第二个则将容器外的文件夹 `dockerize-tutorial/swbuilder/scripts` 挂载到容器内部路径 `/scripts` 上。
```
docker container run                              \
    --volume $(pwd)/swbuilder/scripts:/scripts    \
    --volume $1:/workdir                          \
    --user $(id -u ${USER}):$(id -g ${USER})      \
    --rm -it --name build_swbuilder swbuilder:v1  \
    build
```
另外,`build.sh` 还会用你的用户名(以及组,本教程假设两者一致)去运行容器,以便在访问构建输出时不出现文件权限问题。
请注意,[shell.sh][5] 和 `build.sh` 大体上是一致的,除了两点不同:`build.sh` 会创建一个名为 `build_swbuilder` 的容器,而 `shell.sh` 则会创建一个名为 `shell_swbuilder` 的容器。这样一来,当其中一个脚本运行时另一个脚本被调用也不会产生冲突。
两个脚本之间的另一处关键不同则在于最后一个参数:`build.sh` 传入参数 `build``shell.sh` 则传入 `shell`。如果你看了用于构建容器镜像的 [Dockerfile][6],就会发现最后一行包含了下面的 `ENTRYPOINT` 语句。这意味着上面的 `docker container run` 调用将使用 `build``shell` 作为唯一的输入参数来执行 `run_build.sh` 脚本。
```
# run bash script and process the input command
ENTRYPOINT [ "/bin/bash", "/scripts/run_build.sh"]
```
[run_build.sh][7] 使用这个输入参数来选择启动 Bash shell 还是调用 `gcc` 来构建 `helloworld.c` 项目。一个真正的构建系统通常会使用 Makefile 而非直接运行 `gcc`
```
cd /workdir
if [ $1 = "shell" ]; then    
    echo "Starting Bash Shell"
    /bin/bash
elif [ $1 = "build" ]; then
    echo "Performing SW Build"
    gcc helloworld.c -o helloworld -Wall
fi
```
在使用时,如果你需要传入多个参数,当然也是可以的。我处理过的构建系统,构建通常是对给定的项目调用 `make`。如果一个构建系统有非常复杂的构建调用,则你可以让 `run_build.sh` 调用 `workdir` 下最终用户编写的特定脚本。
### 关于 scripts 文件夹的说明
你可能想知道为什么 `scripts` 文件夹位于目录树深处而不是位于存储库的顶层。两种方法都是可行的,但我不想鼓励最终用户到处乱翻并修改里面的脚本。将它放到更深的地方是一个让他们更难乱翻的方法。另外,我也可以添加一个 `.dockerignore` 文件去忽略 `scripts` 文件夹,因为它不是容器必需的部分。但因为它很小,所以我没有这样做。
### 简单而灵活
尽管这一方法很简单,但我在几个相当不同的构建系统中使用过,发现它相当灵活。相对稳定的部分(例如,一年仅修改数次的给定工具集)被固定在容器镜像内。较为灵活的部分则以脚本的形式放在镜像外。这使我能够通过修改脚本并将更改推送到构建系统存储库中,轻松修改调用工具集的方式。用户所需要做的是将更改拉到本地的构建系统存储库中,这通常是非常快的(与更新 Docker 镜像不同)。这种结构使其能够拥有尽可能多的卷和脚本,同时使最终用户摆脱复杂性。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/how-containerize-build-system
作者:[Ravi Chandran][a]
选题:[lujun9972][b]
译者:[LazyWolfLin](https://github.com/LazyWolfLin)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/ravichandran
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_2015-3-osdc-lead.png?itok=O6aivM_W (Containers on a ship on the ocean)
[2]: https://github.com/ravi-chandran/dockerize-tutorial
[3]: https://opensource.com/sites/default/files/uploads/build_sys_arch.jpg (Container build system architecture)
[4]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/build.sh
[5]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/shell.sh
[6]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/swbuilder/install_swbuilder.dockerfile
[7]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/swbuilder/scripts/run_build.sh

View File

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

View File

@ -1,186 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to use pyenv to run multiple versions of Python on a Mac)
[#]: via: (https://opensource.com/article/20/4/pyenv)
[#]: author: (Matthew Broberg https://opensource.com/users/mbbroberg)
How to use pyenv to run multiple versions of Python on a Mac
======
If you need to run a project that uses a Python version you don't have
installed on macOS, try pyenv.
![Searching for code][1]
Managing a local Python development environment continues to be a challenge, even for experienced developers. While there are well-documented [strategies for package management][2], there is another step necessary to ensure you are running the version of Python you need when you need it.
### Why does the version of Python matter?
It's a strange concept at first, but programming languages change like any other software. They have bugs, fixes, and updates like any of your favorite [APIs][3] and any other software. Similarly again, different releases are identified by a three-digit number known as a [semantic version][4].
> 😭😭😭 [pic.twitter.com/yt1Z2439W8][5]
>
> — Denny Perez (@dennyperez18) [May 28, 2019][6]
For many years, Python 2 was the commonly used major version of the programming language. In January 2020, Python 2 [reached end of life][7], and only Python 3 will be supported by the language's core maintainers from then forward. Python 3 is developing steadily, and releasing new updates regularly. That makes it important for me to regularly get those updates.
Recently, I tried to run a project on macOS that depended on Python 3.5.9, a version that I did not have installed on my system. It might seem logical to think the Python package manager **pip** could install it*, but that wasn't the case:
```
$ pip install python3.5.9
Collecting python3.5.9
  ERROR: Could not find a version that satisfies the requirement python3.5.9 (from versions: none)
ERROR: No matching distribution found for python3.5.9
```
Alternatively, I could have downloaded that version from the official Python website, but how would I run it in on my Mac alongside my existing version of Python? Specifying the version of Python I intend to use every time I run the interpreter (python3.7 or python3.5 for example) seems error-prone at best. There has to be a better way.
_(A note on the above: I know this makes no sense to seasoned Python developer, but it made sense to me at the time. I would happily talk about why I still think it should.)_
### Installing and setting up pyenv
Thankfully, **pyenv** exists to work around this series of complexities. To start, I needed to install pyenv. I could clone and compile it myself [from source][8], but I prefer to manage packages like this through the Homebrew package manager:
```
`$ brew install pyenv`
```
In order to use the version of Python through pyenv, it's essential to understand the shell's PATH variable. PATH determines where the shell searches for files by the name of the command. You must ensure the shell will find the version of Python run by pyenv, not the one installed by default (which is often called the _system version_). If you don't change the path, here is the result:
```
$ which python
/usr/bin/python
```
That's the system version of Python.
To set up pyenv correctly, you can run the following in Bash or zsh:
```
`$ PATH=$(pyenv root)/shims:$PATH`
```
Now, if you check the version of Python, you'll see it is the one managed by pyenv:
```
$ which python
/Users/my_username/.pyenv/shims/python
```
That export statement (PATH=) will only change for this shell instance, so make it a permanent change, you need to add it to your dotfiles. Since zsh is officially macOS's default shell, I'll focus on it. Append that same syntax to the **~/.zshrc** file:
```
`$ echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.zshrc`
```
Now every time we run a command in zsh, it will use the pyenv version of Python. Note that I used single quotes with **echo** so it does not evaluate and expand the commands.
The .zshrc file only manages zsh instances, so be sure to check what your shell is and edit the associated dotfiles. If you need to double-check what your default shell is, you can run **echo $SHELL**. If it's zsh, use the command above. If you use Bash, change **~/.zshrc** to **~/.bashrc**. You can dive deep into [path setting][9] in pyenv's README if you would like to learn more.
### Using pyenv to manage Python versions
Now that pyenv is in control, we can see it only has the system Python available to it:
```
$ pyenv versions
system
```
As mentioned above, you absolutely do not want to use this version ([read more on why][10]). Now that pyenv is set up correctly, I want it to have a few different versions of Python that I regularly use.
There is a way to see all Python versions available from all the different repositories pyenv has access to by running **pyenv install --list**. It's a long, overwhelming list that may be helpful to review in the future. For now, I stick with the latest of each dot-release (3.5.x or 3.6.x where x is the latest) found on the [Python download page][11]. With that in mind, I'll install 3.5.9 and 3.8.0:
```
$ pyenv install 3.5.9
$ pyenv install 3.8.0
```
This will take a while, so get some tea (or read one of the links above). It's interesting to note that the output walks through the download and building of that version of Python. For example, the output shows that the file comes directly from [Python.org][12].
Once everything is installed, you can set up your defaults. I like to live at the cutting edge, so I set my global default Python version to the latest:
```
`$ pyenv global 3.8.0`
```
And that version is immediately set in my shell. To confirm:
```
$ python -V
Python 3.8.0
```
The project I want to run works only with Python 3.5, so I'll set the version locally and confirm it's in use:
```
$ pyenv local 3.5.9
$ python -V
Python 3.5.9
```
Because I used the **local** option with pyenv, it added a file to my current directory to track that information. 
```
$ cat .python-version
3.5.9
```
Now, I can finally set up a virtual environment for the project I want and be sure I'm running the right version of Python.
```
$ python -m venv venv
$ source ./venv/bin/activate
(venv) $ which python
/Users/mbbroberg/Develop/my_project/venv/bin/python
```
To learn more, check out this tutorial about [managing virtual environments on a Mac][13].
### Wrapping up
By default, running multiple Python versions can be a challenge. I find starting with pyenv ensures I have the versions of Python I need set up to run when I need them.
Do you have other beginner or intermediate Python questions? Leave a comment, and we will consider them for a future article.
Newcomers to python-ideas occasionally make reference to the idea of "Python 4000" when proposing...
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/pyenv
作者:[Matthew Broberg][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/mbbroberg
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/search_find_code_python_programming.png?itok=ynSL8XRV (Searching for code)
[2]: https://opensource.com/article/19/4/managing-python-packages
[3]: https://opensource.com/article/19/5/api-evolution-right-way
[4]: https://semver.org/
[5]: https://t.co/yt1Z2439W8
[6]: https://twitter.com/dennyperez18/status/1133505310516232203?ref_src=twsrc%5Etfw
[7]: https://opensource.com/article/19/11/end-of-life-python-2
[8]: https://github.com/pyenv/pyenv
[9]: https://github.com/pyenv/pyenv#understanding-path
[10]: https://opensource.com/article/19/5/python-3-default-mac
[11]: https://www.python.org/downloads/
[12]: http://python.org
[13]: https://opensource.com/article/19/6/python-virtual-environments-mac

View File

@ -1,125 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to Handle Automatic Updates in Ubuntu)
[#]: via: (https://itsfoss.com/auto-updates-ubuntu/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
How to Handle Automatic Updates in Ubuntu
======
_**Brief: This tutorial teaches you how to handle the unattended upgrade i.e. the automatic system updates in Ubuntu Linux.**_
Sometimes, when you try to [shutdown your Ubuntu system][1], you may come across this screen that stops you from shutting down:
**Unattended-upgrade in progress during shutdown, please dont turn off the computer.**
![Unattended Upgrade In Progress In Ubuntu][2]
You might wonder what is this “unattended upgrade” and how come it is running without your knowledge.
The reason is that [Ubuntu][3] takes your systems security very seriously. By default, it automatically checks for system updates daily and if it finds any security updates, it downloads those updates and install them on its own. For normal system and application updates, it notifies you via the Software Updater tool.
Since all this happens in the background, you dont even realize it until you try to shutdown your system or try to install applications on your own.
Trying to install a new software when these unattended upgrades are in progress leads to the famous [could not get lock error][4].
![][5]
As you can see, the automatic updates present a couple of minor annoyance. You may choose to disable the auto updates but that would mean that youll have to check and [update your Ubuntu system][6] manually all the time.
Do you really need to disable auto updates?
Please note that this is a security feature. Linux allows you to do practically everything in your system even disabling these security features.
But in my opinion, as a regular user, _**you should not disable the automatic updates**_. It keeps your system safe after all.
For the sake of your systems security, you may tolerate the minor annoyances that come with the automatic updates.
Now that you have been warned and you think it is better to take up the additional task of manually updating your system, lets see how to handle the auto updates.
As always, there are two ways to do it: GUI and command line. Ill show you both methods.
I have used Ubuntu 20.04 here but the steps are valid for Ubuntu 18.04 and any other Ubuntu version.
### Method 1: Disable automatic updates in Ubuntu graphically
Go to the menu and look for software &amp; updates tool.
![Software & Updates Settings][7]
In here, go to Updates tab. Now look for the “Automatically check for updates”. By default it is set to Daily.
You can change it to Never and your system will never check for updates on its own again. And if it wont check for updates, it wont find new updates to install.
![Disable Auto Updates in Ubuntu Completely][8]
If you do this, you must manually update your system from time to time. But thats an additional chore to do and you may not remember it all the time.
#### Slightly better way to handle auto updates in Ubuntu
Personally, I would suggest to let it check for updates on its own. If you dont want it installing the updates automatically, you can change that behavior to get notified about the availability of security updates.
Keep “Automatically check for updates” to Daily and change “When there are security updates” option to “Display immediately” instead of “Download and install automatically”.
![Get notified for security updates instead of automatically installing them][9]
This way, it checks for updates and if there are updates, instead of installing them automatically in the background, the Software Updater tool notifies you that updates are available for your system. Your system already does that for normal system and software updates.
![Get notified about security updates][10]
With this setup, you wont see the “unattended upgrades in progress” when you shutdown your system However, you may still encounter the could not get lock error because two separate processes cannot use apt package manager at the same time.
I believe this is a better solution, dont you you think?
As I promised both GUI and command line methods, let me show you how to disable unattended upgrades in the terminal.
### How to disable automatic updates in Ubuntu using command line
Youll find the auto-upgrades settings in the **/etc/apt/apt.conf.d/20auto-upgrades** file. The default text editor in Ubuntu terminal is Nano so you can use this command to edit this configuration file:
```
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
```
Now, if you dont want your system to check for updates automatically, you can change the value of APT::Periodic::Update-Package-Lists to 0.
```
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Unattended-Upgrade "0";
```
If you want it to check for updates but dont install the unattended-upgrades automatically, you can choose to set it like this:
```
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "0";
```
**In the end…**
The automatic security updates are enabled automatically for a reason and I recommend you keep it like this. A couple of minor annoyances are not really worth risking the security of your system. What do you think?
--------------------------------------------------------------------------------
via: https://itsfoss.com/auto-updates-ubuntu/
作者:[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/schedule-shutdown-ubuntu/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/unattended-upgrade-in-progress-in-ubuntu.png?ssl=1
[3]: https://ubuntu.com/
[4]: https://itsfoss.com/could-not-get-lock-error/
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/12/Could_not_get_lock.jpg?ssl=1
[6]: https://itsfoss.com/update-ubuntu/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/software-updates-settings-ubuntu-20-04.jpg?ssl=1
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/04/disable-auto-updates-ubuntu.jpg?ssl=1
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/04/handle-auto-updates-ubuntu.jpg?ssl=1
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/04/updates-available-ubuntu.png?ssl=1

View File

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

View File

@ -1,169 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (HankChow)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (5 ways to split your Linux terminal)
[#]: via: (https://opensource.com/article/20/5/split-terminal)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
5 ways to split your Linux terminal
======
What's your favorite terminal multiplexer? Take our poll. Then read
about how Linux offers plenty of ways for you to split your terminal so
you can multitask.
![4 different color terminal windows with code][1]
Is there anything better than a warmly flickering Linux terminal?
Sure there is: two warmly flickering Linux terminals. In fact, the more, the better.
Long ago, [terminals were physical devices][2], but of course, today, they're just emulated as an application on your computer. If you prefer the terminal as your interface, you probably know that one terminal is rarely enough. Inevitably, you're going to open a new terminal or a new tab so you can work in it while your first is busy compiling or converting or otherwise processing data.
If you're a sysadmin, then you know you're going to need at least four open windows while you work on several systems at the same time.
Terminal applications with tabs have existed on Linux for a long time, and luckily, that trend seems to have caught on such that it's an expected feature of a modern terminal. And yet, sometimes it's distracting or inconvenient to flip back and forth between tabs.
The only answer is a split screen so that two or more terminals can exist at the same time within just one application window. There are many tools in your Linux kit to help you slice and dice your consoles.
### Shells, terminals, and consoles
Before you slice and dice screens, you should know the difference between a terminal, a shell, and a "console." To get the full picture, read my article on the subject over on the [Enable Sysadmin][2] blog.
The short version:
* A shell is an input and output screen with a prompt. There's technically a shell running somewhere underneath your [POSIX][3] desktop, even when it's not visible (because it's a shell that launched your user session).
* A terminal is an application running within a graphics server (such as X11 or Wayland) with a shell loaded into it. A terminal is only running when you have a terminal window launched. It's more or less a "portal" into your shell.
* "Console" or "virtual console" is a term usually used to imply a shell running outside of your desktop. You can get to a virtual console by pressing **Alt-Ctrl-F2** (more are usually available from **F3** up to **F7**, with **F1** or **F7** representing your desktop, depending on your distribution).
Some applications let you split your shell or console, while others let you split your terminal.
### tmux
![tmux terminal][4]
Arguably the most flexible and capable of screen splitters, [tmux][5] is a keyboard-centric terminal multiplexer, meaning that you can "layer" one console on top of another and then switch between the two. You can also split a console view in half (or thirds or fourths, and so on) so you can see other consoles next to it.
All controls center around the keyboard, which means you never have to take your hand off the keys in search of a mouse, but also that you must learn some new keyboard combos.
If you're using tmux primarily for screen splitting, then the only commands you really need are these:
* **Ctrl-B %** for a vertical split (one shell on the left, one shell on the right)
* **Ctrl-B"** for a horizontal split (one shell at the top, one shell at the bottom)
* **Ctrl-B O** to make the other shell active
* **Ctrl-B ?** for help
* **Ctrl-B d** detach from Tmux, leaving it running in the background (use **tmux attach** to reenter)
There are many benefits to tmux, including the ability to start a tmux session on one computer, and then join that same session from another computer remotely. It essentially daemonizes your shell.
It's with tmux running on a Pi, for example, that I can stay logged into IRC on a permanent basis—I start tmux on the Pi, and then log in from whatever computer I happen to be on. When I log out, tmux continues to run, patiently waiting for me to reattach to the session from a different computer.
### GNU Screen
![GNU Screen terminal][6]
Similar to tmux, [GNU Screen][7] is a shell multiplexer. You can detach and reattach from a running session, and you can split the screen both horizontally and vertically.
Screen is a little clunkier than tmux. Its default key binding is **Ctrl-A**, which also happens to be Bash's keyboard shortcut to go to the beginning of a line. This means that if you have Screen running, you must press **Ctrl-A** twice instead of just once to go to the beginning of the line. Personally, I redefine the trigger key to **Ctrl-J** with this line in **$HOME/.screenrc**:
```
`escape ^jJ`
```
Screen's split function works well, but it leaves out a few pleasantries that tmux lacks. For instance, when you split your shell, a new shell does not start in the other panel. You have to navigate to the other space with **Ctrl-A Tab** (or **Ctrl-J** if you redefine your keyboard shortcut as I do) and create a new shell manually with **Ctrl-A C**.
Unlike tmux, a split doesn't go away when you exit a shell, which is a design feature that's quite nice in some instances but can also sometimes be cumbersome because it forces you to manage your splits manually.
Still, Screen is a reliable and flexible application that you can run should you find that **tmux** is unavailable to you.
Here are the basic split commands, using the default keyboard shortcuts:
* **Ctrl-A |** for a vertical split (one shell on the left, one shell on the right)
* **Ctrl-A S** for a horizontal split (one shell at the top, one shell at the bottom)
* **Ctrl-A Tab** to make the other shell active
* **Ctrl-A ?** for help
* **Ctrl-A d** detach from Screen, leaving it running in the background (use **screen -r** to reenter)
### Konsole
![Konsole screen][8]
[Konsole][9] is the terminal bundled along with the KDE Plasma desktop. Like KDE itself, Konsole is famous for being highly customizable and powerful.
Among its many features is the ability to split its window, similar to both tmux and GNU Screen. Because Konsole is a graphical terminal, you can control its split-screen feature with your mouse instead of your keyboard.
Splitting is found in the **View** menu of Konsole. You can split your window horizontally or vertically. To change which panel is active, just click on it. Each panel is a unique terminal, so it can have its own theme and tabs.
Unlike tmux and GNU Screen, you can't detach and reattach from Konsole. Like most graphical applications, you use Konsole while you're physically in front of it, and you lose access to it when you're away (unless you use remote desktop software).
### Emacs
![Emacs rpg][10]
Emacs isn't exactly a terminal multiplexer, but its interface supports splitting and resizing, and it has a built-in terminal.
If you're in Emacs on a daily basis anyway, the ability to split your window between essentially different applications means you never have to leave the familiarity and comfort of your favorite text editor. Furthermore, because the Emacs **eshell** module is implemented in eLISP, you can interact with it using the same commands you use in Emacs itself, making it trivial to copy and yank long file paths or command output.
If you're using Emacs in a graphical window, you can perform some actions with your mouse. It's faster to use keyboard shortcuts, and some are more or less required. For instance, you can change which panel is the active one by clicking into it, and you can resize the proportions of your split screen with your mouse.
These are the important keyboard shortcuts:
* **Ctrl-X 3** for a vertical split (one shell on the left, one shell on the right)
* **Ctrl-X 2** for a horizontal split (one shell at the top, one shell at the bottom)
* **Ctrl-X O** to make the other shell active (you can also do this with the mouse)
* **Ctrl-X 0** (thats a zero) close the current panel
Similar to tmux and GNU Screen, you can detach and reattach from Emacs as long as you run **emacs-client**.
### Window manager
![Ratpoison split screen][11]
Should you think a text editor that can split its screen and load a terminal is amazing, imagine your desktop serving the same purpose. There are Linux desktops, like [Ratpoison][12], [Herbsluftwm][13], i3, Awesome, and even the KDE Plasma desktop with specific settings enabled, that present each application window to you as a fixed tile in a desktop grid.
Instead of windows floating "above" your desktop, they remain in a predictable place so you can change from one to the other. You can open any number of terminals within your grid, emulating a terminal multiplexer. In fact, you could even load a terminal multiplexer in your desktop multiplexer.
And there's nothing stopping you from loading Emacs with split buffers inside of that. No one knows what happens if you take it further than that, and most Linux users agree it's best not to find out.
Unlike tmux and GNU Screen, you can't detach and reattach from your desktop unless you count using remote desktop software.
### Other options
Believe it or not, these aren't the only options you have to split your screen on Linux. There are other terminal emulators, like [Tilix][14] and Terminator before it, that can split into sections, and applications with embedded terminal components, and much more. Tell us your favorite way of splitting up your workspace in the comments.
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/5/split-terminal
作者:[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/freedos.png?itok=aOBLy7Ky (4 different color terminal windows with code)
[2]: https://www.redhat.com/sysadmin/terminals-shells-consoles
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
[4]: https://opensource.com/sites/default/files/uploads/terminal-split-tmux2.png (tmux terminal)
[5]: https://github.com/tmux/tmux
[6]: https://opensource.com/sites/default/files/uploads/terminal-split-screen.png (GNU Screen terminal)
[7]: https://www.gnu.org/software/screen/
[8]: https://opensource.com/sites/default/files/uploads/konsole.jpg (Konsole screen)
[9]: https://konsole.kde.org
[10]: https://opensource.com/sites/default/files/uploads/emacs-rpg_0.jpg (Emacs rpg)
[11]: https://opensource.com/sites/default/files/uploads/advent-ratpoison-split_0.jpg (Ratpoison split screen)
[12]: https://opensource.com/article/19/12/ratpoison-linux-desktop
[13]: https://opensource.com/article/19/12/herbstluftwm-linux-desktop
[14]: https://gnunn1.github.io/tilix-web/

View File

@ -0,0 +1,180 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to use pyenv to run multiple versions of Python on a Mac)
[#]: via: (https://opensource.com/article/20/4/pyenv)
[#]: author: (Matthew Broberg https://opensource.com/users/mbbroberg)
如何在 Mac 上使用 pyenv 运行多个版本的 Python
======
如果你需要运行 macOS 上没有安装的 Python 版本,请试试 pyenv。
![Searching for code][1]
即使对于有经验的开发人员,管理本地 Python 开发环境仍然是一个挑战。尽管有详细的[软件包管理策略][2],但仍需要采取另外的步骤来确保你在需要时运行所需的 Python 版本。
### 为什么 Python 版本重要?
起初这是一个奇怪的概念,但是编程语言会像其他任何软件一样发生变化。它们有 bug修复和更新就像你喜欢的 [API][3] 和任何其他软件一样。同样,不同的发行版由称为[语义版本][4]的三位数标识。
> 😭😭😭 [pic.twitter.com/yt1Z2439W8][5]
>
> — Denny Perez (@dennyperez18) [May 28, 2019][6]
多年来Python 2 是该语言的常用主要版本。在 2020 年 1 月Python 2 [到达最后寿命][7]此后Python 的核心维护者将仅支持 Python 3。Python 3 稳步发展,并定期发布新更新。对我来说定期获取这些更新很重要。
最近,我尝试在依赖于 Python 3.5.9 的 macOS 上运行一个项目,但该版本尚未安装在系统上。我认为 Python 包管理器 **pip** 可以安装它,但事实并非如此:
```
$ pip install python3.5.9
Collecting python3.5.9
  ERROR: Could not find a version that satisfies the requirement python3.5.9 (from versions: none)
ERROR: No matching distribution found for python3.5.9
```
或者,我可以从官方 Python 网站下载该版本,但是除了现有的 Python 版本外,如何在 Mac 上运行它?每次运行指定 Python 解释器版本(例如 python3.7 或 python3.5)似乎很容易出错。一定会有更好的方法。
_说明我知道这对经验丰富的 Python 开发人员没有意义但对当时的我来说是有意义的。我很乐意谈论为什么我仍然认为应该如此。_
### 安装和设置 pyenv
值得庆幸的是,**pyenv** 可以解决这一系列复杂性。首先,我需要安装 pyenv。我可以[从源码][8]自己克隆并编译它,但是我更喜欢通过 Homebrew 包管理器来管理软件包:
```
`$ brew install pyenv`
```
为了通过 pyenv 使用 Python 版本,必须了解 shell 的 PATH 变量。PATH 通过命令名称确定 shell 在哪里搜索文件。你必须确保 shell 程序能够找到 pyenv 运行的 Python 版本而不是默认安装的版本通常称为_系统版本_。如果不更改路径那么结果如下
```
$ which python
/usr/bin/python
```
这是 Python 的系统版本。
要正确设置 pyenv可以在 Bash 或 zsh 中运行以下命令:
```
`$ PATH=$(pyenv root)/shims:$PATH`
```
现在,如果你检查 Python 的版本,你会看到它是 pyenv 管理的版本:
```
$ which python
/Users/my_username/.pyenv/shims/python
```
该 export 语句PATH=)仅会对该 shell 实例进行更改,为了永久更改,你需要将它添加到 dotfile 中。由于 zsh 是 macOS 的默认 shell因此我将重点介绍它。将相同的语法添加到 **~/.zshrc** 文件中:
```
`$ echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.zshrc`
```
现在,每次我们在 zsh 中运行命令时,它将使用 pyenv 版本的 Python。请注意我在 **echo** 中使用了单引号,因此它不会评估和扩展命令。
.zshrc 文件仅管理 zsh 实例,因此请确保检查你的 shell 程序并编辑关联的 dotfile。如果需要再次检查默认 shell 程序,可以运行 **echo $SHELL**。如果是 zsh请使用上面的命令。如果你使用 Bash请将 **~/.zshrc** 更改为 **~/.bashrc**。如果您想了解更多信息可以在pyenv的自述文件中深入研究[path setting] [9]。
### 使用 pyenv 管理 Python 版本
现在 pyenv 已经可用,我们可以看到它只有系统 Python 可用:
```
$ pyenv versions
system
```
如上所述,你绝对不想使用此版本([阅读更多有关信息][10])。现在 pyenv 已正确设置,我希望它有我经常使用的几个不同版本的 Python。
有一种方法可以通过运行 **pyenv install --list** 来查看 pyenv 可以访问的所有不同仓库中的所有 Python 版本。这是一个很长的列表,将来可能会有所帮助。目前,我决定在 [Python 下载页面][11]找到的每个最新的“点版本”3.5.x 或 3.6.x其中 x 是最新的)。因此,我将安装 3.5.9 和 3.8.0
```
$ pyenv install 3.5.9
$ pyenv install 3.8.0
```
这将需要一段时间,因此休息一会(或阅读上面的链接之一)。有趣的是,输出遍历了该版本的 Python 的下载和构建。例如,输出显示文件直接来自 [Python.org][12]。
安装完成后,你可以设置默认值。我喜欢最新的,因此将全局默认 Python 版本设置为最新版本:
```
`$ pyenv global 3.8.0`
```
该版本立即在我的 shell 中设置完成。要确认:
```
$ python -V
Python 3.8.0
```
我要运行的项目仅适于 Python 3.5,因此我将在本地设置该版本并确认:
```
$ pyenv local 3.5.9
$ python -V
Python 3.5.9
```
因为我在 pyenv 中使用了 **local** 选项,所以它向当前目录添加了一个文件来跟踪该信息。
```
$ cat .python-version
3.5.9
```
现在,我终于可以为想要的项目设置虚拟环境,并确保运行正确版本的 Python。
```
$ python -m venv venv
$ source ./venv/bin/activate
(venv) $ which python
/Users/mbbroberg/Develop/my_project/venv/bin/python
```
要了解更多信息,请查看有关[在 Mac 上管理虚拟环境][13]的教程。
### 总结
默认情况下,运行多个 Python 版本可能是一个挑战。我发现 pyenv 可以确保在我需要时可以有我需要的 Python 版本。
你还有其他初学者或中级 Python 问题吗? 请发表评论,我们将在以后的文章中考虑它们。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/pyenv
作者:[Matthew Broberg][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/mbbroberg
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/search_find_code_python_programming.png?itok=ynSL8XRV (Searching for code)
[2]: https://opensource.com/article/19/4/managing-python-packages
[3]: https://opensource.com/article/19/5/api-evolution-right-way
[4]: https://semver.org/
[5]: https://t.co/yt1Z2439W8
[6]: https://twitter.com/dennyperez18/status/1133505310516232203?ref_src=twsrc%5Etfw
[7]: https://opensource.com/article/19/11/end-of-life-python-2
[8]: https://github.com/pyenv/pyenv
[9]: https://github.com/pyenv/pyenv#understanding-path
[10]: https://opensource.com/article/19/5/python-3-default-mac
[11]: https://www.python.org/downloads/
[12]: http://python.org
[13]: https://opensource.com/article/19/6/python-virtual-environments-mac

View File

@ -1,163 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (LazyWolfLin)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How I containerize a build system)
[#]: via: (https://opensource.com/article/20/4/how-containerize-build-system)
[#]: author: (Ravi Chandran https://opensource.com/users/ravichandran)
构建系统容器化指南
======
搭建一个通过容器分发应用的可复用系统可能很复杂,但这儿有个好方法。
![Containers on a ship on the ocean][1]
一个用于将源代码编译成可运行的应用的构建系统是由工具和流程共同组成。在编译过程中还涉及到代码从软件开发者流转到最终用户,无论最终用户是运维的同事还是部署的同事。
在使用容器搭建了一些构建系统后,我觉得有一个不错的可复用的方法值得分享。虽然这些构建系统被用于编译机器学习算法和为嵌入式硬件生成可加载的软件镜像上,但这个方法足够抽象,可用于任何基于容器的构建系统。
这个方法是关于通过简单和可维护的方式搭建或组织构建系统,但并不涉及处理特定编译器或工具容器化的技巧。它适用于软件开发人员构建软件并将可维护镜像交给其他技术人员(无论是系统管理员,运维工程师或者其他头衔)的常见情况。由于构建系统对于最终用户是透明的,因此他们能够专注于软件本身。
### 为什么要容器化构建系统?
搭建基于容器的可复用构建系统可以为软件团队带来诸多好处:
* **专注**我希望专注于应用的开发。当我调用一个名为“build”的工具时我希望这个工具集能生成一个随时可用的二进制文件。我不想浪费时间在构建系统的查错上。实际上我宁愿不了解也不关心构建系统。
* **一致的构建行为**:无论在哪种使用情况下,我都想确保整个团队使用相同版本的工具集并在构建时得到相同的结果。否则,我就得不断地处理“我这咋就是好的”的麻烦。在团队项目中,使用相同版本的工具集并对给定的输入源文件集产生一致的输出是非常重要。
* **易于部署和升级**:即使向每个人都提供一套详细说明来为项目安装工具集,也可能会有人翻车。问题可能是由于每个人对自己的 Linux 环境的个性化修改导致的。在团队中使用不同的 Linux 发行版(或者其他操作系统),情况可能还会变得更复杂。当需要将工具集升级到下一版本时,问题很快就会变得更糟糕。使用容器和本指南将使得新版本升级非常简单。
我在项目中容器化构建系统的经验显然很有价值,因为它可以缓解上述问题。我倾向于使用 Docker 作为容器工具,虽然在相对特殊的环境中安装和网络配置仍可能出现问题,尤其是当你在一个使用复杂代理的企业环境中工作时。但至少现在我需要解决的构建系统问题已经很少了。
### 漫步容器化的构建系统
我创建了一个[教程存储库][2],随后你可以 clone 并检查它,或者按照本文内容进行操作。我将逐个介绍存储库中的文件。这个构建系统非常简单(它使用**gcc**)从而可以专注于构建系统结构上。
### 构建系统需求
我认为构建系统中有两个关键点:
* **标准化构建调用**:我希望能够指定一些形如 **/path/to/workdir** 的工作目录来构建代码。我希望以如下形式调用构建:
./build.sh /path/to/workdir
为了使得示例的结构足够简单(以便说明),我将假定输出也在 **/path/to/workdir** 路径下的某处生成。(否则,将增加容器中显示的卷的数量,虽然这并不困难,但解释起来比较麻烦。)
* **通过 shell 自定义构建调用**:有时,工具集会以出乎意料的方式被调用。除了标准的工具集调用 **build.sh** 之外,如果需要还可以为 **build.sh** 添加一些选项。但我一直希望能够有一个可以直接调用工具集命令的 shell。在这个简单的示例中有时我想尝试不同的 **gcc** 优化选项并查看效果。为此,我希望调用:
./shell.sh /path/to/workdir
这将让我得到一个容器内部的 Bash shell并且可以调用工具集和访问我的**工作目录 workdir**,从而我可以根据需要尝试使用这个工具集。
### 构建系统架构
为了满足上述基本需求,这是我的构架系统架构:
![Container build system architecture][3]
在底部的 **workdir** 代表软件开发者用于构建的任意软件源码。通常,这个 **workdir** 是一个源代码的存储库。在构建之前,最终用户可以通过任何方式来操纵这个存储库。例如,如果他们使用 **git** 作为版本控制工具的话,可以使用 **git checkout** 切换到他们正在工作的功能分支上并添加或修改文件。这样可以使得构建系统独立于 **workdir** 之外。
顶部的三个模块共同代表了容器化的构建系统。最左边的黄色模块代表最终用户与构建系统交互的脚本(**build.sh** 和 **shell.sh**)。
在中间的红色模块是 Dockerfile 和相关的脚本 **build_docker_image.sh**。开发者(在这个例子中指我)通常将执行这个脚本并生成容器镜像(事实上我多次执行它直到一切正常为止,但这是另一个故事)。然后我将镜像分发给最终用户,例如通过 container trusted registry 进行分发。最终用户将需要这个镜像。另外,他们将 clone 构建系统存储库(即一个与[教程存储库][2]等效的存储库)。
当最终用户调用 **build.sh** 或者 **shell.sh** 时,容器内将执行右边的 **run_build.sh** 脚本。接下来我将详细解释这些脚本。这里的关键是最终用户不需要为了使用而去了解任何关于红色或者蓝色模块或者容器工作原理的知识。
### 构建系统细节
把教程存储库的文件结构映射到这个系统结构上。我曾将这个原型结构用于相对复杂构建系统,因此它的简单并不会造成任何限制。下面我列出存储库中相关文件的树结构。文件夹 **dockerize-tutorial** 能用构建系统的其他任何名称代替。在这个文件夹下,我用 **workdir** 的路径作参数调用 **build.sh****shell.sh**
```
dockerize-tutorial/
├── build.sh
├── shell.sh
└── swbuilder
    ├── build_docker_image.sh
    ├── install_swbuilder.dockerfile
    └── scripts
        └── run_build.sh
```
请注意,我上面特意没列出 **example_workdir**,你能在教程存储库中找到。实际的源码通常存放在单独的存储库中,而不是构建工具库中的一部分;本教程为了不必处理两个存储库,所以我将它包含在这个存储库中。
如果你只对概念感兴趣,本教程并非必须的,因为我将解释所有文件。但是如果你继续本教程(并且已经安装 Docker首先使用以下命令来构建容器镜像 **swbuilder:v1**
```
cd dockerize-tutorial/swbuilder/
./build_docker_image.sh
docker image ls  # resulting image will be swbuilder:v1
```
然后调用 **build.sh**
```
cd dockerize-tutorial
./build.sh ~/repos/dockerize-tutorial/example_workdir
```
下面是 [build.sh][4] 的代码。这个脚本从容器镜像 **swbuilder:v1** 实例化一个容器。而这个容器实例映射了两个卷:一个将文件夹 **example_workdir** 挂载到容器内部路径 **/workdir** 上,第二个则将容器外的文件夹 **dockerize-tutorial/swbuilder/scripts** 挂载到容器内部路径 **/scripts** 上。
```
docker container run                              \
    --volume $(pwd)/swbuilder/scripts:/scripts    \
    --volume $1:/workdir                          \
    --user $(id -u ${USER}):$(id -g ${USER})      \
    --rm -it --name build_swbuilder swbuilder:v1  \
    build
```
另外,**build.sh** 还会用你的用户名(以及组,本教程假设两者一致)去运行容器,以便在访问构建输出时不出现文件权限问题。
请注意,[**shell.sh**][5] 和 **build.sh** 大体上是一致的,除了两点不同:**build.sh** 会创建一个名为 **build_swbuilder** 的容器,而 **shell.sh** 则会创建一个名为 **shell_swbuilder** 的容器。这样一来,当其中一个脚本运行时另一个脚本被调用也不会产生冲突。
两个脚本之间的另一处关键不同则在于最后一个参数:**build.sh** 传入参数 **build****shell.sh** 则传入 **shell**。如果你看了用于构建容器镜像的 [Dockerfile][6],就会发现最后一行包含了下面的 **ENTRYPOINT** 语句。这意味着上面的 **docker container run** 调用将使用 **build****shell** 作为唯一的输入参数来执行 **run_build.sh** 脚本。
```
# run bash script and process the input command
ENTRYPOINT [ "/bin/bash", "/scripts/run_build.sh"]
```
[**run_build.sh**][7] 使用这个输入参数来选择启动 Bash shell 还是调用 **gcc** 来构建 **helloworld.c** 项目。一个真正的构建系统通常会使用 Makefile 而非直接运行 **gcc**
```
cd /workdir
if [ $1 = "shell" ]; then    
    echo "Starting Bash Shell"
    /bin/bash
elif [ $1 = "build" ]; then
    echo "Performing SW Build"
    gcc helloworld.c -o helloworld -Wall
fi
```
在使用时,如果你需要传入多个参数,当然也是可以的。我处理过的构建系统,构建通常是对给定的项目调用 **make**。如果一个构建系统有非常复杂的构建调用,则你可以让 **run_build.sh** 调用 **workdir** 下最终用户编写的特定脚本。
### 关于 scripts 文件夹的说明
你可能想知道为什么 **scripts** 文件夹位于目录树深处而不是位于存储库的顶层。两种方法都是可行的,但我不想鼓励最终用户到处乱翻并修改里面的脚本。将它放到更深的地方是一个让他们更难乱翻的方法。另外,我也可以添加一个 **.dockerignore** 文件去忽略 **scripts** 文件夹,因为它不是容器必需的部分。但因为它很小,所以我没有这样做。
### 简单而灵活
尽管这一方法很简单,但我将其用于某些非常特殊的构建系统时,发现它其实非常灵活。相对稳定的部分(例如,一年仅修改数次的给定工具集)被固定在容器镜像内。较为灵活的部分则以脚本的形式放在镜像外。这使我能够简单地通过修改脚本并将更改推送到构建系统存储库来修改调用工具集的方式。用户所需要做的是将更改拉到本地的构建系统存储库中,这通常是非常快的(与更新 Docker 镜像不同)。这种结构使其能够拥有尽可能多的卷和脚本,同时使最终用户摆脱复杂性。
你将如何修改你的应用来针对容器化环境进行优化呢?
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/how-containerize-build-system
作者:[Ravi Chandran][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/LazyWolfLin)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/ravichandran
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_2015-3-osdc-lead.png?itok=O6aivM_W (Containers on a ship on the ocean)
[2]: https://github.com/ravi-chandran/dockerize-tutorial
[3]: https://opensource.com/sites/default/files/uploads/build_sys_arch.jpg (Container build system architecture)
[4]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/build.sh
[5]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/shell.sh
[6]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/swbuilder/install_swbuilder.dockerfile
[7]: https://github.com/ravi-chandran/dockerize-tutorial/blob/master/swbuilder/scripts/run_build.sh

View File

@ -0,0 +1,125 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to Handle Automatic Updates in Ubuntu)
[#]: via: (https://itsfoss.com/auto-updates-ubuntu/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
如何在 Ubuntu 中处理自动更新
======
_**简介:本教程教你如何处理无人值守的升级,即 Ubuntu Linux 的自动系统更新。**_
有时,当你尝试[关闭 Ubuntu 系统][1]时,可能看到这个阻止你关闭的页面:
**关机正在进行无人值守升级,请不要关闭计算机。**
![Unattended Upgrade In Progress In Ubuntu][2]
你可能想知道什么是“无人值守的升级”,以及它是如何在你不知情的情况下运行的。
因为 [Ubuntu][3] 非常重视系统的安全性。默认情况下,它会每天自动检查系统更新,如果发现任何安全更新,那么会下载这些更新并自行安装。对于正常的系统和应用更新,它会通过软件更新程序通知你。
由于所有这些都是在后台发生的,因此你会直到关机或者尝试自己安装应用时才会意识到。
在进行这些无人值守的升级时尝试安装新软件会发生[无法获得锁的错误][4]。
![][5]
如你所见,自动更新带来了一些小麻烦。你可以选择禁用自动更新,但这意味着你必须一直手动检查并[更新你的 Ubuntu 系统][6]。
你真的需要禁用自动更新吗?
请注意这是一项安全功能。Linux 实际上允许你禁用系统中的所有功能,甚至禁用这些安全功能。
但是我认为作为普通用户_**你不应禁用自动更新**_。毕竟它可以确保你的系统安全。
为了确保系统的安全性,你可以忍受自动更新所带来的小麻烦。
现在,你已经收到警告,并认为最好承担手动更新系统的额外任务,让我们看看如何处理自动更新。
与往常一样有两种方法可以做到GUI 和命令行。 我将向您=你展示两种方法。
我在这里使用 Ubuntu 20.04,但是这些步骤对 Ubuntu 18.04 和任何其他 Ubuntu 版本均有效。
### 方法 1以图形方式禁用 Ubuntu 中的自动更新
进入菜单并查找“软件和更新”工具。
![Software & Updates Settings][7]
在此处,进入“更新”选项卡。查找“自动检查更新”。默认情况下,它设置为“每日”。
你可以将其更改为“从不”,你的系统将永远不会检查更新。如果不检查更新,它将不会找到要安装的新更新。
![Disable Auto Updates in Ubuntu Completely][8]
如果这样做,那么必须不时手动更新系统。但是,这是额外的工作,你可能不会一直记得。
#### 在 Ubuntu 中处理自动更新的更好方法
就个人而言,我建议让它自己检查更新。如果你不希望它自动安装更新,那么可以更改该行为以通知有关安全更新的可用性。
保持“自动检查更新”为“每日”,然后将“有安全更新时”选项更改为“立即显示”,而不是“自动下载并安装”。
![Get notified for security updates instead of automatically installing them][9]
这样,它会检查是否有更新,而不是在后台自动安装更新,软件更新程序会通知你更新可用于系统。你的系统已经完成正常的系统和软件更新。
![Get notified about security updates][10]
使用此设置,关闭系统时将不会看到“正在进行的无人值守升级”。但是,由于两个不同的进程无法同时使用 apt 包管理器,因此你仍然可能会遇到“无法锁定”错误。
我相信这是一个更好的解决方案,你不认为是么?
如我承诺的同时有 GUI 和命令行方法一样,让我向你展示如何在终端中禁用无人值守的升级。
### 如何在 Ubuntu 中使用命令行禁用自动更新
你可以在 **/etc/apt/apt.conf.d/20auto-upgrades** 中找到自动升级设置。Ubuntu 终端中的默认文本编辑器是 Nano因此你可以使用以下命令来编辑此文件
```
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
```
现在,如果你不希望系统自动检查更新,那么可以将 APT::Periodic::Update-Package-Lists 的值更改为 0。
```
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Unattended-Upgrade "0";
```
如果你希望它检查更新但不自动安装无人值守的升级,那么可以选择将其设置为:
```
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "0";
```
**最后**
由于某种原因,启用了自动安全更新,建议你保持这种状态。小的烦恼实际上并不值得冒险损害系统安全性。你怎么看?
--------------------------------------------------------------------------------
via: https://itsfoss.com/auto-updates-ubuntu/
作者:[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/schedule-shutdown-ubuntu/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/unattended-upgrade-in-progress-in-ubuntu.png?ssl=1
[3]: https://ubuntu.com/
[4]: https://itsfoss.com/could-not-get-lock-error/
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/12/Could_not_get_lock.jpg?ssl=1
[6]: https://itsfoss.com/update-ubuntu/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/software-updates-settings-ubuntu-20-04.jpg?ssl=1
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/04/disable-auto-updates-ubuntu.jpg?ssl=1
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/04/handle-auto-updates-ubuntu.jpg?ssl=1
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/04/updates-available-ubuntu.png?ssl=1

View File

@ -0,0 +1,159 @@
[#]: collector: (lujun9972)
[#]: translator: (HankChow)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (5 ways to split your Linux terminal)
[#]: via: (https://opensource.com/article/20/5/split-terminal)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
5 种拆分 Linux 终端的方法
======
> 本文介绍了 Linux 提供的拆分终端的方法,它能够帮助你完成多任务工作。那么,你最喜欢哪一款终端复用工具呢?
![4 different color terminal windows with code][1]
没有什么问题是不能用一个 Linux 终端解决的,如果不行,那就用两个。
很早以前,[终端其实是一个物理设备][2],而现在的终端实际上是在计算机上被模拟出来的一个应用程序。当你使用终端和计算机进行交互的时候,就会发现,只打开一个终端是不够用的。在进行编译、数据处理等长时间任务的时候,你不得不打开一个新终端或新<ruby>选项卡<rt>tab</rt></ruby>来同时进行其它工作。
如果你是系统管理员,你就需要更多的终端窗口,以便连接到多个不同的主机上并行工作了。
在 Linux 系统中,终端应用程序在很久之前已经开始带有选项卡功能了。而现在的终端应用程序里,选项卡已经是标配功能了,这是非常流行的趋势。尽管如此,工作的时候在多个选项卡之间来回切换,或多或少也会分散我们的注意力,甚至带来不便。
而最好的解决方案就是将整个屏幕划分为多个部分这样多个终端就可以在同一个终端应用程序窗口中同时存在。Linux 套件中也有很多相关的工具可以实现这一功能。
### Shell、终端和控制台
在此之前,我们首先要明确 Shell、<ruby>终端<rt>terminal</rt></ruby><ruby>控制台<rt>console</rt></ruby>这三个概念。想要详细了解的话,请参阅 [Enable Sysadmin][2] 博客上的相关文章。
太长不看版:
* Shell 是带有<ruby>命令提示符<rt>prompt</rt></ruby>的用于输入、输出的界面。准确地说,[POSIX][3] 桌面底层也运行着一个 Shell无论这个 Shell 是否对用户可见,因为用户会话就是由这个 Shell 启动的。
* 终端是在图形界面服务器(例如 X11 或 Wayland中运行的应用程序其中加载了一个 Shell。只有在终端窗口启动之后才算是运行了一个终端。终端可以认为是操作 Shell 的一个入口。
* 控制台(或称“虚拟控制台”)通常表示在桌面环境以外使用的 Shell你可以通过 `Alt+Ctrl+F2` 进入控制台,通常情况下从 `F3``F7` 都是不同的控制台,其中桌面环境有可能是 `F1` 或者 `F7`,这在不同的发行版中可能会有所不同。
因此,一些应用程序提供的功能是拆分 Shell 或者控制台,一些应用程序的功能则是拆分终端。
### tmux
![tmux terminal][4]
[tmux][5] 可以说是最灵活最强大的屏幕拆分工具了,它通过键盘控制对多个终端的复用,因此你可以将一个控制台叠放在另一个控制台上面,并在两个控制台之间切换。你还可以将整个屏幕等分为多个控制台,以便同时观察不同控制台上的状况。
tmux 的所有操作都是通过键盘完成的,这就意味着你的手不需要离开键盘去寻找鼠标。为此,你需要记住一些按键组合。
如果你只用 tmux 来做屏幕拆分,那你只需要记住一下这些命令:
* `Ctrl-B %` 竖直拆分屏幕(两个 Shell 分别位于左右)
* `Ctrl-B "` 水平拆分屏幕(两个 Shell 分别位于上下)
* `Ctrl-B O` 切换到另一个 Shell
* `Ctrl-B ?` 查看帮助
* `Ctrl-B d` 断开 tmux 并让其在后台运行(可以使用 `tmux attach` 重新进入)
tmux 的一大好处是,在一台计算机上启动 tmux 会话之后也可以从另一台计算机上进入到这个会话由此可以看出tmux 对 Shell 进行了<ruby>守护<rt>daemonize</rt></ruby>
例如,当我在树莓派上运行 tmux我就可以从计算机上连接到树莓派并登录 IRC当我断开连接时树莓派上的 tmux 会继续运行,并等待我的下一次连接,在此期间 IRC 是处于持续登录状态的。
### GNU Screen
![GNU Screen terminal][6]
[GNU Screen][7] 也是一个 Shell 复用工具,类似于 tmux你可以在断开一个活动会话后重连到其中它也支持竖直或水平拆分屏幕。
Screen 的灵活性比 tmux 要弱一些。它默认的绑定按键组合是 `Ctrl-A`,和 Bash 中光标移动到行首的快捷键是一样的。因此,当你正在运行 Screen 的时候,如果想要将光标移动到行首,就需要多按一次 `Ctrl-A`。而我自己的做法是,在 `$HOME/.screenrc` 文件中将绑定按键组合重新设置为 `Ctrl-J`
```
`escape ^jJ`
```
尽管 Screen 在屏幕拆分功能上做得很好,但 tmux 上的一些缺点在 Screen 上也同样存在。例如在拆分 Shell 时,新的 Shell 不会在一个新的面板中启动,而是需要使用 `Ctrl-A Tab` 导航到另一个空间(如果你按照我的方式重新设置了按键组合,需要对应地把 `Ctrl-A` 改为 `Ctrl-J`),然后通过 `Ctrl-A C` 手动创建一个新的 Shell。
和 tmux 不同的是Screen 在推出一个 Shell 的时候,屏幕拆分状态不会改变,这样的设计在某些情况下是比较适合的,但麻烦之处在于需要手动管理屏幕拆分状态。
尽管如此Screen 还是一个相当可靠灵活的应用程序,在无法使用 tmux 的时候,你可以选择 Screen 作为备选方案。
在默认按键方案下Screen 常用的基本命令包括:
* `Ctrl-A |` 竖直拆分屏幕(两个 Shell 分别位于左右)
* `Ctrl-A S` 水平拆分屏幕(两个 Shell 分别位于上下)
* `Ctrl-A Tab` 切换到另一个 Shell
* `Ctrl-A ?` 查看帮助
* `Ctrl-A d` 断开 Screen 并让其在后台运行(可以使用 `screen -r` 重新进入)
### Konsole
![Konsole screen][8]
[Konsole][9] 是 KDE Plasma 桌面使用的终端应用程序。和 KDE 一样Konsole 也以高度可定制、功能强大的特点而著称。
和 tmux、GNU Screen 类似Konsole 也具有拆分屏幕的功能。由于 Konsole 是图形界面的终端,因此还可以用鼠标来控制它的屏幕拆分。
Konsole 的屏幕拆分功能在“<ruby>查看<rt>View</rt></ruby>”菜单中。它也支持竖直和水平方向的拆分,只要点击鼠标就可以切换到另一个面板上。每个面板都是一个独立的终端,因此都可以拥有独立的主题和标签页。
Konsole 和 tmux、GNU Screen 最大的不同之处在于不能断开和重新连接 Konsole。除非使用远程桌面软件否则只能在打开 Konsole 时使用,这一点和大多数图形界面应用程序是一样的。
### Emacs
![Emacs rpg][10]
严格来说Emacs 并不算是一个终端复用工具,但它的使用界面支持拆分和调整大小,同时还带有一个内建的终端。
如果 Emacs 是你日常使用的文本编辑器,你就可以在不关闭编辑器的情况下,在不同的应用程序之间轻松互相切换。由于 Emacs eshell 模块是通过 eLISP 实现的,因此你可以在 Emacs 中使用相同的命令进行交互,让一些繁琐的操作变得更为简单。
如果你是在图形界面中使用 Emacs还可以使用鼠标进行操作。例如通过点击切换面板、用鼠标调整拆分屏幕的的大小等等。尽管如此键盘的操作速度还是更快因此记住一些键盘快捷键还是很有必要的。
Emacs 的一些重要快捷键包括:
* `Ctrl-X 3` 竖直拆分屏幕(两个 Shell 分别位于左右)
* `Ctrl-X 2` 水平拆分屏幕(两个 Shell 分别位于上下)
* `Ctrl-X O` 切换到另一个 Shell你也可以使用鼠标操作
* `Ctrl-X 0` 关闭当前面板
如果你运行了 emacs-client 的话,就可以像 tmux 和 GNU Screen 一样断开和重新连接到 Emacs 了。
### Window manager
![Ratpoison split screen][11]
除了文本编辑器之外,一些 Linux 桌面也同样具有拆分屏幕、加载终端这样的功能。例如 [Ratpoison][12]、[Herbsluftwm][13]、i3、Awesome甚至是启用了特定设置的 KDE Plasma 桌面,都可以将多个应用程序在桌面上分块显示。
这些桌面可以让各个应用程序占据屏幕的固定位置,而不是逐个叠放在一起,因此你可以在多个应用程序窗口之间轻松切换。你还可以打开多个终端,以达到终端复用的目的。更进一步,你还可以在桌面复用工具中加载终端复用工具。
And there's nothing stopping you from loading Emacs with split buffers inside of that. No one knows what happens if you take it further than that, and most Linux users agree it's best not to find out.
和 tmux、GNU Screen 不同,你在断开与桌面的连接后无法重新连接到同一个桌面会话,除非你使用了远程桌面软件进行连接。
### 更多选择
除了上面介绍到的工具以外,还有诸如 [Tilix][14]、Terminator 这样的终端模拟器,它们同样可以实现屏幕拆分、嵌入终端组件等功能。欢迎在评论区分享你喜欢的终端拆分工具。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/5/split-terminal
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[HankChow](https://github.com/HankChow)
校对:[校对者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/freedos.png?itok=aOBLy7Ky (4 different color terminal windows with code)
[2]: https://www.redhat.com/sysadmin/terminals-shells-consoles
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
[4]: https://opensource.com/sites/default/files/uploads/terminal-split-tmux2.png (tmux terminal)
[5]: https://github.com/tmux/tmux
[6]: https://opensource.com/sites/default/files/uploads/terminal-split-screen.png (GNU Screen terminal)
[7]: https://www.gnu.org/software/screen/
[8]: https://opensource.com/sites/default/files/uploads/konsole.jpg (Konsole screen)
[9]: https://konsole.kde.org
[10]: https://opensource.com/sites/default/files/uploads/emacs-rpg_0.jpg (Emacs rpg)
[11]: https://opensource.com/sites/default/files/uploads/advent-ratpoison-split_0.jpg (Ratpoison split screen)
[12]: https://opensource.com/article/19/12/ratpoison-linux-desktop
[13]: https://opensource.com/article/19/12/herbstluftwm-linux-desktop
[14]: https://gnunn1.github.io/tilix-web/