Merge pull request #2 from LCTT/master

sync with LCTT
This commit is contained in:
Sun Yongfei 2018-01-29 20:20:25 +08:00 committed by GitHub
commit 52024ad74c
9 changed files with 488 additions and 472 deletions

View File

@ -15,19 +15,17 @@
好,让我们直接来看第一个 bug。这是我在 Dropbox 工作时遇到的一个 bug。你们或许听说过Dropbox 是一个将你的文件从一个电脑上同步到云端和其他电脑上的应用。
```
+--------------+ +---------------+
| | | |
| METASERVER | | BLOCKSERVER |
| 元数据服务器 | | 块服务器 |
| | | |
+-+--+---------+ +---------+-----+
^ | ^
| | |
| | +----------+ |
| +---> | | |
| | CLIENT +--------+
| | 客户端 +--------+
+--------+ |
+----------+
```
@ -79,7 +77,7 @@
l \x0c < $ ( . -
```
英文逗号的 ASCII 码是44。`l` 的 ASCII 码是 108。它们的二进制表示如下
英文逗号的 ASCII 码是 44。`l` 的 ASCII 码是 108。它们的二进制表示如下
```
bin(ord(',')): 0101100
@ -101,8 +99,7 @@ $ : 0100100
- : 0101101
```
### 位反转是真的!
#### 位反转是真的!
我爱这个 bug 因为它证明了位反转是可能真实发生的事情,而不只是一个理论上的问题。实际上,它在某些情况下会比平时更容易发生。其中一种情况是用户使用的是低配或者老旧的硬件,而运行 Dropbox 的电脑很多都是这样。另外一种会造成很多位反转的地方是外太空——在太空中没有大气层来保护你的内存不受高能粒子和辐射的影响,所以位反转会十分常见。
@ -110,31 +107,31 @@ $ : 0100100
在刚才那种情况下Dropbox 并不需要处理位反转。出现内存损坏的是用户的电脑,所以即使我们可以检测到逗号字符的位反转,但如果这发生在其他字符上我们就不一定能检测到了,而且如果从硬盘中读取的文件本身发生了位反转,那我们根本无从得知。我们能改进的地方很少,于是我们决定无视这个异常并继续程序的运行。这种 bug 一般都会在客户端重启之后自动解决。
### 不常见的 bug 并非不可能发生
#### 不常见的 bug 并非不可能发生
这是我最喜欢的 bug 之一,有几个原因。第一,它提醒我注意不常见和不可能之间的区别。当规模足够大的时候,不常见的现象会以值得注意的频率发生。
### 覆盖面广的 bug
#### 覆盖面广的 bug
这个 bug 第二个让我喜欢的地方是它覆盖面非常广。每当桌面客户端和服务器交流的时候,这个 bug 都可能悄然出现,而这可能会发生在系统里很多不同的端点和组件当中。这意味着许多不同的 Dropbox 工程师会看到这个 bug 的各种版本。你第一次看到它的时候,你 _真的_ 会满头雾水,但在那之后诊断这个 bug 就变得很容易了,而调查过程也非常简短:你只需找到中间的字母,看它是不是个 `l`
### 文化差异
#### 文化差异
这个 bug 的一个有趣的副作用是它展示了服务器组和客户端组之间的文化差异。有时候这个 bug 会被服务器组的成员发现并展开调查。如果你的 _服务器_ 上发生了位反转,那应该不是个偶然——这很可能是内存损坏,你需要找到受影响的主机并尽快把它从集群中移除,不然就会有损坏大量用户数据的风险。这是个事故,而你必须迅速做出反应。但如果是用户的电脑在破坏数据,你并没有什么可以做的。
### 分享你的 bug
#### 分享你的 bug
如果你在调试一个难搞的 bug特别是在大型系统中不要忘记跟别人讨论。也许你的同事以前就遇到过类似的 bug。若是如此你可能会节省很多时间。就算他们没有见过也不要忘记在你解决了问题之后告诉他们解决方法——写下来或者在组会中分享。这样下次你们组遇到类似的问题时你们都会早有准备。
### Bug 如何帮助你进步
### Recurse Center
#### Recurse Center
在加入 Dropbox 之前,我曾在 Recurse Center 工作。它的理念是建立一个社区让正在自学的程序员们聚到一起来提高能力。这就是 Recurse Center 的全部了:我们没有大纲、作业、截止日期等等。唯一的前提条件是我们都想要成为更好的程序员。参与者中有的人有计算机学位但对自己的实际编程能力不够自信,有的人已经写了十年 Java 但想学 Clojure 或者 Haskell还有各式各样有着其他的背景的参与者。
我在那里是一位导师,帮助人们更好地利用这个自由的环境,并参考我们从以前的参与者那里学到的东西来提供指导。所以我的同事们和我本人都非常热衷于寻找对成年自学者最有帮助的学习方法。
### 刻意练习
#### 刻意练习
在学习方法这个领域有很多不同的研究,其中我觉得最有意思的研究之一是刻意练习的概念。刻意练习理论意在解释专业人士和业余爱好者的表现的差距。它的基本思想是如果你只看内在的特征——不论先天与否——它们都无法非常好地解释这种差距。于是研究者们,包括最初的 Ericsson、Krampe 和 Tesch-Romer开始寻找能够解释这种差距的理论。他们最终的答案是在刻意练习上所花的时间。
@ -189,18 +186,15 @@ $ : 0100100
所有这些 bug 都很容易修复。前两个 bug 出在客户端上,所以我们在 alpha 版本修复了它们,但大部分的客户端还没有获得这些改动。我们在服务器代码中修复了第三个 bug 并部署了新版的服务器。
### 📈
#### 📈
突然日志服务器集群的流量开始激增。客服团队找到我们并问我们是否知道原因。我花了点时间把所有的部分拼到一起。
在修复之前,这四件事情会发生:
1. 日志文件从最早的开始发送
2. 日志文件从最新的开始删除
3. 如果服务器无法解码日志文件,它会返回 500
4. 如果客户端收到 500它会停止发送日志
一个存有损坏的日志文件的客户端会试着发送这个文件,服务器会返回 500客户端会放弃发送日志。在下一次运行时它会尝试再次发送同样的文件再次失败并再次放弃。最终日志目录会被填满然后客户端会开始删除最新的日志文件而把损坏的文件继续保留在硬盘上。
@ -209,27 +203,27 @@ $ : 0100100
问题是,处于这种状态的客户端比我们想象的要多很多。任何有一个损坏文件的客户端都会像被关在堤坝里一样,无法再发送日志。现在这个堤坝被清除了,所有这些客户端都开始发送它们的日志目录的剩余内容。
### 我们的选择
#### 我们的选择
好的,现在文件从世界各地的电脑如洪水般涌来。我们能做什么?(当你在一个有 Dropbox 这种规模,尤其是这种桌面客户端的规模的公司工作时,会遇到这种有趣的事情:你可以非常轻易地对自己造成 DDOS 攻击)。
好的,现在文件从世界各地的电脑如洪水般涌来。我们能做什么?(当你在一个有 Dropbox 这种规模,尤其是这种桌面客户端的规模的公司工作时,会遇到这种有趣的事情:你可以非常轻易地对自己造成 DDoS 攻击)。
当你部署的新版本发生问题时,第一个选项是回滚。这是非常合理的选择,但对于这个问题,它无法帮助我们。我们改变的不是服务器的状态而是客户端的——我们删除了那些出错文件。将服务器回滚可以防止更多客户端进入这种状态,但它并不能解决根本问题。
那扩大日志集群的规模呢?我们试过了——然后因为处理能力增加了,我们开始收到更多的请求。我们又扩大了一次,但你不可能一直这么下去。为什么不能?因为这个集群并不是独立的。它会向另一个集群发送请求,在这里是为了处理异常。如果你的一个集群正在被 DDOS而你持续扩大那个集群你最终会把它依赖的集群也弄坏然后你就有两个问题了。
那扩大日志集群的规模呢?我们试过了——然后因为处理能力增加了,我们开始收到更多的请求。我们又扩大了一次,但你不可能一直这么下去。为什么不能?因为这个集群并不是独立的。它会向另一个集群发送请求,在这里是为了处理异常。如果你的一个集群正在被 DDoS而你持续扩大那个集群你最终会把它依赖的集群也弄坏然后你就有两个问题了。
我们考虑过的另一个选择是减低负载——你不需要每一个日志文件,所以我们可以直接无视一些请求。一个难点是我们并没有一个很好的方法来区分好的请求和坏的请求。我们无法快速地判断哪些日志文件是旧的,哪些是新的。
我们最终使用的是一个 Dropbox 里许多不同场合都用过的一个解决方法:我们有一个自定义的头字段,`chillout`,全世界所有的客户端都遵守它。如果客户端收到一个有这个头字段的响应,它将在字段所标注的时间内不再发送任何请求。很早以前一个英明的程序员把它加到了 Dropbox 客户端里,在之后这些年中它已经不止一次地起了作用。
### 了解你的系统
#### 了解你的系统
这个 bug 的第一个教训是要了解你的系统。我对于客户端和服务器之间的交互有不错的理解,但我并没有考虑到当服务器和所有这些客户端同时交互的时候会发生什么。这是一个我没有完全搞懂的层面。
### 了解你的工具
#### 了解你的工具
第二个教训是要了解你的工具。如果出了差错,你有哪些选项?你能撤销你做的迁移吗?你如何知道事情出了差错,你又如何发现更多信息?所有这些事情都应该在危机发生之前就了解好——但如果你没有,你会在危机发生时学到它们并不会再忘记。
### 功能开关 & 服务器端功能控制
#### 功能开关 & 服务器端功能控制
第三个教训是专门针对移动端和桌面应用开发者的_你需要服务器端功能控制和功能开关_。当你发现一个问题时如果你没有服务器端的功能控制你可能需要几天或几星期来推送新版本或者提交新版本到应用商店中然后问题才能得到解决。这是个很糟糕的处境。Dropbox 桌面客户端不需要经过应用商店的审查过程,但光是把一个版本推送给上千万的用户就已经要花很多时间。相比之下,如果你能在新功能遇到问题的时候在服务器上翻转一个开关:十分钟之后你的问题就已经解决了。
@ -237,7 +231,7 @@ $ : 0100100
但是它的好处——啊,当你需要它的时候,你真的是很需要它。
# 如何去爱 bug
### 如何去爱 bug
我讲了几个我爱的 bug也讲了为什么要爱 bug。现在我想告诉你如何去爱 bug。如果你现在还不爱 bug我知道唯一一种改变的方法那就是要有成长型心态。
@ -261,7 +255,7 @@ Dweck 发现一个人看待智力的方式——固定型还是成长型心态
这些发现表明成长型心态对 debug 至关重要。我们必须从从困惑中重整旗鼓,诚实地面对我们理解上的不足,并时不时地在寻找答案的路上努力奋斗——成长型心态会让这些都变得更简单而且不那么痛苦。
### 热爱你的 bug
#### 热爱你的 bug
我在 Recurse Center 工作时会直白地欢迎挑战,我就是这样学会热爱我的 bug 的。有时参与者会坐到我身边说“唉,我觉得我遇到了个奇怪的 Python bug”然后我会说“太棒了_爱_ 奇怪的 Python bug” 首先,这百分之百是真的,但更重要的是,我这样是在对参与者强调,找到让自己觉得困难的事情是一种成就,而他们做到了这一点,这是件好事。
@ -274,22 +268,18 @@ Dweck 发现一个人看待智力的方式——固定型还是成长型心态
在此向给我的演讲提出反馈以及给我的演讲提供其他帮助的人士表示感谢:
* Sasha Laundy
* Amy Hanlon
* Julia Evans
* Julian Cooper
* Raphael Passini Diniz 以及其他的 Python Brasil 组织团队成员
--------------------------------------------------------------------------------
via: http://akaptur.com/blog/2017/11/12/love-your-bugs/
作者:[Allison Kaptur ][a]
作者:[Allison Kaptur][a]
译者:[yixunx](https://github.com/yixunx)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -1,3 +1,5 @@
translating-----geekpi
3 Essential Questions to Ask at Your Next Tech Interview
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/os-jobs_0.jpg?itok=nDf5j7xC)

View File

@ -1,103 +0,0 @@
translated by hopefully2333
Meltdown and Spectre Linux Kernel Status
============================================================
By now, everyone knows that something “big” just got announced regarding computer security. Heck, when the [Daily Mail does a report on it][1] , you know something is bad…
Anyway, Im not going to go into the details about the problems being reported, other than to point you at the wonderfully written [Project Zero paper on the issues involved here][2]. They should just give out the 2018 [Pwnie][3] award right now, its that amazingly good.
If you do want technical details for how we are resolving those issues in the kernel, see the always awesome [lwn.net writeup for the details][4].
Also, heres a good summary of [lots of other postings][5] that includes announcements from various vendors.
As for how this was all handled by the companies involved, well this could be described as a textbook example of how  _NOT_  to interact with the Linux kernel community properly. The people and companies involved know what happened, and Im sure it will all come out eventually, but right now we need to focus on fixing the issues involved, and not pointing blame, no matter how much we want to.
### What you can do right now
If your Linux systems are running a normal Linux distribution, go update your kernel. They should all have the updates in them already. And then keep updating them over the next few weeks, we are still working out lots of corner case bugs given that the testing involved here is complex given the huge variety of systems and workloads this affects. If your distro does not have kernel updates, then I strongly suggest changing distros right now.
However there are lots of systems out there that are not running “normal” Linux distributions for various reasons (rumor has it that it is way more than the “traditional” corporate distros). They rely on the LTS kernel updates, or the normal stable kernel updates, or they are in-house franken-kernels. For those people heres the status of what is going on regarding all of this mess in the upstream kernels you can use.
### Meltdown x86
Right now, Linuss kernel tree contains all of the fixes we currently know about to handle the Meltdown vulnerability for the x86 architecture. Go enable the CONFIG_PAGE_TABLE_ISOLATION kernel build option, and rebuild and reboot and all should be fine.
However, Linuss tree is currently at 4.15-rc6 + some outstanding patches. 4.15-rc7 should be out tomorrow, with those outstanding patches to resolve some issues, but most people do not run a -rc kernel in a “normal” environment.
Because of this, the x86 kernel developers have done a wonderful job in their development of the page table isolation code, so much so that the backport to the latest stable kernel, 4.14, has been almost trivial for me to do. This means that the latest 4.14 release (4.14.12 at this moment in time), is what you should be running. 4.14.13 will be out in a few more days, with some additional fixes in it that are needed for some systems that have boot-time problems with 4.14.12 (its an obvious problem, if it does not boot, just add the patches now queued up.)
I would personally like to thank Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Peter Zijlstra, Josh Poimboeuf, Juergen Gross, and Linus Torvalds for all of the work they have done in getting these fixes developed and merged upstream in a form that was so easy for me to consume to allow the stable releases to work properly. Without that effort, I dont even want to think about what would have happened.
For the older long term stable (LTS) kernels, I have leaned heavily on the wonderful work of Hugh Dickins, Dave Hansen, Jiri Kosina and Borislav Petkov to bring the same functionality to the 4.4 and 4.9 stable kernel trees. I had also had immense help from Guenter Roeck, Kees Cook, Jamie Iles, and many others in tracking down nasty bugs and missing patches. I want to also call out David Woodhouse, Eduardo Valentin, Laura Abbott, and Rik van Riel for their help with the backporting and integration as well, their help was essential in numerous tricky places.
These LTS kernels also have the CONFIG_PAGE_TABLE_ISOLATION build option that should be enabled to get complete protection.
As this backport is very different from the mainline version that is in 4.14 and 4.15, there are different bugs happening, right now we know of some VDSO issues that are getting worked on, and some odd virtual machine setups are reporting strange errors, but those are the minority at the moment, and should not stop you from upgrading at all right now. If you do run into problems with these releases, please let us know on the stable kernel mailing list.
If you rely on any other kernel tree other than 4.4, 4.9, or 4.14 right now, and you do not have a distribution supporting you, you are out of luck. The lack of patches to resolve the Meltdown problem is so minor compared to the hundreds of other known exploits and bugs that your kernel version currently contains. You need to worry about that more than anything else at this moment, and get your systems up to date first.
Also, go yell at the people who forced you to run an obsoleted and insecure kernel version, they are the ones that need to learn that doing so is a totally reckless act.
### Meltdown ARM64
Right now the ARM64 set of patches for the Meltdown issue are not merged into Linuss tree. They are [staged and ready to be merged][6] into 4.16-rc1 once 4.15 is released in a few weeks. Because these patches are not in a released kernel from Linus yet, I can not backport them into the stable kernel releases (hey, we have [rules][7] for a reason…)
Due to them not being in a released kernel, if you rely on ARM64 for your systems (i.e. Android), I point you at the [Android Common Kernel tree][8] All of the ARM64 fixes have been merged into the [3.18,][9] [4.4,][10] and [4.9 branches][11] as of this point in time.
I would strongly recommend just tracking those branches as more fixes get added over time due to testing and things catch up with what gets merged into the upstream kernel releases over time, especially as I do not know when these patches will land in the stable and LTS kernel releases at this point in time.
For the 4.4 and 4.9 LTS kernels, odds are these patches will never get merged into them, due to the large number of prerequisite patches required. All of those prerequisite patches have been long merged and tested in the android-common kernels, so I think it is a better idea to just rely on those kernel branches instead of the LTS release for ARM systems at this point in time.
Also note, I merge all of the LTS kernel updates into those branches usually within a day or so of being released, so you should be following those branches no matter what, to ensure your ARM systems are up to date and secure.
### Spectre
Now things get “interesting”…
Again, if you are running a distro kernel, you  _might_  be covered as some of the distros have merged various patches into them that they claim mitigate most of the problems here. I suggest updating and testing for yourself to see if you are worried about this attack vector
For upstream, well, the status is there is no fixes merged into any upstream tree for these types of issues yet. There are numerous patches floating around on the different mailing lists that are proposing solutions for how to resolve them, but they are under heavy development, some of the patch series do not even build or apply to any known trees, the series conflict with each other, and its a general mess.
This is due to the fact that the Spectre issues were the last to be addressed by the kernel developers. All of us were working on the Meltdown issue, and we had no real information on exactly what the Spectre problem was at all, and what patches were floating around were in even worse shape than what have been publicly posted.
Because of all of this, it is going to take us in the kernel community a few weeks to resolve these issues and get them merged upstream. The fixes are coming in to various subsystems all over the kernel, and will be collected and released in the stable kernel updates as they are merged, so again, you are best off just staying up to date with either your distributions kernel releases, or the LTS and stable kernel releases.
Its not the best news, I know, but its reality. If its any consolation, it does not seem that any other operating system has full solutions for these issues either, the whole industry is in the same boat right now, and we just need to wait and let the developers solve the problem as quickly as they can.
The proposed solutions are not trivial, but some of them are amazingly good. The [Retpoline][12] post from Paul Turner is an example of some of the new concepts being created to help resolve these issues. This is going to be an area of lots of research over the next years to come up with ways to mitigate the potential problems involved in hardware that wants to try to predict the future before it happens.
### Other arches
Right now, I have not seen patches for any other architectures than x86 and arm64\. There are rumors of patches floating around in some of the enterprise distributions for some of the other processor types, and hopefully they will surface in the weeks to come to get merged properly upstream. I have no idea when that will happen, if you are dependant on a specific architecture, I suggest asking on the arch-specific mailing list about this to get a straight answer.
### Conclusion
Again, update your kernels, dont delay, and dont stop. The updates to resolve these problems will be continuing to come for a long period of time. Also, there are still lots of other bugs and security issues being resolved in the stable and LTS kernel releases that are totally independent of these types of issues, so keeping up to date is always a good idea.
Right now, there are a lot of very overworked, grumpy, sleepless, and just generally pissed off kernel developers working as hard as they can to resolve these issues that they themselves did not cause at all. Please be considerate of their situation right now. They need all the love and support and free supply of their favorite beverage that we can provide them to ensure that we all end up with fixed systems as soon as possible.
--------------------------------------------------------------------------------
via: http://kroah.com/log/blog/2018/01/06/meltdown-status/
作者:[Greg Kroah-Hartman ][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://kroah.com
[1]:http://www.dailymail.co.uk/sciencetech/article-5238789/Intel-says-security-updates-fix-Meltdown-Spectre.html
[2]:https://googleprojectzero.blogspot.fr/2018/01/reading-privileged-memory-with-side.html
[3]:https://pwnies.com/
[4]:https://lwn.net/Articles/743265/
[5]:https://lwn.net/Articles/742999/
[6]:https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti
[7]:https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
[8]:https://android.googlesource.com/kernel/common/
[9]:https://android.googlesource.com/kernel/common/+/android-3.18
[10]:https://android.googlesource.com/kernel/common/+/android-4.4
[11]:https://android.googlesource.com/kernel/common/+/android-4.9
[12]:https://support.google.com/faqs/answer/7625886

View File

@ -1,103 +0,0 @@
translating---geekpi
How to install Spotify application on Linux
======
How do I install Spotify app on Ubuntu Linux desktop to stream music?
Spotify is a digital music stream service that provides you access to tons of songs. You can stream for free or buy a subscription. Creating a playlist is possible. A subscriber can listen music ad-free. You get better sound quality. This page **shows how to install Spotify on Linux using a snap package manager that works on Ubuntu, Mint, Debian, Fedora, Arch and many other distros**.
### Installing spotify application on Linux
The procedure to install spotify on Linux is as follows:
1. Install snapd
2. Turn on snapd
3. Find Spotify snap:
```
snap find spotify
```
4. Install spotify music app:
```
do snap install spotify
```
5. Run it:
```
spotify &
```
Let us see all steps and examples in details.
### Step 1 - Install Snapd
You need to install snapd package. It is daemon (service) and tooling that enable snap packages on Linux operating system.
#### Snapd on a Debian/Ubuntu/Mint Linux
Type the following [apt command][1]/[apt-get command][2] as follows:
`$ sudo apt install snapd`
#### Install snapd on an Arch Linux
snapd is available in the Arch User Repository (AUR) only. Run yaourt command (see [how to install yaourt on Archlinux][3]):
```
$ sudo yaourt -S snapd
$ sudo systemctl enable --now snapd.socket
```
#### Get snapd on a Fedora Linux
Run snapd command
```
sudo dnf install snapd
sudo ln -s /var/lib/snapd/snap /snap
```
#### OpenSUSE install snapd
Execute the snap command:
`$ snap find spotify`
[![snap search for spotify app command][4]][4]
Install it:
`$ sudo snap install spotify`
[![How to install Spotify application on Linux using snap command][5]][5]
### Step 3 - Run spotify and enjoy it(译注原博客中就是这么直接跳到step3的)
Run it from GUI or simply type:
`$ spotify`
Automatically sign in to your account on startup:
```
$ spotify --username vivek@nixcraft.com
$ spotify --username vivek@nixcraft.com --password 'myPasswordHere'
```
Start spotify client with given URI when initialized:
`$ spotify--uri=<uri>`
Start with the specified URL:
`$ spotify--url=<url>`
[![Spotify client app running on my Ubuntu Linux desktop][6]][6]
### About the author
The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9].
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-install-spotify-application-on-linux/
作者:[Vivek Gite][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
[3]:https://www.cyberciti.biz/faq/how-to-install-yaourt-in-arch-linux/
[4]:https://www.cyberciti.biz/media/new/faq/2018/01/snap-search-for-spotify-app-command.jpg
[5]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Spotify-application-on-Linux-using-snap-command.jpg
[6]:https://www.cyberciti.biz/media/new/faq/2018/01/Spotify-client-app-running-on-my-Ubuntu-Linux-desktop.jpg
[7]:https://twitter.com/nixcraft
[8]:https://facebook.com/nixcraft
[9]:https://plus.google.com/+CybercitiBiz

View File

@ -1,235 +0,0 @@
translating by wenwensnow
Shell Scripting a Bunco Game
======
I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern.
Played in six rounds with three dice, the game is simple. You roll all three dice and have to match the current round number. If all three dice match the current round number (for example, three 3s in round three), you score 21\. If all three match but aren't the current round number, it's a Mini Bunco and worth five points. Failing both of those, each die with the same value as the round number is worth one point.
Played properly, the game also involves teams, multiple tables including a winner's table, and usually cash prizes funded by everyone paying $5 or similar to play and based on specific winning scenarios like "most Buncos" or "most points". I'll skip that part here, however, and just focus on the dice part.
### Let's Do the Math
Before I go too far into the programming side of things, let me talk briefly about the math behind the game. Dice are easy to work with because on a properly weighted die, the chance of a particular value coming up is 1:6.
Random tip: not sure whether your dice are balanced? Toss them in salty water and spin them. There are some really interesting YouTube videos from the D&D world showing how to do this test.
So what are the odds of three dice having the same value? The first die has a 100% chance of having a value (no leaners here), so that's easy. The second die has a 16.66% chance of being any particular value, and then the third die has the same chance of being that value, but of course, they multiply, so three dice have about a 2.7% chance of all having the same value.
Then, it's a 16.66% chance that those three dice would be the current round's number—or, in mathematical terms: 0.166 * 0.166 * 0.166 = 0.00462.
In other words, you have a 0.46% chance of rolling a Bunco, which is a bit less than once out of every 200 rolls of three dice.
It could be tougher though. If you were playing with five dice, the chance of rolling a Mini Bunco (or Yahtzee) is 0.077%, and if you were trying to accomplish a specific value, say just sixes, then it's 0.00012% likely on any given roll—which is to say, not bloody likely!
### And So into the Coding
As with every game, the hardest part is really having a good random number generator that generates truly random values. That's actually hard to affect in a shell script though, so I'm going to sidestep this entire issue and assume that the shell's built-in random number generator will be sufficient.
What's nice is that it's super easy to work with. Just reference $RANDOM, and you'll have a random value between 0 and MAXINT (32767):
```
$ echo $RANDOM $RANDOM $RANDOM
10252 22142 14863
```
To constrain that to values between 16 use the modulus function:
```
$ echo $(( $RANDOM % 6 ))
3
$ echo $(( $RANDOM % 6 ))
0
```
Oops! I forgot to shift it one. Here's another try:
```
$ echo $(( ( $RANDOM % 6 ) + 1 ))
6
```
That's the dice-rolling feature. Let's make it a function where you can specify the variable you'd like to have the generated value as part of the invocation:
```
rolldie()
{
local result=$1
rolled=$(( ( $RANDOM % 6 ) + 1 ))
eval $result=$rolled
}
```
The use of the eval is to ensure that the variable specified in the invocation is actually assigned the calculated value. It's easy to work with:
```
rolldie die1
```
That will load a random value between 16 into the variable die1. To roll your three dice, it's straightforward:
```
rolldie die1 ; rolldie die2 ; rolldie die3
```
Now to test the values. First, let's test for a Bunco where all three dice have the same value, and it's the value of the current round too:
```
if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then
if [ $die1 -eq $round ] ; then
echo "BUNCO!"
score=25
else
echo "Mini Bunco!"
score=5
fi
```
That's probably the hardest of the tests, and notice the unusual use of test in the first conditional: [ cond1 ] && [ cond2 ]. If you're thinking that you could also write it as cond1 -a cond2, you're right. As with so much in the shell, there's more than one way to get to the solution.
The remainder of the code is straightforward; you just need to test for whether the die matches the current round value:
```
if [ $die1 -eq $round ] ; then
score=1
fi
if [ $die2 -eq $round ] ; then
score=$(( $score + 1 ))
fi
if [ $die3 -eq $round ] ; then
score=$(( $score + 1 ))
fi
```
The only thing to consider here is that you don't want to score die value vs. round if you've also scored a Bunco or Mini Bunco, so the entire second set of tests needs to be within the else clause of the first conditional (to see if all three dice have the same value).
Put it together and specify the round number on the command line, and here's what you have at this point:
```
$ sh bunco.sh 5
You rolled: 1 1 5
score = 1
$ sh bunco.sh 2
You rolled: 6 4 3
score = 0
$ sh bunco.sh 1
You rolled: 1 1 1
BUNCO!
score = 25
```
A Bunco so quickly? Well, as I said, there might be a slight issue with the randomness of the random number generator in the shell.
You can test it once you have the script working by running it a few hundred times and then checking to see what percentage are Bunco or Mini Bunco, but I'll leave that as an exercise for you, dear reader. Well, maybe I'll come back to it another time.
Let's finish up this script by having it accumulate score and run for all six rounds instead of specifying a round on the command line. That's easily done, because it's just a wrapper around the entire script, or, better, the big conditional statement becomes a function all its own:
```
BuncoRound()
{
# roll, display, and score a round of bunco!
# round is specified when invoked, score added to totalscore
local score=0 ; local round=$1 ; local hidescore=0
rolldie die1 ; rolldie die2 ; rolldie die3
echo Round $round. You rolled: $die1 $die2 $die3
if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then
if [ $die1 -eq $round ] ; then
echo " BUNCO!"
score=25
hidescore=1
else
echo " Mini Bunco!"
score=5
hidescore=1
fi
else
if [ $die1 -eq $round ] ; then
score=1
fi
if [ $die2 -eq $round ] ; then
score=$(( $score + 1 ))
fi
if [ $die3 -eq $round ] ; then
score=$(( $score + 1 ))
fi
fi
if [ $hidescore -eq 0 ] ; then
echo " score this round: $score"
fi
totalscore=$(( $totalscore + $score ))
}
```
I admit, I couldn't resist a few improvements as I went along, including the addition of it showing either Bunco, Mini Bunco or a score value (that's what $hidescore does).
Invoking it is a breeze, and you'll use a for loop:
```
for round in {1..6} ; do
BuncoRound $round
done
```
That's about the entire program at this point. Let's run it once and see what happens:
```
$ sh bunco.sh 1
Round 1\. You rolled: 2 3 3
score this round: 0
Round 2\. You rolled: 2 6 6
score this round: 1
Round 3\. You rolled: 1 2 4
score this round: 0
Round 4\. You rolled: 2 1 4
score this round: 1
Round 5\. You rolled: 5 5 6
score this round: 2
Round 6\. You rolled: 2 1 3
score this round: 0
Game over. Your total score was 4
```
Ugh. Not too impressive, but it's probably a typical round. Again, you can run it a few hundred—or thousand—times, just save the "Game over" line, then do some quick statistical analysis to see how often you score more than 3 points in six rounds. (With three dice to roll a given value, you should hit that 50% of the time.)
It's not a complicated game by any means, but it makes for an interesting little programming project. Now, what if they used 20-sided die and let you re-roll one die per round and had a dozen rounds?
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/shell-scripting-bunco-game
作者:[Dave Taylor][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/users/dave-taylor

View File

@ -1,3 +1,5 @@
Translating by yizhuoyan
Linux rm Command Explained for Beginners (8 Examples)
======

View File

@ -0,0 +1,102 @@
meltdown 和 spectre 影响下的 Linux 内核状况
============================================================
截止到目前为止,每个人都知道一件关乎电脑安全的“大事”发生了,真见鬼,等每日邮报报道的时候,你就知道什么是糟糕了...
不管怎样,我不打算去跟进这个问题被报道出来的细节,除了告诉你问题涉及范围内的精彩的零日文章,他们应该直接发布 2018 的 Pwnie award 奖,这非常好。
如果你想了解我们如何在内核中解决这些问题的技术细节,你可以持续关注了不起的 lwn.net他们会把这些细节写成文章。
以此同时,很多的厂商发出了相关的公告,这有一条很好的关于这些公告的摘要。
至于这些涉及的公司是如何处理这些问题的,这可以说是如何适当的与 Linux 内核社区保持距离的教科书般的例子。这件事涉及到的人和公司都知道发生了什么,我确定这件事最终会出现,但是目前我需要去关注的是如何修复这些涉及到的问题,然后不要去点名指责,不管我有多么的想去这么做。
### 你现在能做什么
如果你的 Linux 系统正在运行一个正常的 Linux 分布式系统,那么升级你的内核。它们都应该已经更新了,然后在接下来的几个星期里保持更新。我们会统计大量在极端情况下出现的 bug ,这个情况的测试范围是复杂的,包括庞大的受影响的各种各样的系统和工作量。如果你的 Linux 发行版没有内核升级,我坚决的建议你马上更换你使用的 Linux 发行版。
然而有很多的系统因为各种各样的原因它们比起相对“传统”的公司的分布式系统更加特殊不是在运行“正常的”Linux 分布式系统。它们依靠长期支持版本的内核升级,或者是正常稳定的内核升级,或者是内部的 franken-kernels。对于这部分人这个状况是在你能使用的上游的内核中关于这个混乱正在发生的。
### Meltdown x86
现在Linux 内核树包含所有我们当前知道的为 x86 架构解决 meltdown 漏洞的修复。去开启 CONFIG_PAGE_TABLE_ISOLATION 这个内核构建选项,然后进行重构和重启,所有的设备应该就安全了。
然而Linux 的代码树分支在 4.15-rc6 这个版本加上一些出色的补丁。4.15-rc7 版本要明天才会推出,里面的一些补丁会解决一些问题。但是大部分的人不会运行 -rc kernel 在一个“正常”的环境里。
因为这个原因x86 内核开发者在页表隔离代码开发过程中做了一个非常好的工作好到以至于移植到了最新推出的稳定内核4.14,对我们要做的事而言几乎是微不足道的了。这意味着最新的 4.14版本(现在是 4.14.12 版本是你应该正在运行的版本4.14.13 会在接下来的几天里推出,这个更新里有一些额外的修复补丁,这些补丁是一些运行 4.14.12 内核且有启动时间问题(这是一个显而易见的问题,如果它不启动,手动把这些补丁加入更新排队中)的系统所需要的。
我个人要去感谢 Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Peter Zijlstra, Josh Poimboeuf, Juergen Gross, 和 Linus Torvalds。他们开发出了这些修复补丁并且为了让我们能简单地更新到稳定版本来正常工作还把这些补丁用一张表单融合到了上游分支里。没有这些工作我甚至不会想要去思考到底发生了什么。
对于老的长期支持内核,我大量地依靠 Hugh Dickins, Dave Hansen, Jiri Kosina 和 Borislav Petkov 优秀的工作所带来的针对 4.4 到 4.9 稳定内核代码树分支的相同功能。我同样在追踪讨厌的bug和缺失的补丁方面从 Guenter Roeck, Kees Cook, Jamie Iles,以及其他很多人那里得到了极大的帮助。我要感谢 David Woodhouse, Eduardo Valentin, Laura Abbott, 和 Rik van Riel 在反向移植和集成方面的帮助,他们的帮助在许多棘手的地方是必不可少的。
这些长期支持版本的内核同样有 CONFIG_PAGE_TABLE_ISOLATION 这个内核构建选项,你应该开启它来获得全方面的保护。
主要版本 4.14 和 4.15 的移植是非常不一样的,他们会出现不同的 bug我们现在知道了一些在工作中遇见的 VDSO 上的问题。一些特殊的虚拟机安装的时候会报一些奇怪的错,但这是只是现在出现的少部分情况,这中情况不会阻止你进行全部的升级,请让我们在稳定内核邮件列表中知道这件事。
如果你依赖 4.4 和 4.9 以外的内核代码树分支或是现在的 4.14,并且没有分布式支持你的话,你就太不幸了。比起你当前版本内核包含的上百个已知的漏洞和 bug缺少补丁去解决 meltdown 问题算是一个小问题了。你现在最需要考虑的就是马上把你的系统升级到最新。
以此同时,臭骂那些强迫你运行一个已被废弃且不安全的内核版本的人,他们是那些需要知道这是完全不顾后果的行为的人中的一份子。
### Meltdown ARM64
现在 ARM64 为解决 Meltdown 问题而开发的补丁还没有并入 Linux 的代码树分支,一旦 4.15 在接下来的几周里成功发布,他们就准备阶段式地并入 4.16-rc1因为这些补丁还没有在一个已发布的 Linux 内核中,我不能把它们移植进一个稳定的内核版本里(额。。我们有这个规矩是有原因的)
由于它们还没有在一个已发布的内核版本中,如果你的系统是用的 ARM64 的芯片(例如 Android ),我建议你在现在所有并入 3.18,4.4 和 4.9 分支的 ARM64 补丁中选择 Android 公共内核代码树分支。
我强烈建议你关注这些分支,看随着时间的过去,由于测试了已并入补丁的已发布的上游内核版本,会不会有更多的修复补丁被补充进来,特别是我不知道这些补丁会在什么时候加进稳定的长期支持内核版本里。
对于 4.4 到 4.9 的长期支持内核版本,这些补丁有很大概率永远不会并入它们,因为需要大量的依赖性补丁。而所有的这些依赖性补丁长期以来都一直在 Android 公共内核版本中测试和合并,所以我认为现在对于 ARM 系统来说,仅仅依赖这些内核分支而不是长期支持的发行版是一个更好的主意。
同样需要注意的是,我合并所有的长期支持内核版本的更新到这些分支后通常会在一天之内或者这个时间点左右进行发布,所以你无论如何都要关注这些分支,来确保你的 ARM 系统是最新且安全的。
### Spectre
现在,事情变得“有趣”了...
再一次,如果你正在运行一个发行版的内核。一些内核融入了各种各样的声称能缓解目前大部分问题的补丁,你的内核可能就被包含在其中。如果你担心这一类的攻击的话,我建议你更新并测试看看。
对于上游来说,很好,现状就是仍然没有任何的上游代码树分支有合并这些类型的问题相关的修复补丁。有很多的邮件列表在讨论如何去解决这些问题的解决方案,大量的补丁在这些邮件列表中广为流传,但是它们被压在了沉重的开发下,一些补丁系列甚至没有被构建或者应用到任何已知的代码树,这些系列彼此之间相互冲突,这是常见的混乱。
这是由于 Spectre 问题是最近被内核开发者解决的。我们所有人都在 Meltdown 问题上工作,我们没有精确的 Spectre 问题全部的真实信息,也没有比公开发布更糟糕的情形下什么补丁会广为流传的的真实信息。
因为所有的这些原因,我们打算在内核社区里花上几个星期去解决这些问题并把它们合并到内核中去。修复补丁会进入到所有内核的各种各样的子系统中,而且在它们被合并后,会集成并在稳定内核的更新中发布,所以再次提醒,你最好是在你使用的内核发行版和长期支持稳定的内核发行版中选择一个并保持更新到最新版。
这不是最好的新闻,我知道,但是这就是现实。如果它是任意的安慰的话,它就不会显得其他的操作系统也为这些问题准备了完整的解决方案,现在整个产业都在同一条船上,我们只需要等待,并让开发者尽他们所能快地解决这些问题。
计划解决方案已经不重要了但是它们中的一些还是非常好的。一些新概念会被创造出来来帮助解决这些问题Paul Turner 提出的 Retpoline 方法就是其中的一个例子。这将是未来大量研究的一个领域,想出方法去减轻硬件中涉及的潜在问题,想在它发生前就去预言它。
### 其他的 arches 芯片
现在,我没有看见任何 x86 和 arm64 架构以外的芯片架构的补丁,有一些谣传的补丁在一些企业为其他类型的处理器准备的分配方案中广为流传。希望他们在这几周里能在表面上适当地合并到开发者那里,这件事发生的时候我不知道,如果你使用着一个特殊的架构,我建议在 arch-specific 邮件列表上问这件事来得到一个直接的回答。
### 结论
再次更新你的内核不要耽搁不要停止。更新会在很长的一段时间里持续地解决这些问题。同样的稳定和长期支持内核发行版里仍然有很多其他的bug和安全问题他们和问题的类型无关所以一直保持更新始终是一个好主意。
现在,这里有很多非常劳累、坏脾气、缺少睡眠的人,他们通常会生气地让内核开发人员竭尽全力地解决这些问题,即使这些问题完全不是他们自己造成的。请关爱这些可怜的程序猿。他们需要爱、支持和我们可以为他们免费提供的他们最爱的饮料,以此来确保我们都可以尽可能快地结束修补系统。
--------------------------------------------------------------------------------
via: http://kroah.com/log/blog/2018/01/06/meltdown-status/
作者:[Greg Kroah-Hartman ][a]
译者:[hopefully2333](https://github.com/hopefully2333)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://kroah.com
[1]:http://www.dailymail.co.uk/sciencetech/article-5238789/Intel-says-security-updates-fix-Meltdown-Spectre.html
[2]:https://googleprojectzero.blogspot.fr/2018/01/reading-privileged-memory-with-side.html
[3]:https://pwnies.com/
[4]:https://lwn.net/Articles/743265/
[5]:https://lwn.net/Articles/742999/
[6]:https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti
[7]:https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
[8]:https://android.googlesource.com/kernel/common/
[9]:https://android.googlesource.com/kernel/common/+/android-3.18
[10]:https://android.googlesource.com/kernel/common/+/android-4.4
[11]:https://android.googlesource.com/kernel/common/+/android-4.9
[12]:https://support.google.com/faqs/answer/7625886

View File

@ -0,0 +1,101 @@
如何在 Linux 上安装 Spotify
======
如何在 Ubuntu Linux 桌面上安装 Spotify 来在线听音乐?
Spotify 是一个可让你访问大量歌曲的数字音乐流服务。你可以免费收听或者购买订阅。可以创建播放列表。订阅用户可以免广告收听音乐。你会得到更好的音质。本教程**展示如何使用在 Ubuntu、Mint、Debian、Fedora、Arch 和其他更多发行版**上的 snap 包管理器安装 Spotify。
### 在 Linux 上安装 spotify
在 Linux 上安装 spotify 的步骤如下:
1. 安装 snapd
2. 打开 snapd
3. 找到 Spotify snap
```
snap find spotify
```
4. 安装 spotify
```
do snap install spotify
```
5. 运行:
```
spotify &
```
让我们详细看看所有的步骤和例子。
### 步骤 1 - 安装 Snapd
你需要安装 snapd 包。它是一个守护进程(服务),并能在 Linux 系统上启用 snap 包管理。
#### Debian/Ubuntu/Mint Linux 上的 Snapd
输入以下[ apt 命令][1]/ [apt-get 命令][2]
`$ sudo apt install snapd`
#### 在 Arch Linux 上安装 snapd
snapd 只包含在 Arch User RepositoryAUR中。运行 yaourt 命令(参见[如何在 Archlinux 上安装 yaourt][3]
```
$ sudo yaourt -S snapd
$ sudo systemctl enable --now snapd.socket
```
#### 在 Fedora 上获取 snapd
运行 snapd 命令
```
sudo dnf install snapd
sudo ln -s /var/lib/snapd/snap /snap
```
#### OpenSUSE 安装 snapd
执行 snap 命令:
`$ snap find spotify`
[![snap search for spotify app command][4]][4]
安装它:
`$ sudo snap install spotify`
[![How to install Spotify application on Linux using snap command][5]][5]
### 步骤 3 - 运行 spotify 并享受它(译注:原博客中就是这么直接跳到 step3 的)
从 GUI 运行它,或者只需输入:
`$ spotify`
在启动时自动登录你的帐户:
```
$ spotify --username vivek@nixcraft.com
$ spotify --username vivek@nixcraft.com --password 'myPasswordHere'
```
在初始化时使用给定的 URI 启动 Spotify 客户端:
`$ spotify--uri=<uri>`
以指定的网址启动:
`$ spotify--url=<url>`
[![Spotify client app running on my Ubuntu Linux desktop][6]][6]
### 关于作者
作者是 nixCraft 的创建者,是经验丰富的系统管理员,也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及 IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][7]、[Facebook][8]、[Google +][9] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-install-spotify-application-on-linux/
作者:[Vivek Gite][a]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
[3]:https://www.cyberciti.biz/faq/how-to-install-yaourt-in-arch-linux/
[4]:https://www.cyberciti.biz/media/new/faq/2018/01/snap-search-for-spotify-app-command.jpg
[5]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Spotify-application-on-Linux-using-snap-command.jpg
[6]:https://www.cyberciti.biz/media/new/faq/2018/01/Spotify-client-app-running-on-my-Ubuntu-Linux-desktop.jpg
[7]:https://twitter.com/nixcraft
[8]:https://facebook.com/nixcraft
[9]:https://plus.google.com/+CybercitiBiz

View File

@ -0,0 +1,260 @@
 脚本编程之骰子游戏
======
我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:光晕系列游戏)但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。
游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如在第三轮三个骰子都是3)你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同你会得到最低的Bunco分数只有5分。如果你投出的点数两者都不是每一个和当前轮数相同的骰子得1分。
要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队)每人付5美元现金或赢家得到其他类似现金奖励并规定什么样的情况下才是赢家例如"most Buncos" or "most points"的情况下胜利。在这里我会跳过这些,而只关注投骰子这一部分。
### 关于数学逻辑部分
在专注于编程这方面的事之前,我先简单说说游戏背后的数学逻辑。要是有一个适当重量的骰子投骰子会变得很容易,任意一个值出现概率都是 1/6。
完全随机小提示:不确定你的骰子是否每个面都是一样重量? 把它们扔进盐水里然后转一下。YouTube上有很多科学界的有趣视频向你展示怎么来做这个测试。
所以三个骰子点数一样的几率有多大? 第一个骰子100%会有一个值 (这儿没什么可说的)所以很简单。第二个则有16.66%的概率和第一个骰子的值一样,接下来第三个骰子也是一样。 但当然总概率是三个概率相乘的结果所以最后三个骰子值相等的概率是2.7%。
接下来每个骰子和当前轮数数字相同的概率都是16.66%。从数学角度来说0.166 * 0.166 * 0.166 = 0.00462。
换句话说你有0.46%的可能性投出Bunco,比200次中出现一次的可能性还小一点。
实际上还可以更难。如果你有5个骰子投出 Mini Bunco (也可以叫做Yahtzee) 的概率为0.077%如果你想所有的骰子的值都相同假设都是6那概率就是0.00012%,那就基本上没什么可能了。
### 开始编程吧
和所有游戏一样最难的部分是有一个能生成随机数的随机数发生器。这一部分在shell 脚本中还是很难实现的所以我需要一步步来并假设shell内置的随机数发生器就够用了
不过好在内置的随机数发生器很好用。用 $RANDOM 就能得到一个0到MAXINT(32767)之间的随机值:
```
$ echo $RANDOM $RANDOM $RANDOM
10252 22142 14863
```
为了确保产生的值一定是 1-6之中的某个值使用取余函数
```
$ echo $(( $RANDOM % 6 ))
3
$ echo $(( $RANDOM % 6 ))
0
```
我忘了要加1下面是另一次尝试
```
$ echo $(( ( $RANDOM % 6 ) + 1 ))
6
```
下面要实现投骰子这一功能。这个函数中你可以声明一个局部变量来存储生成的随机值:
```
rolldie()
{
local result=$1
rolled=$(( ( $RANDOM % 6 ) + 1 ))
eval $result=$rolled
}
```
使用 eval 确保生成的随机数被实际存储在变量中。这一部分也很容易:
```
rolldie die1
```
这会为第一个骰子生成一个1-6之中的值。要为3个骰子都生成值执行3次上面的函数
```
rolldie die1 ; rolldie die2 ; rolldie die3
```
现在判断下生成的值。首先判断是不是Bunco(3个骰子值相同),然后是不是和当前轮数值也相同:
```
if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then
if [ $die1 -eq $round ] ; then
echo "BUNCO!"
score=25
else
echo "Mini Bunco!"
score=5
fi
```
这可能是所有判断语句中最难的部分了,注意第一个条件语句中这种不常用的写法 [ cond1 ] && [ cond2 ]。如果你想写成 cond1 -a cond2 这样也可以。在shell编程中解决问题的方法往往不止一种。
代码剩下的部分很直白,你只需要判断每个骰子的值是不是和本轮数字相同:
```
if [ $die1 -eq $round ] ; then
score=1
fi
if [ $die2 -eq $round ] ; then
score=$(( $score + 1 ))
fi
if [ $die3 -eq $round ] ; then
score=$(( $score + 1 ))
fi
```
唯一要注意的是当出现 Bunco/Mini Bunco 就不需要再统计本轮分数了。所以整个第二部分的判断语句都要写在第一个条件语句的else中为了判断3个骰子值是否都相同
把所有的综合起来,然后在命令行中输入轮数,下面是现在的脚本执行后的结果:
```
$ sh bunco.sh 5
You rolled: 1 1 5
score = 1
$ sh bunco.sh 2
You rolled: 6 4 3
score = 0
$ sh bunco.sh 1
You rolled: 1 1 1
BUNCO!
score = 25
```
竟然这么快就出现 Bunco 了? 好吧就像我说的shell内置的随机数发生器在随机数产生这方面可能有些问题。
你可以执行脚本几百次从而让你的脚本得以正确运行然后看看Bunco/Mini Bunco出现次数所占的百分比。但是我想把这部分作为练习留给亲爱的读者你们。不过也许我下次会抽时间完成剩下的部分。
让我们完成这一脚本吧还有分数统计和一次性执行6次投骰子(这次不用再在命令行中手动输入当前轮数了)这两个功能。这也很容易,因为只是将上面的内容整个嵌套在里面,换句话说,就是将一个复杂的条件嵌套结构全部写在了一个函数中:
```
BuncoRound()
{
# roll, display, and score a round of bunco!
# round is specified when invoked, score added to totalscore
local score=0 ; local round=$1 ; local hidescore=0
rolldie die1 ; rolldie die2 ; rolldie die3
echo Round $round. You rolled: $die1 $die2 $die3
if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then
if [ $die1 -eq $round ] ; then
echo " BUNCO!"
score=25
hidescore=1
else
echo " Mini Bunco!"
score=5
hidescore=1
fi
else
if [ $die1 -eq $round ] ; then
score=1
fi
if [ $die2 -eq $round ] ; then
score=$(( $score + 1 ))
fi
if [ $die3 -eq $round ] ; then
score=$(( $score + 1 ))
fi
fi
if [ $hidescore -eq 0 ] ; then
echo " score this round: $score"
fi
totalscore=$(( $totalscore + $score ))
}
```
我承认我忍不住自己做了一点改进包括判断当前是Bunco, Mini Bunco 还是其他需要计算分数的情况这一部分 (这就是$hidescore这一变量的作用).
实现这个简直是小菜一碟,只要一个循环就好了:
```
for round in {1..6} ; do
BuncoRound $round
done
```
这就是现在所写的整个程序。让我们执行一下看看结果:
```
$ sh bunco.sh 1
Round 1\. You rolled: 2 3 3
score this round: 0
Round 2\. You rolled: 2 6 6
score this round: 1
Round 3\. You rolled: 1 2 4
score this round: 0
Round 4\. You rolled: 2 1 4
score this round: 1
Round 5\. You rolled: 5 5 6
score this round: 2
Round 6\. You rolled: 2 1 3
score this round: 0
Game over. Your total score was 4
```
嗯。并不是很令人满意,可能是因为它只是游戏的一次完整执行。不过,你可以将脚本执行几百几千次,记下"Game over"出现的位置然后用一些快速分析工具来看看你在每6轮中有几次得分超过3分。(要让3个骰子值相同这个概率大概在50%左右)。
无论怎么说这都不是一个复杂的游戏但是它是一个很有意思的小程序项目。现在如果有一个20面的骰子每一轮游戏有好几十轮每轮都掷同一个骰子情况又会发生什么变化呢?
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/shell-scripting-bunco-game
作者:[Dave Taylor][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/users/dave-taylor