mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-03 23:40:14 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
0c0f678b47
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12279-1.html)
|
||||
[#]: subject: (How to Execute a Command or Script at Reboot or Startup)
|
||||
[#]: via: (https://www.2daygeek.com/execute-run-linux-scripts-command-at-reboot-startup/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
@ -10,31 +10,29 @@
|
||||
如何在重启或启动时执行命令或脚本
|
||||
======
|
||||
|
||||
总所周知 Linux 可以在启动时添加服务。
|
||||
![](https://img.linux.net.cn/data/attachment/album/202006/04/091837g664qu0y206aqoo9.jpg)
|
||||
|
||||
例如,如果要在**[启动时添加][1]** Apache Httpd 服务,你可以在 chkconfig 和 systemctl 命令的帮助下完成此操作。
|
||||
众总所周知 Linux 可以在启动时添加服务。例如,如果要在[启动时添加][1] Apache Httpd 服务,你可以在 `chkconfig` 和 `systemctl` 命令的帮助下完成此操作。
|
||||
|
||||
有时你需要在启动时添加自定义脚本、命令或服务,该怎么做?
|
||||
|
||||
你可以使用以下三种方法来做到。
|
||||
有时你需要在启动时添加自定义脚本、命令或服务,该怎么做?你可以使用以下三种方法来做到。
|
||||
|
||||
在本文中,我们将通过示例向你展示如何使用这些方法。
|
||||
|
||||
### 方法 1:如何使用 /etc/rc.d/rc.local 文件在重启或启动时运行脚本或命令
|
||||
|
||||
传统上,**“/etc/rc.local”** 文件是在切换到多用户运行级别的过程结束时启动所有正常的计算机服务之后执行的。
|
||||
传统上,`/etc/rc.local` 文件是在切换到多用户运行级别的过程结束时,在所有正常的计算机服务启动之后执行的。
|
||||
|
||||
此方法也适用于 systemd 系统。
|
||||
|
||||
你需要将脚本位置添加到 “/etc/rc.d/rc.local” 文件中以在启动时运行。
|
||||
你需要将你的脚本位置添加到 `/etc/rc.d/rc.local` 文件中以在启动时运行。
|
||||
|
||||
确保文件有运行权限。
|
||||
确保该文件有运行权限:
|
||||
|
||||
```
|
||||
# chmod +x /etc/rc.d/rc.local
|
||||
```
|
||||
|
||||
为了演示,我们将创建一个简单的示例脚本。你可以根据需要创建任何脚本。
|
||||
作为演示,我们将创建一个简单的示例脚本。你可以根据需要创建任何脚本。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/run-script-on-boot.sh
|
||||
@ -44,13 +42,13 @@ date > /root/on-boot-output.txt
|
||||
hostname > /root/on-boot-output.txt
|
||||
```
|
||||
|
||||
脚本完成后,设置可执行权限。
|
||||
脚本完成后,设置可执行权限:
|
||||
|
||||
```
|
||||
# chmod +x /opt/scripts/run-script-on-boot.sh
|
||||
```
|
||||
|
||||
最后,将该脚本添加到文件底部。
|
||||
最后,将该脚本添加到文件底部:
|
||||
|
||||
```
|
||||
# vi /etc/rc.d/rc.local
|
||||
@ -58,7 +56,7 @@ hostname > /root/on-boot-output.txt
|
||||
/opt/scripts/run-script-on-boot.sh
|
||||
```
|
||||
|
||||
**[重启系统][2]**进行检查。
|
||||
[重启系统][2]进行检查:
|
||||
|
||||
```
|
||||
# reboot
|
||||
@ -66,17 +64,11 @@ hostname > /root/on-boot-output.txt
|
||||
|
||||
### 方法 2:如何使用 crontab 在重启或启动时执行命令或脚本
|
||||
|
||||
cron 在特定时间在后台自动执行计划的作业。
|
||||
cron 在特定时间在后台自动执行计划的作业。可以在 [cron 任务][3]中使用特殊的字符串 `@reboot` 来完成。`@reboot` 是一个特殊的字符串,它允许用户在启动时运行任何命令或脚本。
|
||||
|
||||
可以在 **[cron 任务][3]**中使用特殊的字符串 **“@reboot”** 来完成。
|
||||
此示例在系统重启时运行 `/opt/scripts/run-script-on-boot.sh` 文件。我们将使用与上面相同的脚本。
|
||||
|
||||
@reboot 是一个特殊的字符串,它允许用户在启动时运行任何命令或脚本。
|
||||
|
||||
此示例在系统重启时运行 “/opt/scripts/run-script-on-boot.sh” 文件。
|
||||
|
||||
我们将使用与上面相同的脚本。
|
||||
|
||||
为此,只需在 crontab 文件中添加以下条目。
|
||||
为此,只需在 crontab 文件中添加以下条目:
|
||||
|
||||
```
|
||||
# crontab -e
|
||||
@ -84,7 +76,7 @@ cron 在特定时间在后台自动执行计划的作业。
|
||||
@reboot /opt/scripts/run-script-on-boot.sh
|
||||
```
|
||||
|
||||
重启系统进行检查。
|
||||
重启系统进行检查:
|
||||
|
||||
```
|
||||
# reboot
|
||||
@ -96,9 +88,9 @@ cron 在特定时间在后台自动执行计划的作业。
|
||||
|
||||
我们将使用上面相同的脚本进行演示。
|
||||
|
||||
为此,你需要创建一个 systemd 启动脚本并将其放在 **”/etc/systemd/system/“** 目录中。
|
||||
为此,你需要创建一个 systemd 启动脚本并将其放在 `/etc/systemd/system/` 目录中。
|
||||
|
||||
这是我们的示例 systemd 启动单元脚本。
|
||||
这是我们的示例 systemd 启动单元脚本:
|
||||
|
||||
```
|
||||
# vi sample-on-boot-script.service
|
||||
@ -114,28 +106,28 @@ ExecStart=/opt/scripts/run-script-on-boot.sh
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
将单元脚本放置在 systemd 所在位置后,运行以下命令更新 systemd 配置文件并启用服务。
|
||||
将单元脚本放置在 systemd 所在位置后,运行以下命令更新 systemd 配置文件并启用服务:
|
||||
|
||||
```
|
||||
# systemctl daemon-reload
|
||||
# systemctl enable sample-on-boot-script.service
|
||||
```
|
||||
|
||||
重启系统进行检查。
|
||||
重启系统进行检查:
|
||||
|
||||
```
|
||||
# reboot
|
||||
```
|
||||
|
||||
### 额外提示:
|
||||
### 额外提示
|
||||
|
||||
如果你想在后台运行脚本,你需要在最后加上 “&” 符号
|
||||
如果你想在后台运行脚本,你需要在最后加上 `&` 符号
|
||||
|
||||
```
|
||||
/Path/To/My_Script &
|
||||
```
|
||||
|
||||
如果你想以不同用户运行命令,使用以下格式。
|
||||
如果你想以不同用户运行命令,使用以下格式:
|
||||
|
||||
```
|
||||
su - $USER -c /Path/To/My_Script
|
||||
@ -148,7 +140,7 @@ via: https://www.2daygeek.com/execute-run-linux-scripts-command-at-reboot-startu
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,99 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Devuan Beowulf 3.0 is the Latest Stable Release Based on Debian 10.4 Buster (and Free From systemd))
|
||||
[#]: via: (https://itsfoss.com/devuan-3-release/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Devuan Beowulf 3.0 is the Latest Stable Release Based on Debian 10.4 Buster (and Free From systemd)
|
||||
======
|
||||
|
||||
[Devuan GNU+Linux][1] is a fork of [Debian][2] without [systemd][3]. If you are wondering what’s wrong with systemd — that’s a discussion for another day.
|
||||
|
||||
But, if you are someone who wanted a systemd-free Linux distribution, the release of Devuan Beowulf 3.0 should be good news for you.
|
||||
|
||||
### Devuan Beowulf 3.0: What’s New?
|
||||
|
||||
![][4]
|
||||
|
||||
Devuan is normally appreciated for providing alternative [init][5] software such as [SysV][6].
|
||||
|
||||
In this article, we’ll take a look at the key highlights in Devuan Beowulf 3.0.
|
||||
|
||||
#### Based on Debian 10.4 Buster
|
||||
|
||||
[Debian 10 Buster][7] is undoubtedly an impressive series of releases while Debian 10.4 being the latest.
|
||||
|
||||
And, with Devuan Beowulf 3.0, you’ll be happy to know that the release is based on the latest Debian 10.4 Buster update.
|
||||
|
||||
In case you aren’t aware of it, you may check out the [official announcement post for Debian 10.4 Buster][8] release to know more about it.
|
||||
|
||||
#### Linux Kernel 4.19
|
||||
|
||||
It’s also a great addition to have [Linux Kernel 4.19 LTS][9] baked in the latest release.
|
||||
|
||||
Of course, not the latest because we are in ‘Debian land’ and things are not always latest here but more stable. The new kernel should fix several issues that you may have had with previous releases.
|
||||
|
||||
#### Support For ppc64el Architecture
|
||||
|
||||
The support for [ppc64el][10] may not be a big deal for the most part — but having the support for PowerPC and Power ISA processors is a plus.
|
||||
|
||||
Not to forget, Devuan GNU+Linux already supports i386, amd64, armel, armhf and arm64 architectures.
|
||||
|
||||
#### Added runit & OpenRC as optional alternative
|
||||
|
||||
To consider more init software alternatives, [runit][11] and [openrc][12] is now an option in the latest release.
|
||||
|
||||
#### Other Changes
|
||||
|
||||
In addition to the key highlights mentioned above, you will also find the addition of standalone daemons [eudev][13] and [elogind][14].
|
||||
|
||||
The boot screen, the display manager and the desktop theming also includes subtle changes. For example, the boot menu says “**Debian**” instead of “**Devuan**“.
|
||||
|
||||
You might want to look the [official release notes][15] if you want more technical details on the changes with Devuan Beowulf 3.0.0.
|
||||
|
||||
Trivia
|
||||
|
||||
Devuan releases are named after minor planets. Beowulf is a [minor planet numbered 38086][16].
|
||||
|
||||
### Wrapping Up
|
||||
|
||||
The latest stable release of Devuan Beowulf 3.0 counts as good progress with systemd-free distributions available out there.
|
||||
|
||||
If you want to support Devuan project, please make some [contribution to their project either financially][17] or [by other means][18].
|
||||
|
||||
What do you think about this release? Feel free to let me know what you think in the comments below!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/devuan-3-release/
|
||||
|
||||
作者:[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://devuan.org
|
||||
[2]: https://www.debian.org
|
||||
[3]: https://en.wikipedia.org/wiki/Systemd
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/06/devuan-beowulf.jpg?ssl=1
|
||||
[5]: https://en.wikipedia.org/wiki/Init
|
||||
[6]: https://wiki.archlinux.org/index.php/SysVinit
|
||||
[7]: https://itsfoss.com/debian-10-buster/
|
||||
[8]: https://www.debian.org/News/2020/20200509
|
||||
[9]: https://itsfoss.com/linux-kernel-4-19-lts-release/
|
||||
[10]: https://en.wikipedia.org/wiki/Ppc64
|
||||
[11]: https://en.wikipedia.org/wiki/Runit
|
||||
[12]: https://en.wikipedia.org/wiki/OpenRC
|
||||
[13]: https://wiki.gentoo.org/wiki/Eudev
|
||||
[14]: https://wiki.gentoo.org/wiki/Elogind
|
||||
[15]: https://files.devuan.org/devuan_beowulf/Release_notes.txt
|
||||
[16]: https://en.wikipedia.org/wiki/Meanings_of_minor_planet_names:_38001%E2%80%9339000#086
|
||||
[17]: https://devuan.org/os/donate
|
||||
[18]: https://dev1galaxy.org/viewtopic.php?pid=1380#p1380
|
@ -0,0 +1,86 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 common open source testing myths debunked)
|
||||
[#]: via: (https://opensource.com/article/20/6/open-source-testing-myths)
|
||||
[#]: author: (Kevin Dunne https://opensource.com/users/kdunne916)
|
||||
|
||||
5 common open source testing myths debunked
|
||||
======
|
||||
These survey results paint a picture of the bright future of open source
|
||||
testing.
|
||||
![Collaboration on a mobile software design][1]
|
||||
|
||||
Open source tools are constantly changing the landscape of testing, and the community around these tools is bigger and more vocal than ever.
|
||||
|
||||
The first-ever _[State of Open Source Testing Survey][2]_ examines the latest trends and developments across the software development industry. This survey received over 2,000 responses from practitioners across the behavior-driven development, functional testing, and load testing domains.
|
||||
|
||||
The survey reveals a great deal about software testing and how it uses open source, and based on the results, it's reasonable to expect an increased rate of adoption and deployment of open source tools.
|
||||
|
||||
Importantly, the survey results also debunk some of the common myths around open source and software testing. Here's a look at the top five:
|
||||
|
||||
### Myth #1: The biggest impediment to using open source testing tools are the skills required.
|
||||
|
||||
There is undoubtedly a large jump in technical skill sets required to use open source testing tools, and typically a need to brush up on or learn new coding skills. However, while 40% of respondents did cite the lack of technical skills as one of their largest roadblocks, the most common roadblock cited was simply lack of time to learn new tools.
|
||||
|
||||
![OS testing impediments][3]
|
||||
|
||||
### Myth #2: Open source testing happens mostly in English-speaking countries.
|
||||
|
||||
Of all respondents to the survey, 61% are in Asia. While many have believed that Agile and DevOps are making co-located work more essential, the significant number of respondents in countries like India, Vietnam, and the Philippines says otherwise. There's a possibility that the rise of remote work and distributed teams will continue to grow the importance of multilingual support for projects and more adoption of asynchronous communication practices.
|
||||
|
||||
![OS testing offshore][4]
|
||||
|
||||
### Myth 3: Open source tools are only used for cost savings.
|
||||
|
||||
Sure, the largest reason for using open source testing tools stated was cost (39%). However, the overwhelming majority of respondents (61%) cited other primary reasons for leveraging open source tools, including community support, better integration, and more ability to customize to their liking. Simply put, the choice to use open source is not a purely economic one.
|
||||
|
||||
![OS testing benefits][5]
|
||||
|
||||
### Myth #4: Quality Assurance Engineering is no longer a career because developers write their own tests.
|
||||
|
||||
An overwhelming majority (84%) of organizations surveyed still had dedicated testing and QA personnel contributing to the creation of functional automated tests against their applications. Only a small percentage (8%) left those tasks completely up to developers to handle.
|
||||
|
||||
![functional testing roles][6]
|
||||
|
||||
When looking at other types of testing, such as load and performance testing, there seemed to be a wider variety of titles/roles that were involved (performance engineering, operations, etc.). Still, the role of a dedicated tester, whether technically focused or otherwise, seems to be one that won't be eliminated anytime soon.
|
||||
|
||||
![performance/load testing roles][7]
|
||||
|
||||
### Myth #5: Behavior-driven development means you don't have to plan ahead.
|
||||
|
||||
[Behavior-driven development][8] (BDD) is a hot topic in industry discussions these days, with anywhere between 15-40% of companies using it (depending on your source). While many have implemented the tools that support BDD (Cucumber, SpecFlow, and so on), few have implemented the true foundation of the approach: specification-by-example using scenarios. Teams have often managed to get by with suboptimal requirement definitions due to their frequent, in-person collaboration; requirements are defined along the way, as things develop. If only 20% of companies provide documentation in the required format, it's likely we'll see struggles now that teams are increasingly remote.
|
||||
|
||||
![BDD usage][9]
|
||||
|
||||
### Open source and the future
|
||||
|
||||
The future of open source testing is bright, but it's changing. Few industries are as well-equipped to adapt to rapid change as open source development.
|
||||
|
||||
Want to dig a little deeper? Head over to Tricentis' [infographic][10] to explore the detailed results and sign up to participate in the _2021 State of Open Source Testing Survey_.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/6/open-source-testing-myths
|
||||
|
||||
作者:[Kevin Dunne][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/kdunne916
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/mobile-device-phone-team-collaboration-demo.png?itok=q96f2Eao (Collaboration on a mobile software design)
|
||||
[2]: https://www.tricentis.com/state-of-open-source-2020/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/os_testing_1_0.png (OS testing impediments)
|
||||
[4]: https://opensource.com/sites/default/files/uploads/os_testing_2.png (OS testing offshore)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/os_testing_3.png (OS testing benefits)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/os_testing_4.png (functional testing roles)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/os_testing_5.png (performance/load testing roles)
|
||||
[8]: https://opensource.com/article/19/2/behavior-driven-development-tools
|
||||
[9]: https://opensource.com/sites/default/files/uploads/os_testing_6.png (BDD usage)
|
||||
[10]: https://www.tricentis.com/state-of-open-source-2020
|
@ -0,0 +1,77 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Airbus tells quantum-computing developers what it needs from the the technology)
|
||||
[#]: via: (https://www.networkworld.com/article/3561228/airbus-tells-quantum-computing-developers-what-it-needs-from-the-the-technology.html)
|
||||
[#]: author: (Michael Cooney https://www.networkworld.com/author/Michael-Cooney/)
|
||||
|
||||
Airbus tells quantum-computing developers what it needs from the the technology
|
||||
======
|
||||
Aerospace multinational Airbus says it is 'quantum-ready' and helping to shape the future capabilities of quantum computing.
|
||||
[Glosser.ca / Pete Linforth][1] [(CC BY-SA 3.0)][2]
|
||||
|
||||
Airbus expects quantum computing to have major production, performance and efficiency benefits as the technology plays a role in its cybersecurity, aerospace and communications businesses.
|
||||
|
||||
“We are users of quantum computing and intend to use it to deliver more powerful services and systems,” said [Paolo Bianco][3], global research & technology cooperation manager for Airbus to an online audience at the [Inside Quantum Technology][4] virtual event this week.
|
||||
|
||||
[10 of the world's fastest supercomputers][5]
|
||||
|
||||
“We are not very much interested in developing our own quantum technology but will help others develop quantum technologies so that we can integrate them into what we are doing. Our aim is to be quantum-ready. It’s a race, and we want to hit the ground running.”
|
||||
|
||||
The multinational aerospace corporation and world’s largest airline manufacturer is well on its way to utilizing and helping influence the develop the future of quantum computing.
|
||||
|
||||
For example, Bianco pointed to three key quantum technology areas Airbus is interested in – communication/security, computing and sensing.
|
||||
|
||||
"The field of quantum communications is where we started in 2012 as the company was evaluating the technology’s threat to secure communications," Bianco said.
|
||||
|
||||
According to a recent Airbus [blog][6], "Today’s cryptographic algorithms—such as the widely used encryption via asymmetric keys—will not be able to sustain attacks by the quantum computers of tomorrow. Our goal is to develop a future secure communications infrastructure for our aerospace platforms based on security-enhancing quantum information technologies (algorithms, authentications, keys).”
|
||||
|
||||
Airbus wants to make quantum computing a significant part of its ongoing high-performance computing (HPC) work.
|
||||
|
||||
"We are an avid HPC user because we do a lot of simulations and design," the company says, "and we have invested a lot of time and money to understand how quantum computing can be used with HPC to improve our efficiency and performance."
|
||||
|
||||
The third area Airbus is looking to develop is quantum sensors that "are effective at measuring physical quantities such as frequency, acceleration, rotation rates, electric and magnetic fields, and temperature with the highest relative and absolute accuracy," Airbus stated.
|
||||
|
||||
"We believe this could have direct applications in improving our navigation systems in which precise acceleration measurement is used to achieve position data," Airbus stated. "In addition, quantum sensors could act as payloads for a range of different applications, such as climate dynamics from satellites or underground resources surveying from an aircraft."
|
||||
|
||||
In addition to those three areas, the company 18 months ago began the [Airbus Quantum Computing Challenge][7] (AQCC) to get the quantum community involved in addressing aerospace-flight physics problems. The challenge put forward five distinct problems, such as saving fuel or designing aircraft wings, with varying degrees of complexity, ranging from a simple mathematical question to a global flight physics problem, Airbus stated.
|
||||
|
||||
The challenge involved quantum-computing research from Airbus’ team and third parties, and the results were expected earlier this year. But as with many things, the announcement of the winner has been delayed due the COVID-19 pandemic, but Bianco said results are expected soon.
|
||||
|
||||
Beyond the Challenge, Airbus has taken part in the development of the quantum computing community. For example it provided early funding to quantum-computing-as-a-service vendor QC Ware, which offers a cloud-based service that provides enterprises with access to quantum resources. Other vendors such as [D-Wave][8], Google, [IBM][9] and [Rigetti][10] offer similar cloud-based resource services.
|
||||
|
||||
Airbus has also been involved in developing quantum technologies for use in [space][11], as well as facilitating [university research][12] with the Quantum Technology Application Centre.
|
||||
|
||||
“We need to develop systems that are far away from the everyday experience…we are ready to go the extra mile to understand something we are going to use,” Bianco said. Aerospace could be one of the technologies that helps everyone learn what quantum can do, particularly in extreme environments, he said.
|
||||
|
||||
Join the Network World communities on [Facebook][13] and [LinkedIn][14] to comment on topics that are top of mind.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3561228/airbus-tells-quantum-computing-developers-what-it-needs-from-the-the-technology.html
|
||||
|
||||
作者:[Michael Cooney][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.networkworld.com/author/Michael-Cooney/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/File:Bloch_Sphere.svg
|
||||
[2]: https://creativecommons.org/licenses/by-sa/3.0/legalcode
|
||||
[3]: https://www.linkedin.com/in/paolobianco1/?originalSubdomain=uk
|
||||
[4]: https://www.insidequantumtechnology.com/news/inside-quantum-technology-new-york-online-tuesday-june-2/
|
||||
[5]: https://www.networkworld.com/article/3236875/embargo-10-of-the-worlds-fastest-supercomputers.html
|
||||
[6]: https://www.airbus.com/innovation/future-technology/quantum-technologies.html
|
||||
[7]: https://www.airbus.com/newsroom/news/en/2019/10/world-leading-experts-Airbus-Quantum-Computing-Challenge.html
|
||||
[8]: https://www.dwavesys.com/quantum-computing
|
||||
[9]: https://www.ibm.com/quantum-computing/
|
||||
[10]: https://rigetti.com/
|
||||
[11]: http://qtspace.eu:8080/sites/testqtspace.eu/files/QTspace_Stretegic_Report_Intermediate.pdf
|
||||
[12]: http://www.bristol.ac.uk/temple-quarter-campus/research-teaching-and-partnerships/qtic/
|
||||
[13]: https://www.facebook.com/NetworkWorld/
|
||||
[14]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,116 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Code your hardware using this open source RTOS)
|
||||
[#]: via: (https://opensource.com/article/20/6/open-source-rtos)
|
||||
[#]: author: (Zhu Tianlong https://opensource.com/users/zhu-tianlong)
|
||||
|
||||
Code your hardware using this open source RTOS
|
||||
======
|
||||
Programming a chip is hard, but RTOS solves many of the major issues on
|
||||
embedded systems
|
||||
![Puzzle pieces coming together to form a computer screen][1]
|
||||
|
||||
In general computing, an operating system is software that provides a computer's basic functions. It ensures that a computer detects and responds to peripherals (like keyboards, screens, mobile devices, printers, and so on), and it manages memory and drive space.
|
||||
|
||||
Even though modern operating systems make it seem that multiple programs are running at the same time, a CPU core can run only a single thread at a time. Each task is executed so quickly and in such rapid succession that the result appears to be massive multi-tasking. This is managed by a subroutine called a _scheduler_.
|
||||
|
||||
Operating systems, usually, are for computers. The OS is installed to your hard drive, and manages the computer's tasks.
|
||||
|
||||
### Why RTOS is essential for embedded systems
|
||||
|
||||
I discovered embedded software in 2008, when I was a student learning about programming on an [MCS-51][2] chip. Because I was majoring in computer science, all the programs I was doing in other courses were executed on a PC. But programming on a chip was a completely different experience. For the first time, I saw my programs running on a bare-metal board, and I can still remember the excitement when my first cycling lamp program ran successfully.
|
||||
|
||||
The excitement was relatively short-lived, though. The more bare-metal programs I wrote, the more issues I encountered. I wasn't alone in this frustration. Programming a chip directly is hard, and there are good reasons PCs use an operating system. Unfortunately, computer chips (an embedded system) don't normally have an OS. They're "hard coded" with code with no OS to help manage how the code gets executed.
|
||||
|
||||
Here are the problems you might encounter when hard coding a computer chip:
|
||||
|
||||
#### Concurrency
|
||||
|
||||
You don't have daemons on a chip to manage execution. For bare-metal programs, there is inevitably a huge `while (1)` loop that contains almost all the transaction logic of the whole project. Each transaction invokes one or more delay functions. These are executed serially when the CPU is running a delay function. There's nothing to preempt an unnecessary delay, so the transaction reset has to wait. As a result, much of the CPU time is wasted on empty loops, which is bad for concurrency.
|
||||
|
||||
#### Modularity
|
||||
|
||||
From the perspective of a software project, the principle of high cohesion and low coupling is always emphasized during the development process. However, modules in bare-metal software usually depend on each other heavily. As mentioned above, most functions are collected in a huge `while (1)` loop, which is hard to divide into modules. It's just not convenient to design software with low coupling, which makes it difficult to develop large projects on bare-metal boards.
|
||||
|
||||
Also, developers must be careful to use delay functions when a watchdog timer is involved. If the delay time is too long, then the main function doesn't have an opportunity to reset the watchdog, so the watchdog is triggered during execution. For bare-metal development, there are too many things to consider, even when invoking a delay function. The more complex the project is, the more care you need to take. Imagine trying to decouple this series of delicately timed interactions into modules.
|
||||
|
||||
#### Ecosystem
|
||||
|
||||
Many advanced software components depend on the implementation of the lower-level operating system. For example, I developed an open source project based on [FreeModbus][3] that I'd planned to transplant to various platforms, even to bare metal. But compared to the convenience of adapting it to different operating systems, some functions are too complex to implement on all bare-metal boards. Worse still, many implementations would have to be designed from scratch on different hardware platforms because of the lack of commonality.
|
||||
|
||||
For now, my implementation of the Modbus stack still cannot run on bare-metal boards.
|
||||
|
||||
Many WiFi software-development kits provided by big companies such as Realtek, TI, and MediaTek can run only on the operating system. They don't publish their firmware's source code for the user to modify, so you can't use them within a bare-metal environment.
|
||||
|
||||
#### Real-time capability
|
||||
|
||||
Real-time capability is necessary for some application fields. For some use cases, a critical software step must be triggered at a specific time. For industry control, for instance, mechanical devices must complete actions in a predetermined order and timing. Without ensuring real-time capability, there would be malfunctions that could endanger the lives of workers. On bare-metal platforms, when all the functions are jammed into one big `while (1)` loop, it's impossible to maintain the real-time capabilities.
|
||||
|
||||
#### Reusability
|
||||
|
||||
Reusability depends on modularity. Nobody wants to do the same job over and over, especially if that job is writing code. Not only is it a waste of time, but it makes code maintenance exponentially more complex. And yet, on various hardware platforms with different chips, the same function has to be adapted to different hardware because the implementation depends on low-level hardware. It's inevitable to reinvent the wheel.
|
||||
|
||||
### Advantages of RTOS
|
||||
|
||||
Fortunately, there are operating systems written for chips: they're called a real-time operating system (RTOS), and like most operating systems, they have a scheduler to ensure a predictable order of code execution.
|
||||
|
||||
I first used an RTOS for bare metal in 2010. The [STM32][4] series of microcontrollers (MCUs) was starting to become popular, and because they were so powerful and rich in features, many people were running operating systems on them. I used the [RT-Thread][5] operating system, which has many available, ready-to-use components built on it. It's available under the Apache 2.0 license, and I feel more comfortable with it compared to other operating systems. I have been developing on it for 10 years.
|
||||
|
||||
For bare-metal programming, an RTOS solves most of the biggest problems we face.
|
||||
|
||||
#### Modularity
|
||||
|
||||
With an operating system, the entire software can be split into several tasks (known as threads). Each thread has its own independent execution space. They're independent of each other, which improves modularity.
|
||||
|
||||
#### Concurrency
|
||||
|
||||
When a thread invokes the delay function, it automatically yields the CPU to other threads that need to run, which improves the utilization of the entire CPU and, ultimately, the concurrency.
|
||||
|
||||
#### Real-time
|
||||
|
||||
An RTOS is designed with real-time capabilities. Each thread is assigned a specified priority. More important threads are set to a higher priority, with less important threads set to lower ones. In this way, the real-time performance of the entire software is guaranteed.
|
||||
|
||||
#### Development efficiency
|
||||
|
||||
The operating system provides a unified layer of abstract interfaces. This facilitates the accumulation of reusable components and improves development efficiency.
|
||||
|
||||
The operating system is a product of the wisdom of a group of software geeks. Many common software functions, such as semaphore, event notification, mailbox, ring buffer, one-way chain list, two-way list, and so on, are encapsulated and abstracted to make them ready to use.
|
||||
|
||||
Operating systems like Linux and RT-Thread implement a standard set of hardware interfaces for fragmented hardware. This is known as the device-driver framework. Because of this, a software engineer can focus on development with no concern about the underlying hardware or reinventing the wheel.
|
||||
|
||||
#### Software ecosystem
|
||||
|
||||
The richness of the RT-Thread ecosystem brings the process of quantitative changes to qualitative ones. The improvement in modularity and reusability with an operating system allows programmers to encapsulate RTOS-based, embedded-friendly reusable components. These can be used in projects as well as be shared with other embedded-application developers who need to maximize the value of software.
|
||||
|
||||
For example, the LkdGui project is an open source graphics library designed for monochrome displays. You might see it used in industrial settings for simple, beautiful graphical interfaces for control panels. LkdGui provides graphical functions, such as drawing points, lines, rectangles, text display, button widgets, and progress bars.
|
||||
|
||||
![LkdGui][6]
|
||||
|
||||
The ability to reuse a library as extensive and robust as LkdGui means programmers can build on top of their peers' work. Without an RTOS, this just wouldn't be possible.
|
||||
|
||||
### Try RT-Thread
|
||||
|
||||
I'm an open source geek, and I have open sourced some embedded software on GitHub. Before creating open source software, I rarely talked with others about my projects because people were inevitably using different chips or hardware platforms, so our code could hardly run on one another's hardware. An RTOS like RT-Thread greatly improves software reusability, so many diverse experts all over the world can communicate with each other about the same project. This is encouraging more and more people to share and talk about their projects. If you're doing bare-metal programming, try RT-Thread on your next project.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/6/open-source-rtos
|
||||
|
||||
作者:[Zhu Tianlong][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/zhu-tianlong
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
|
||||
[2]: https://en.wikipedia.org/wiki/Intel_MCS-51
|
||||
[3]: https://www.embedded-solutions.at/files/freemodbus-v1.6-apidoc/
|
||||
[4]: https://en.wikipedia.org/wiki/STM32
|
||||
[5]: https://github.com/RT-Thread/rt-thread
|
||||
[6]: https://opensource.com/sites/default/files/uploads/lkdgui.jpg (LkdGui)
|
381
sources/tech/20200603 Exploring Algol 68 in the 21st century.md
Normal file
381
sources/tech/20200603 Exploring Algol 68 in the 21st century.md
Normal file
@ -0,0 +1,381 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Exploring Algol 68 in the 21st century)
|
||||
[#]: via: (https://opensource.com/article/20/6/algol68)
|
||||
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
|
||||
|
||||
Exploring Algol 68 in the 21st century
|
||||
======
|
||||
An in-depth look at a forgotten language and its modern applications.
|
||||
![Old UNIX computer][1]
|
||||
|
||||
In the preface to his excellent textbook _Algol 68: A First and Second Course_, Andrew McGettrick writes:
|
||||
|
||||
> "This book originated from lectures first given at the University of Strathclyde in 1973-4 to first-year undergraduates, many of whom had no previous knowledge of programming. Many of the students were not taking computer science as their main subject but merely as a subsidiary subject. They, therefore, served as a suitable audience on whom to inflict lectures attempting to teach Algol 68 as a first programming language."
|
||||
|
||||
Perhaps this quote carries particular weight for me as I, too, was a first-year student in 1973-1974, though at a different institution—the University of British Columbia. Moreover, "back in those days," the introductory computer science course at UBC was taught in the second year using Waterloo FORTRAN with a bit of IBM 360 Assembler thrown in; nothing so exotic as Algol 68. In my case, I didn't encounter Algol 68 until my third year. Maybe this wait, along with experiences in other programming languages, contributed to my lifelong fascination with this underrated and wonderful programming language. And thanks to Marcel van der Veer, who has created [a very fine implementation of Algol 68][2] called Algol 68 Genie, that is now in my distro's repositories, at long last, I've been able to explore Algol 68 at my leisure. I should also mention that Marcel's book, [_Learning Algol 68 Genie_][3], is of great utility both for newcomers and as a refresher course in Algol 68.
|
||||
|
||||
Because I've been having so much fun rediscovering Algol 68, I thought I'd share some of my thoughts and impressions.
|
||||
|
||||
### What people say about Algol 68
|
||||
|
||||
If it's worth reading [the overview of Algol 68 on Wikipedia][4], then it's really worth reading this paragraph from the [_Revised Report on the Algorithmic Language Algol 68_][5]:
|
||||
|
||||
> "The original authors acknowledged with pleasure and thanks the wholehearted cooperation, support, interest, criticism, and violent objections from members of WG 2.1 and many other people interested in Algol."
|
||||
|
||||
"Criticism and violent objections"—wow! In fact, some committee members were so unhappy with the direction the committee was taking that they left and started their own language definition projects, at least partly as a protest against Algol 68. Niklaus Wirth, for example, fed up with the complexity of Algol 68, [went off to design Pascal][6]. And having written and supported a fair bit of Pascal code from about 1984 through 2000 or so, I am here to tell you that Pascal is about as far from Algol 68 as it's possible to get. Which, it seems to me, was Wirth's point.
|
||||
|
||||
Dennis Ritchie [gave a talk][7] at the second ACM History of Programming Languages conference in Cambridge, Massachusetts in 1993, in which he compares Bliss, Pascal, Algol 68, and C. In that talk, he made several interesting observations:
|
||||
|
||||
* All of the four languages are "based on this old, old model of machines that pick up things, do operations, and put them someplace else" and "are very much influenced by Algol 60 and FORTRAN."
|
||||
* "When Steve Bourne (yes, the person who created the Bourne shell) came to Bell Labs with the Algol 68C compiler, he made it do the same things that C could do; it had Unix system call interfaces and so forth."
|
||||
* "I think the language really did suffer from its definition in terms of acceptance. Nevertheless, it was really quite practical."
|
||||
* "In some ways, Algol 68 is the most elegant of the languages I've been discussing. I think in some ways, it's even the most influential, although as a language in itself, it has nearly gone away."
|
||||
|
||||
|
||||
|
||||
There is much more opinion on Algol 68 still prominent on the Internet today. A lot of it is negative, but oh well! I suspect a great deal of it is not informed by actual use. One very interesting place to find coders just getting down to using the language (and many others, some marvelously obscure) is on [the Rosetta Code Wiki][8]. Go there and form your own opinion! Or follow me as I review what strikes me as great and not so great about Algol 68.
|
||||
|
||||
### What seems important and relevant to me about Algol 68
|
||||
|
||||
Algol 68, as a programming language, offers some distinctive and useful ideas that were innovative at the time and have shown up, to some degree or the other, in other languages since then.
|
||||
|
||||
#### Key design principles clearly explained in the Revised Report
|
||||
|
||||
The committee that designed Algol 68 was driven by a very clear set of principles:
|
||||
|
||||
* Completeness and clarity of description (aided by the use of two-level grammar, which provoked many negative opinions)
|
||||
* Orthogonal design; that is, basic concepts defined in the language can be used anywhere that usage can be said to "make sense." As an example—every expression that can reasonably be expected to yield a value does, in fact, yield a value.
|
||||
* Security by way of careful syntactical design (that two-level grammar again); most errors thought to be related to semantic concepts in other languages can be detected at compile time.
|
||||
* Efficiency, in that programs should run efficiently (on the hardware of the day) without requiring significant efforts to optimize the generated code, and furthermore:
|
||||
* No run time-type checking except in the unique case of types that present alternative configurations at run time (`united` types in Algol 68, similar to `union` types in C)
|
||||
* Type-independent parsing (again, the two-level grammar at work here) and certainty that, in a finite number of steps, any input sequence can be evaluated as to whether it is a program or not
|
||||
* Loop structures that encourage the use of well-known loop optimization strategies of the day
|
||||
* A symbol set (with alternatives) that worked on the various different character sets available on computers at the time
|
||||
|
||||
|
||||
|
||||
I find it instructive to see the emphasis on very strong static typing (50 years ago!!) and the benefits that were expected to accrue, in contrast to today's universe of dynamically-typed languages and languages with weak static typing that have helped spawn an entire industry of run-time testing. (OK maybe that's not completely fair, but it contains a certain element of truth).
|
||||
|
||||
#### Structures to group statements together without extra grouping constructs
|
||||
|
||||
In programs written in Algol 60 and Pascal, we see a lot of `begin` and `end` tokens; in C, C++, Java, and so forth, we see a lot of `{` and `}`. For example, the simple expression to calculate the absolute value `av` of an integer value `iv` can be written in either Algol 60 or Pascal as:
|
||||
|
||||
|
||||
```
|
||||
`if iv < 0 then av := -iv else av := iv`
|
||||
```
|
||||
|
||||
If we wanted to set a Boolean value stating whether `iv` was negative, then we need to start inserting `begin` and `end`:
|
||||
|
||||
|
||||
```
|
||||
`if iv < 0 then begin av := -iv; negative := true end else begin av := iv; negative := false end`
|
||||
```
|
||||
|
||||
Formally, Algol 68 uses boldface for tokens with special meaning like **if** or **then**, and uses italics for names of things like the _print_() procedure. This wasn't practical back in the day when many still used keypunches for coding, and it would still be a bit weird today. So Algol 68 implementations usually provided some method of marking special symbols (called _stropping_), leaving everything else unmarked. By default, Algol 68 Genie uses upper case stropping, so symbols like **if** are coded as IF, and names of things can only be in lower case. Worth noting however is that it's completely ok to have a variable named "if" should that suit the purpose at hand. Anway... in case any reader is inclined to copy / paste, I'm using the Genie convention in my code samples.
|
||||
|
||||
Moreover, Algol 68 has a closed syntax, which the Bourne shell and Bash have inherited. So the previous line of code in Algol 68 Genie would be:
|
||||
|
||||
|
||||
```
|
||||
`IF iv < 0 THEN av := -iv; negative := TRUE ELSE av := iv; negative := FALSE FI`
|
||||
```
|
||||
|
||||
The token `fi` closes off the preceding `if`, in case that's not obvious. Now, perhaps I'm the only person in the world who has ever written some Java that looks like this:
|
||||
|
||||
|
||||
```
|
||||
if (something)
|
||||
statement;
|
||||
```
|
||||
|
||||
and then found myself inserting a call to `println` to debug that code:
|
||||
|
||||
|
||||
```
|
||||
if (something)
|
||||
statement;
|
||||
[System][9].err.println(stuff); /* not in the then-part of if!!! */
|
||||
```
|
||||
|
||||
cluelessly forgetting to wrap the then-part in `{` … `}`. And of course, this isn't the end of the world, but when the insertion is something with less obvious results, well, let's just say I've spent a fair bit of time debugging this kind of thing over the years.
|
||||
|
||||
But that can't happen in Algol 68. Well, mostly, anyway. Algol 68 still needs `begin` … `end` for operator and procedure declarations. But `if` … `fi`, `do` … `od` and `case` … `esac` (the Algol 68 switch statement) are all closed.
|
||||
|
||||
We see this same concept in Go today; an "if" statement looks like if … { … }; the { and } are required. And as I already mentioned, the Bourne shell and its descendants use similar constructs.
|
||||
|
||||
#### Almost every expression yields a value
|
||||
|
||||
Look at the expression `iv < 0` above; pretty obvious that yields a value, and most likely that value is Boolean (`true` or `false`). So no big deal there.
|
||||
|
||||
But an assignment statement also yields a value, namely, the left-hand side of the assignment statement after the assignment is completed.
|
||||
|
||||
A sequence of statements yields whatever the final statement (or expression) yields as a value.
|
||||
|
||||
An "if" statement yields either the value of the then-part or the else-part, depending on whether the expression following "if" yields `true` or `false`.
|
||||
|
||||
An example: think of using the C, Java… ternary operator for our absolute value calculation:
|
||||
|
||||
|
||||
```
|
||||
`av = iv < 0 ? -iv : iv;`
|
||||
```
|
||||
|
||||
In Algol 68, we don't need an extra "ternary operator," as the "if" statement works just fine:
|
||||
|
||||
|
||||
```
|
||||
`av := IF iv < 0 THEN -iv ELSE iv FI`
|
||||
```
|
||||
|
||||
This might be a good moment to mention that Algol 68 provides "brief" versions of symbols like `begin`, `end`, `if`, `then`, `else` and so forth, using `( |` and `)`:
|
||||
|
||||
|
||||
```
|
||||
`av := ( iv < 0 | -iv | iv )`
|
||||
```
|
||||
|
||||
has the same meaning as the previous expression.
|
||||
|
||||
One thing that surprised me when I first encountered it is that loops don't yield an expression. But loops have a few differences that end up making sense once they are fully understood.
|
||||
|
||||
A loop in Algol 68 might look like this:
|
||||
|
||||
|
||||
```
|
||||
`FOR lv FROM 1 BY 1 TO 1000 WHILE 2 * lv * ly < limit DO … OD`
|
||||
```
|
||||
|
||||
The variable `ly` here is the loop variable, implicitly declared by the `for` as an integer. Its scope is the entire `for` … `od`**,** and its value is retained from one iteration to the next. We can declare a regular variable in the `while` … `do` part, just like in an `if` … `then` part. Its scope is the `while` … `od` part, but its value is not retained from one iteration to the next. So, for example, if we want to accumulate the sum of the elements of an array, we must write:
|
||||
|
||||
|
||||
```
|
||||
`INT sum := 0; FOR ai FROM LWB array TO UPB array DO sum +:= array[ai] OD`
|
||||
```
|
||||
|
||||
where the operators `lwb` and `upb` deliver the smallest and largest index values respectively defined for the array and the +:= symbol has the same meaning as += in C or Java.
|
||||
|
||||
If we wanted to return the sum as a value, we would write:
|
||||
|
||||
|
||||
```
|
||||
`BEGIN INT sum := 0; FOR ai FROM LWB array TO UPB array DO sum +:= array[ai] OD; sum END`
|
||||
```
|
||||
|
||||
Of course, we could replace `begin` and `end` with `(` and `)` for brevity. This expression would be a reasonable implementation of a procedure (or operator) that returns the sum of the values of the elements of an array.
|
||||
|
||||
#### Orthogonality—the same expression will work almost anywhere
|
||||
|
||||
Look again at the expression `iv < 0` above.
|
||||
|
||||
Let's step back a bit and include a definition of `iv` and the acquisition of its value. Then the code might look like:
|
||||
|
||||
|
||||
```
|
||||
`INT iv; read(iv); IF iv < 0 THEN … FI`
|
||||
```
|
||||
|
||||
However, we could just as well write:
|
||||
|
||||
|
||||
```
|
||||
`IF INT iv; read(iv); iv < 0 THEN … FI`
|
||||
```
|
||||
|
||||
Here we can see orthogonality at work - the declaration and reading of the variable can occur between the `if` and the logical expression testing the variable, because the value delivered is just that of the final expression. Moreover, this works with Algol 68 semantics to provide an interesting difference—in the first case, the scope of `iv` is the code surrounding the "if" statement; in the second, the scope is just between the `if` and the `fi`. To my way of thinking, this option means that we should have fewer variables declared far away from where they are used, and the ones that remain really do have a "long life" in the code.
|
||||
|
||||
This has practical importance as well. Think, for example, of code that uses some kind of SQL interface to execute several scripts in a database and return the values for further analysis. Usually, in this case, the programmer needs to do a bit of work to set up the connection to the database, pass a query string to the execute command, and retrieve the results. Each instance requires declaring some variables to hold the connection, the query string, and the results. How nice it is when these variables can be declared locally to the results accumulation code! This also facilitates adding a new query-analysis step with a quick copy-paste. And yes, it's good to turn these code snippets into procedure calls, especially in a language that supports lambdas (anonymous procedures) so as to avoid obscuring the different analysis steps with repeated administrative steps. But having very locally-defined administrative variables facilitates the refactoring effort required.
|
||||
|
||||
Another great consequence of orthogonality is that we can have the equivalent of the ternary operator on the left-hand side of an assignment statement as well as on the right-hand side.
|
||||
|
||||
Let's suppose we're processing an input stream of signed integers, and we want to accumulate positive integers into gains and negative integers into losses. Then, the following Algol 68 code would work:
|
||||
|
||||
|
||||
```
|
||||
`IF amount < 0 THEN losses +:= amount ELSE gains +:= amount FI`
|
||||
```
|
||||
|
||||
However, there's no need to repeat the `+:= amount` here; we can move it outside the `if` … `fi` as follows:
|
||||
|
||||
|
||||
```
|
||||
`IF amount < 0 THEN losses ELSE gains FI +:= amount`
|
||||
```
|
||||
|
||||
This works because the "if" statement yields either the losses or gains expression as a result of the evaluation of the test, and that expression is incremented by amount. And of course, we can use the brief form, which, in my opinion at least, improves the readability in these short expressions:
|
||||
|
||||
|
||||
```
|
||||
`(amount < 0 | losses | gains) +:= amount`
|
||||
```
|
||||
|
||||
How about a real example to show why this expression-oriented thing is so great?
|
||||
|
||||
Suppose you are writing a hash table facility. Two functions you will have to implement are "get the value associated with a given key" and "set the value associated with a given key".
|
||||
|
||||
In an expression-oriented language, those can be one function. Why? Because the "get" operation returns the location where the value is found, and then the "set" operation simply uses the "get" operation to set the value at that location. Let's assume we've created an operator called `valueat` that takes two arguments—the hash table itself and the key value. Then,
|
||||
|
||||
|
||||
```
|
||||
`ht VALUEAT 42`
|
||||
```
|
||||
|
||||
will return the location of key 42 in the hash table ht and
|
||||
|
||||
|
||||
```
|
||||
`ht VALUEAT 42 := "the meaning of everything"`
|
||||
```
|
||||
|
||||
will put the string "the meaning of everything" at location 42.
|
||||
|
||||
This reduces the amount of code required to support the application at hand, reducing the number of pathways and edge cases that must be tested, and just generally adds wonderfulness to the users' and maintainers' lives.
|
||||
|
||||
There is a simple example of using procedures on the left-hand side of assignment statements to store values in a table on [RosettaCode][10].
|
||||
|
||||
#### Anonymous procedures (lambdas)
|
||||
|
||||
Everyone seems to want anonymous procedures (or "here" procedures, or lambdas) these days. Algol 68 provided that out of the box, and it's really, truly useful.
|
||||
|
||||
By way of example, imagine that you want to create a facility to read files with delimited fields and to give users a nice interaction pathway with those. Think of the fine job `awk` does on this, basically by abstracting away all the junk related to opening the file, reading the lines, splitting the lines into fields, and providing some useful collateral variables along the way, like current-line-number, number-of-fields-on-this-line, and so forth.
|
||||
|
||||
It turns out that's pretty easy to do in Algol 68 as well, where the task becomes to write a procedure that takes three arguments—the first being the input file name, the second being the field separator string, and the third being a procedure that handles each line.
|
||||
|
||||
The declaration of that procedure might look like this:
|
||||
|
||||
|
||||
```
|
||||
PROC each line = # 1 #
|
||||
(STRING input file name, CHAR separator, PROC (STRING, [] STRING, INT) VOID process) # 2 #
|
||||
VOID: BEGIN # 3 #
|
||||
FILE inf; # 4 #
|
||||
open(inf, input file name, stand in channel); # 5 #
|
||||
BOOL finished reading := FALSE;
|
||||
on logical file end (inf, (REF FILE f) bool: finished reading := TRUE); # 6 #
|
||||
INT linecount := 0; # 7 #
|
||||
WHILE # 8 #
|
||||
string line;
|
||||
get(inf,(line, new line));
|
||||
not finished reading
|
||||
DO # 9 #
|
||||
linecount +:= 1;
|
||||
FLEX [1:0] STRING fields := split(line, separator);
|
||||
process(line, fields, linecount)
|
||||
OD;
|
||||
close(inf) # 10 #
|
||||
END # 11 #
|
||||
```
|
||||
|
||||
Here’s what’s going on above:
|
||||
|
||||
1. Comment 1 (the # 1 # above)—the declaration of the procedure `each line` (note that blanks can be inserted into the middle of names or numbers at will)
|
||||
|
||||
2. The parameters to each line—the `string` file name, the field separator `char`acter, and the `pro`cedure to be called to process each line, which itself takes a `string` (the line of input) an array of `string`s (the fields of the line) and an `int`eger (the line number) and which returns a `void` value
|
||||
|
||||
3. `each line` returns a `void` value, and the procedure body starts with a `begin`, allowing us to use several statements in its definition
|
||||
|
||||
4. Declare the input `file`
|
||||
|
||||
5. Associate the `standard input channel` with the `file`, whose name is given by `input file name` and open it (for reading)
|
||||
|
||||
6. Algol 68 handles end-of-file conditions a bit differently; here, we use the I/O event detection procedure `on logical file end` to set the flag `finished reading` that we can detect while processing the file
|
||||
|
||||
7. Create and initialize the line count (see the previous description of the nature of loops)
|
||||
|
||||
8. This `while` loop attempts to read the next line from the input file. If successful, it processes the line; otherwise, it exits
|
||||
|
||||
9. Processing the input line—increment the line count; create an array of strings corresponding to the fields of the line using the `split` procedure; call the supplied `process` procedure to consume the line, its fields and the line count
|
||||
|
||||
10. Remember to `close` the file
|
||||
|
||||
11. `end` of the procedure definition.
|
||||
|
||||
|
||||
|
||||
|
||||
And we might use it like so, in order to build a lookup table (in conjunction with the hypothetical hash table facility mentioned in passing in the previous section):
|
||||
|
||||
|
||||
```
|
||||
# remapping definitions in remapping.csv file #
|
||||
# new-reference|old-reference #
|
||||
# 093M0770371|093X0012250 #
|
||||
# 093M0770375|093X0012249 #
|
||||
# 093M0770370|093X0012133 #
|
||||
|
||||
[/code] [code]
|
||||
|
||||
HASTABLE ht := new hashtable;
|
||||
|
||||
each delimited line("test.csv", "|", (STRING line, [] STRING fields, INT linecount) VOID: BEGIN
|
||||
STRING to map := fields[1], from map := fields[2];
|
||||
ht VALUEAT from map := to map
|
||||
END);
|
||||
```
|
||||
|
||||
Above, we see the call to each delimited line. Of particular interest is the declaration of the "here" procedure or lambda that stows the lookup values into the hash table. From my perspective, the big lesson here is that lambdas are a consequence of Algol 68's orthogonality; I think that's pretty neat.
|
||||
|
||||
One of the things I plan to dig deeper into as I continue to explore Algol 68 is how much further I can take this functional form of expression. For example, I don't see why I can't build a list or a hash table element by element and yield the finished structure as the result of the looping procedure, so the above might look more like:
|
||||
|
||||
|
||||
```
|
||||
HASHTABLE ht := each delimited line as map entry("test.csv", "|",
|
||||
(STRING line, [] STRING fields, INT linecount) VOID: BEGIN
|
||||
STRING to map := fields[1], from map := fields[2];
|
||||
(from map, to map)
|
||||
END);
|
||||
```
|
||||
|
||||
### In conclusion
|
||||
|
||||
Why learn about old, dusty, and forgotten languages? Well, we all know about the recent interest in COBOL, but perhaps that's an outlier in the sense that there probably aren't a lot of mission-critical applications written in SNOBOL, Icon, APL, or even Algol 68. Certainly, there is George Santayana's guidance to bear in mind: ["Those who cannot remember the past are condemned to repeat it."][11]
|
||||
|
||||
For me, there are a few key reasons to up my game in Algol 68 (and probably in a few other languages that don't seem to be absolutely necessary to my daily efforts):
|
||||
|
||||
* Algol 68 was not defined as a reaction against some annoyances in an existing programming language; rather, according to the Revised Report:
|
||||
|
||||
* The committee (Working Group 2.1 on ALGOL of the International Federation for Information Processing) "expresses its belief in the value of a common programming language serving many people in many countries."
|
||||
|
||||
* "Algol 68 has not been designed as an expansion of Algol 60 but rather as a completely new language based on new insight into the essential, fundamental concepts of computing and a new description technique."
|
||||
|
||||
* Whether through positive contributions copied into other languages (`do` … `od` in the Bourne shell; += in C, Java, …) or negative reactions (Pascal and all its descendants, Ada), Algol 68 can claim to have influenced computing in profound ways.
|
||||
|
||||
* While Algol 68 is very much "a child of its time," being influenced by keypunches and line printers, small and diverse character sets, the wide variation in character and word sizes of computers in the 1960s and 1970s, and not explicitly incorporating object orientation or functional programming, its rather extraordinary orthogonality and expression-orientedness make up for these oddities and lacking in other useful ways.
|
||||
|
||||
* Perhaps the most practical reason is having the wonderful Algol 68 Genie interpreter installed and running on my desktop, allowing me to pursue this odd small hobby!
|
||||
|
||||
|
||||
|
||||
|
||||
Perhaps I should return to Santayana for a final comment:
|
||||
|
||||
> ["Beauty as we feel it is something indescribable: what it is or what it means can never be said."][11]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/6/algol68
|
||||
|
||||
作者:[Chris Hermansen][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/clhermansen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/retro_old_unix_computer.png?itok=SYAb2xoW (Old UNIX computer)
|
||||
[2]: https://jmvdveer.home.xs4all.nl/en.algol-68-genie.html
|
||||
[3]: https://jmvdveer.home.xs4all.nl/en.download.learning-algol-68-genie-283.html
|
||||
[4]: https://en.wikipedia.org/wiki/ALGOL_68
|
||||
[5]: http://www.softwarepreservation.org/projects/ALGOL/report/Algol68_revised_report-AB.pdf
|
||||
[6]: https://en.wikipedia.org/wiki/Pascal_(programming_language)
|
||||
[7]: https://www.bell-labs.com/usr/dmr/www/hopl.html
|
||||
[8]: http://rosettacode.org/wiki/Rosetta_Code
|
||||
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
|
||||
[10]: https://rosettacode.org/wiki/Associative_array/Creation#ALGOL_68
|
||||
[11]: https://en.wikiquote.org/wiki/George_Santayana
|
@ -0,0 +1,129 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to Install Nvidia Drivers on Fedora Linux)
|
||||
[#]: via: (https://itsfoss.com/install-nvidia-drivers-fedora/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
How to Install Nvidia Drivers on Fedora Linux
|
||||
======
|
||||
|
||||
Like most Linux distributions, [Fedora][1] does not come with the proprietary [Nvidia][2] drivers installed by default.
|
||||
|
||||
The default open source [Nouveau driver][3] works in most situations, but you may encounter issues like screen tearing with it.
|
||||
|
||||
![Display issue in Fedora with Nouveau graphics driver][4]
|
||||
|
||||
If you encounter such graphics/video issues, you may want to install the official proprietary Nvidia drivers in Fedora. Let me show you how to do that.
|
||||
|
||||
### Installing Nvidia drivers in Fedora
|
||||
|
||||
I am using [Fedora 32][5] in this tutorial but it should be applicable to other Fedora versions.
|
||||
|
||||
#### Step 1
|
||||
|
||||
Before you do anything else, make sure that your system is up-to-date. You can either use the Software Center or use the following command in the terminal:
|
||||
|
||||
```
|
||||
sudo dnf update
|
||||
```
|
||||
|
||||
#### Step 2
|
||||
|
||||
Since Fedora doesn’t ship the Nvidia driver, you need to add the [RPMFusion repos][6] to your system. You can use the following command in the terminal
|
||||
|
||||
```
|
||||
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
```
|
||||
|
||||
Don’t like terminal? Use GUI method to add RPMFusion repository
|
||||
|
||||
If you are using Firefox, you can also add the RPMFusion repositories from your browser. Go to the [Configuration page][7] and scroll down to the “Graphical Setup via Firefox web browser” section. Click the link for the free and then the nonfree repo. This will download the .rpm file, which will eventually install the repository.
|
||||
|
||||
![RPMFusion Browser Installation][8]
|
||||
|
||||
You can double click on the downloaded RPM file to install it.
|
||||
|
||||
![RPMFusion in the Software Center][9]
|
||||
|
||||
#### Step 3
|
||||
|
||||
Now you need to determine [what graphics card (or chip) you have in your Linux system][10]. Pull up the terminal and enter the following command:
|
||||
|
||||
```
|
||||
lspci -vnn | grep VGA
|
||||
```
|
||||
|
||||
![Video Card Lookup in Fedora][11]
|
||||
|
||||
Next, you need to look up what driver corresponds to that chip. You can find a list of the Nvidia chips [here][12]. You can also use [this tool][13] to search for your device.
|
||||
|
||||
**Note**: Keep in mind that there are only three drivers available to install, even though the Nvidia list shows more. The most recent cards are supported by the Nvidia driver. Old devices are supported by the nvidia-390 and nvidia-340 drivers.
|
||||
|
||||
#### Step 4
|
||||
|
||||
To install the required driver, enter one of the commands into the terminal. The following command is the one I had to use for my card. Update as appropriate for your system.
|
||||
|
||||
```
|
||||
sudo dnf install akmod-nvidia sudo dnf install xorg-x11-drv-nvidia-390xx akmod-nvidia-390xx sudo dnf install xorg-x11-drv-nvidia-340xx akmod-nvidia-340xx
|
||||
```
|
||||
|
||||
![Nvidia terminal installation][14]
|
||||
|
||||
#### Step 5
|
||||
|
||||
To make the changes take effect, reboot your system. It might take longer for your system to reboot because it is injecting the Nvidia driver into the Linux kernel.
|
||||
|
||||
Once you log in to your system after reboot, you should have a better visual performance and no screen tearing.
|
||||
|
||||
![Fedora with Nvidia drivers][15]
|
||||
|
||||
#### Bonus Tip:
|
||||
|
||||
This is an optional step but it is recommended. When you add the RPMFusion repos, you get access to multimedia packages that are not available in the regular repos.
|
||||
|
||||
This command will install packages for applications that use [gstreamer][16]:
|
||||
|
||||
```
|
||||
sudo dnf groupupdate multimedia --setop="install_weak_deps=False" --exclude=PackageKit-gstreamer-plugin
|
||||
```
|
||||
|
||||
This command will install packages needed by sound and video packages:
|
||||
|
||||
```
|
||||
sudo dnf groupupdate sound-and-video
|
||||
```
|
||||
|
||||
Hopefully, you find this tutorial useful in installing Nvidia drivers on Fedora. What other Fedora tutorials would you like to see on It’s FOSS?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-nvidia-drivers-fedora/
|
||||
|
||||
作者:[John Paul][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/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://getfedora.org/
|
||||
[2]: https://www.nvidia.com/en-us/
|
||||
[3]: https://en.wikipedia.org/wiki/Nouveau_(software)
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/05/fedora-nouveau.jpg?resize=800%2C500&ssl=1
|
||||
[5]: https://itsfoss.com/fedora-32/
|
||||
[6]: https://rpmfusion.org/RPM%20Fusion
|
||||
[7]: https://rpmfusion.org/Configuration
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/05/rpmfusion-gui-install.png?resize=800%2C500&ssl=1
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/05/rpmfusion-gui-install2.png?resize=800%2C500&ssl=1
|
||||
[10]: https://itsfoss.com/check-graphics-card-linux/
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/06/video-card-lookup-fedora.png?ssl=1
|
||||
[12]: https://us.download.nvidia.com/XFree86/Linux-x86/367.57/README/supportedchips.html
|
||||
[13]: https://www.nvidia.com/Download/index.aspx?lang=en-us
|
||||
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/05/nvidia-cli-install.png?resize=800%2C500&ssl=1
|
||||
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/05/fedora-nvidia.jpg?resize=800%2C500&ssl=1
|
||||
[16]: https://en.wikipedia.org/wiki/GStreamer
|
@ -0,0 +1,90 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Now You Can Buy Linux Certified Lenovo ThinkPad and ThinkStation (for the Best Possible Out of The Box Linux Experience))
|
||||
[#]: via: (https://itsfoss.com/lenovo-linux-certified/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Now You Can Buy Linux Certified Lenovo ThinkPad and ThinkStation (for the Best Possible Out of The Box Linux Experience)
|
||||
======
|
||||
|
||||
There was a time when [ThinkPad][1] was the preferred system for Linux users.
|
||||
|
||||
But that was when ThinkPad was an [IBM][2] product. When [Beijing-based Lenovo acquired New York-based IBM’s personal computer business in 2005][3], (I feel that) things started to change.
|
||||
|
||||
ThinkPad was/is an amazing series of laptops, reliable, trustworthy and rock solid. Just ask a person who used it before 2010s.
|
||||
|
||||
But around 2010, Lenovo ThinkPad started to lose its charm. It was filled with issues after issues and consumer complaints of poor performance.
|
||||
|
||||
Things were even worse for Linux users. Its secure boot with UEFI [created problems for Linux][4] users. The [controversy with Linux][5] would just not end.
|
||||
|
||||
Why am I recalling all this? Because Lenovo seems to be working on improving Linux compatibility. The latest announcement from Lenovo is an excellent news for Linux lovers.
|
||||
|
||||
### Entire range of Lenovo ThinkPad and ThinkStation will be Linux certified
|
||||
|
||||
![][6]
|
||||
|
||||
Lenovo [announced][7] that it is going to **certify the full workstation portfolio for top Linux distributions from Ubuntu and Red Hat**. This is valid for all models and configuration.
|
||||
|
||||
What does it mean to you as a Linux users? It means that if you buy a Lenovo computer, you will have the **best possible out-of-the-box Linux experience**.
|
||||
|
||||
Wait? Can you not just install Linux on any computer be it Le-novo or The-novo? Of course, you can. But when you wipe out existing (Windows) operating system and install Linux on your own, you may encounter hardware compatibility issues like audio missing, Wi-Fi not working etc.
|
||||
|
||||
The out-of-the-box experience matters because not everyone would be willing to spend time in fixing sound, graphics card, Wi-Fi and Bluetooth issues instead of focusing on their real work for which they bought the computer.
|
||||
|
||||
The developers from [Ubuntu][8] and Red Hat test and verify that each hardware component of Lenovo system works as intended.
|
||||
|
||||
### Ubuntu, Red Hat and more
|
||||
|
||||
![][9]
|
||||
|
||||
Lenovo has chosen two of the top Linux distributions for this purpose. Red Hat is a popular choice for Linux desktop and servers in enterprises. Ubuntu is of course popular in general.
|
||||
|
||||
This means that Lenovo system would work the best with Ubuntu LTS versions and Red Hat Linux. Lenovo will even offer the choice of Ubuntu and Red Hat preinstalled on its systems.
|
||||
|
||||
But it just doesn’t end here. Fedora is a community project from Red Hat and Lenovo is going to offer Fedora preloaded on ThinkPad P53 and P1 Gen 2 systems.
|
||||
|
||||
There are so many Linux distributions based on Ubuntu LTS release. Most of the time, these distributions differ in looks, applications and other graphical stuff, but they use the same base as Ubuntu.
|
||||
|
||||
This should mean that the Ubuntu-based distributions like Linux Mint, elementary OS etc also better hardware compatibility with Lenovo devices.
|
||||
|
||||
Lenovo is also going to upstream device drivers directly to the Linux kernel, to help maintain stability and compatibility throughout the life of the workstation. That’s superb.
|
||||
|
||||
### Will it help increase the Linux user base?
|
||||
|
||||
Out of the box experience matters. It lets you focus on the important tasks that you are supposed to do on your system rather than troubleshooting.
|
||||
|
||||
I have a [Dell XPS laptop that came with Ubuntu preinstalled][10]. This is the only device that has required pretty much no hardware troubleshoot from my end even when I have installed Ubuntu-based distributions manually.
|
||||
|
||||
I am happy to see Lenovo doing the extra effort to improve Linux compatibility on its end. There is one more option in the [list of Linux preloaded computers][11] now.
|
||||
|
||||
I don’t know if Lenovo offering Linux on its systems will help increase the Linux user base. Most of the time Windows will be highlighted and Linux version won’t get the prime focus.
|
||||
|
||||
It is still commendable of Lenovo for their efforts to make their devices more Linux friendly. I hope other manufacturers do the same. There is no harm in hoping :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/lenovo-linux-certified/
|
||||
|
||||
作者:[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://en.wikipedia.org/wiki/ThinkPad
|
||||
[2]: https://www.ibm.com/
|
||||
[3]: https://in.pcmag.com/laptops/38093/10-years-later-looking-back-at-the-ibm-lenovo-pc-deal
|
||||
[4]: https://www.phoronix.com/scan.php?page=news_item&px=mtiyotg
|
||||
[5]: https://www.engadget.com/2016-09-21-lenovo-pc-linux-trouble.html
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/06/lenevo-linux-certified-systems.jpg?ssl=1
|
||||
[7]: https://news.lenovo.com/pressroom/press-releases/lenovo-brings-linux-certification-to-thinkpad-and-thinkstation-workstation-portfolio-easing-deployment-for-developers-data-scientists/
|
||||
[8]: https://ubuntu.com/
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/06/thinkpad-ubuntu.jpg?resize=800%2C582&ssl=1
|
||||
[10]: https://itsfoss.com/dell-xps-13-ubuntu-review/
|
||||
[11]: https://itsfoss.com/get-linux-laptops/
|
Loading…
Reference in New Issue
Block a user