mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
commit
b773558ad6
121
README.md
121
README.md
@ -5,7 +5,7 @@ LCTT是“Linux中国”([https://linux.cn/](https://linux.cn/))的翻译组
|
||||
|
||||
LCTT 已经拥有几百名活跃成员,并欢迎更多的Linux志愿者加入我们的团队。
|
||||
|
||||
![logo](http://img.linux.net.cn/static/image/common/lctt_logo.png)
|
||||
![logo](https://linux.cn/static/image/common/lctt_logo.png)
|
||||
|
||||
LCTT 的组成
|
||||
-------------------------------
|
||||
@ -21,7 +21,7 @@ LCTT的组成
|
||||
加入我们
|
||||
-------------------------------
|
||||
|
||||
请首先加入翻译组的QQ群,群号是:198889102,加群时请说明是“志愿者”。加入后记得修改您的群名片为您的github的ID。
|
||||
请首先加入翻译组的 QQ 群,群号是:198889102,加群时请说明是“志愿者”。加入后记得修改您的群名片为您的 GitHub 的 ID。
|
||||
|
||||
加入的成员,请先阅读 [WIKI 如何开始](https://github.com/LCTT/TranslateProject/wiki/01-如何开始)。
|
||||
|
||||
@ -34,11 +34,11 @@ LCTT的组成
|
||||
-------------------------------
|
||||
|
||||
* 2013/09/10 倡议并得到了大家的积极响应,成立翻译组。
|
||||
* 2013/09/11 采用github进行翻译协作,并开始进行选题翻译。
|
||||
* 2013/09/11 采用 GitHub 进行翻译协作,并开始进行选题翻译。
|
||||
* 2013/09/16 公开发布了翻译组成立消息后,又有新的成员申请加入了。并从此建立见习成员制度。
|
||||
* 2013/09/24 鉴于大家使用Github的水平不一,容易导致主仓库的一些错误,因此换成了常规的fork+PR的模式来进行翻译流程。
|
||||
* 2013/09/24 鉴于大家使用 GitHub 的水平不一,容易导致主仓库的一些错误,因此换成了常规的 fork+PR 的模式来进行翻译流程。
|
||||
* 2013/10/11 根据对 LCTT 的贡献,划分了 Core Translators 组,最先的加入成员是 vito-L 和 tinyeyeser。
|
||||
* 2013/10/12 取消对LINUX.CN注册用户的依赖,在QQ群内、文章内都采用github的注册ID。
|
||||
* 2013/10/12 取消对 LINUX.CN 注册用户的关联,在 QQ 群内、文章内都采用 GitHub 的注册 ID。
|
||||
* 2013/10/18 正式启动 man 翻译计划。
|
||||
* 2013/11/10 举行第一次北京线下聚会。
|
||||
* 2014/01/02 增加了 Core Translators 成员: geekpi。
|
||||
@ -52,7 +52,11 @@ LCTT的组成
|
||||
* 2015/04/19 发起 LFS-BOOK-7.7-systemd 项目。
|
||||
* 2015/06/09 提升 ictlyh 和 dongfengweixiao 为 Core Translators 成员。
|
||||
* 2015/11/10 提升 strugglingyouth、FSSlc、Vic020、alim0x 为 Core Translators 成员。
|
||||
* 2016/02/18 由于选题 DeadFire 重病,任命 oska874 接手选题工作。
|
||||
* 2016/02/29 选题 DeadFire 病逝。
|
||||
* 2016/05/09 提升 PurlingNayuki 为校对。
|
||||
* 2016/09/10 LCTT 三周年。
|
||||
* 2016/12/24 拟定 LCTT [Core 规则](core.md),并增加新的 Core 成员: @ucasFL、@martin2011qi,及调整一些组。
|
||||
|
||||
活跃成员
|
||||
-------------------------------
|
||||
@ -60,135 +64,108 @@ LCTT的组成
|
||||
目前 TP 活跃成员有:
|
||||
- Leader @wxy,
|
||||
- Source @oska874,
|
||||
- Proofreader @PurlingNayuki,
|
||||
- Proofreaders @jasminepeng,
|
||||
- CORE @geekpi,
|
||||
- CORE @GOLinux,
|
||||
- CORE @ictlyh,
|
||||
- CORE @carolinewuyan,
|
||||
- CORE @strugglingyouth,
|
||||
- CORE @FSSlc
|
||||
- CORE @zpl1025,
|
||||
- CORE @runningwater,
|
||||
- CORE @bazz2,
|
||||
- CORE @Vic020,
|
||||
- CORE @dongfengweixiao,
|
||||
- CORE @alim0x,
|
||||
- CORE @tinyeyeser,
|
||||
- CORE @Locez,
|
||||
- CORE @ucasFL
|
||||
- CORE @martin2011qi
|
||||
- Senior @DeadFire,
|
||||
- Senior @reinoir,
|
||||
- Senior @tinyeyeser,
|
||||
- Senior @reinoir222,
|
||||
- Senior @vito-L,
|
||||
- Senior @jasminepeng,
|
||||
- Senior @willqian,
|
||||
- Senior @vizv,
|
||||
- Senior @dongfengweixiao,
|
||||
- Senior @PurlingNayuki,
|
||||
- Senior @carolinewuyan,
|
||||
- cposture,
|
||||
- ZTinoZ,
|
||||
- theo-l,
|
||||
- luoxcat,
|
||||
- martin2011qi,
|
||||
- Luoxcat,
|
||||
- GHLandy,
|
||||
- wi-cuckoo,
|
||||
- StdioA,
|
||||
- disylee,
|
||||
- haimingfg,
|
||||
- KayGuoWhu,
|
||||
- wwy-hust,
|
||||
- felixonmars,
|
||||
- KayGuoWhu,
|
||||
- mr-ping,
|
||||
- wyangsun,
|
||||
- su-kaiyao,
|
||||
- ivo-wang,
|
||||
- GHLandy,
|
||||
- cvsher,
|
||||
- wyangsun,
|
||||
- OneNewLife
|
||||
- DongShuaike,
|
||||
- flsf,
|
||||
- SPccman,
|
||||
- Stevearzh
|
||||
- mr-ping,
|
||||
- Stevearzh,
|
||||
- bestony,
|
||||
- Linchenguang,
|
||||
- Linux-pdz,
|
||||
- 2q1w2007,
|
||||
- NearTan,
|
||||
- H-mudcup,
|
||||
- cposture,
|
||||
- GitFuture,
|
||||
- MikeCoder,
|
||||
- xiqingongzi,
|
||||
- goreliu,
|
||||
- NearTan,
|
||||
- rusking,
|
||||
- jiajia9linuxer,
|
||||
- name1e5s,
|
||||
- TxmszLou,
|
||||
- ZhouJ-sh,
|
||||
- wangjiezhe,
|
||||
- icybreaker,
|
||||
- zky001,
|
||||
- vim-kakali,
|
||||
- shipsw,
|
||||
- LinuxBars,
|
||||
- Moelf,
|
||||
- Chao-zhi
|
||||
- johnhoow,
|
||||
- soooogreen,
|
||||
- kokialoves,
|
||||
- linuhap,
|
||||
- ChrisLeeGit,
|
||||
- blueabysm,
|
||||
- yangmingming,
|
||||
- boredivan,
|
||||
- name1e5s,
|
||||
- yechunxiao19,
|
||||
- l3b2w1,
|
||||
- XLCYun,
|
||||
- KevinSJ,
|
||||
- l3b2w1,
|
||||
- tenght,
|
||||
- firstadream,
|
||||
- coloka,
|
||||
- luoyutiantang,
|
||||
- sonofelice,
|
||||
- jiajia9linuxer,
|
||||
- scusjs,
|
||||
- tnuoccalanosrep,
|
||||
- woodboow,
|
||||
- 1w2b3l,
|
||||
- JonathanKang,
|
||||
- crowner,
|
||||
- mtunique,
|
||||
- dingdongnigetou,
|
||||
- CNprober,
|
||||
- mtunique,
|
||||
- hyaocuk,
|
||||
- szrlee,
|
||||
- KnightJoker,
|
||||
- Xuanwo,
|
||||
- nd0104,
|
||||
- jerryling315,
|
||||
- xiaoyu33,
|
||||
- guodongxiaren,
|
||||
- ynmlml,
|
||||
- kylepeng93,
|
||||
- ggaaooppeenngg,
|
||||
- Ricky-Gong,
|
||||
- zky001,
|
||||
- Flowsnow,
|
||||
- lfzark,
|
||||
- 213edu,
|
||||
- Tanete,
|
||||
- chenzhijun,
|
||||
- frankatlingingdigital,
|
||||
- willcoderwang,
|
||||
- liuaiping,
|
||||
- bestony,
|
||||
- Timeszoro,
|
||||
- rogetfan,
|
||||
- itsang,
|
||||
- JeffDing,
|
||||
- Yuking-net,
|
||||
- MikeCoder,
|
||||
- zhangboyue,
|
||||
- liaoishere,
|
||||
- yupmoon,
|
||||
- Medusar,
|
||||
- zzlyzq,
|
||||
- yujianxuechuan,
|
||||
- ailurus1991,
|
||||
- tomatoKiller,
|
||||
- stduolc,
|
||||
- shaohaolin,
|
||||
- FineFan,
|
||||
- kingname,
|
||||
- CHINAANSHE,
|
||||
|
||||
(按提交行数排名前百)
|
||||
|
||||
LFS 项目活跃成员有:
|
||||
|
||||
- @ictlyh
|
||||
- @dongfengweixiao
|
||||
- @wxy
|
||||
- @H-mudcup
|
||||
- @zpl1025
|
||||
- @KevinSJ
|
||||
- @Yuking-net
|
||||
|
||||
(更新于2016/05/09)
|
||||
(按增加行数排名前百,更新于2016/12/24)
|
||||
|
||||
谢谢大家的支持!
|
||||
|
||||
|
39
core.md
Normal file
39
core.md
Normal file
@ -0,0 +1,39 @@
|
||||
给核心成员的一封信
|
||||
===================
|
||||
|
||||
鉴于您的卓越贡献,我邀请您成为 LCTT 的核心(Core)成员。
|
||||
|
||||
作为核心成员,您拥有如下权利:
|
||||
|
||||
- 您能够合并您以及其它普通成员的 PR
|
||||
- 您能够校对其它普通成员的文章,并提交校对 PR
|
||||
- 您能够建议或反对将某位普通成员升级为核心成员
|
||||
- 您能够自主添加符合 LCTT 定位的选题并翻译
|
||||
- 您能够以 LCTT 核心成员名义宣称、署名
|
||||
- 在得到 LCTT 同意后,以 LCTT 身份出席活动
|
||||
- 在得到 LCTT 同意后,创建 LCTT 名下的其它仓库并管理(及邀请其它成员参与)
|
||||
- 成为 LinuxCN 管理团队的一员
|
||||
- 参与 LCTT 及 LinuxCN 决策投票
|
||||
|
||||
以下是不允许的行为,虽然您可能有这样的权限:
|
||||
|
||||
- 直接在 LCTT 主仓库上提交修改
|
||||
- 在 LCTT 主仓库上创建分支
|
||||
|
||||
除此以外,您有以下义务:
|
||||
|
||||
- 为您的 GitHub 账户创建安全的密码
|
||||
- 为您的 GitHub 账户创建 2FA 验证
|
||||
- 不得外借您的 GitHub 账户,您需要为您的账户负责
|
||||
- 保持参与度,如长期不能参与,会转换身份为荣誉成员,并放弃相应权限
|
||||
- 接待新加入的成员,并做好引导个工作
|
||||
- 维护 Wiki
|
||||
|
||||
作为核心成员,您会执行一些管理工作,以下是一些惯例:
|
||||
|
||||
- 合并 PR 时,要按时间顺序,从最早的(最下方)的开始合并
|
||||
- 合并 PR 时,如果与仓库或前面的 PR 冲突,则关闭该 PR,并提醒 PR 发起人修改处理
|
||||
- 除非必要,合并 PR 时不要 squash-merge
|
||||
|
||||
wxy@LCTT
|
||||
2016/12/24
|
42
lctt2016.md
Normal file
42
lctt2016.md
Normal file
@ -0,0 +1,42 @@
|
||||
LCTT 2016:LCTT 成立三周年了!
|
||||
===========================
|
||||
|
||||
不知不觉,LCTT 已经成立三年了,对于我这样已经迈过四张的人来说,愈发的感觉时间过得真快。
|
||||
|
||||
这三年来,我们 LCTT 经历了很多事情,有些事情想起来仍恍如昨日。
|
||||
|
||||
三年前的这一天,我的一个偶发的想法促使我在 Linux 中国的 QQ 群里面发了一则消息,具体的消息内容已经不可考了,大意是鉴于英文 man 手册的中文翻译太差,想组织一些人来重新翻译。不料发出去之后很快赢得一些有热情、有理想的小伙伴们的响应。于是我匆匆建了一个群,拉了一些人进来,甚至当时连翻译组的名称都没有确定。LCTT (Linux.Cn Translation Team)这个名称都是后来逐步定下来的。
|
||||
|
||||
关于 LCTT 的早期发展情况,可以参考 LCTT 2014 年周年[总结](http://linux.cn/article-3784-1.html)。
|
||||
|
||||
虽然说“翻译 man 手册”这个最初建群的目标因为种种原因搁浅而一直未能重启,但是,这三年来,我们组织了 [213 位志愿者](https://github.com/LCTT/TranslateProject/graphs/contributors)翻译了 2155 篇文章,接受了 [4263 个 PR](https://github.com/LCTT/TranslateProject/pulls?q=is%3Apr+is%3Aclosed),得到了 476 个星。
|
||||
|
||||
这三年来,我们经历了 man 项目的流产、 LFS 手册的翻译发布、选题 DeadFire 的离去。得益于 Linux 中国的网站和微博,乃至微信的兴起后的传播,志愿者们的译文传播很广,切实的为国内的开源社区做出了贡献(当然,与此同时,Linux 中国社区也随之更加壮大)。
|
||||
|
||||
这些年间,LCTT 来了很多人,也有人慢慢淡出,这里面涌现了不少做出了卓越贡献的人,比如:
|
||||
|
||||
- geekpi,作为整个 LCTT 项目中翻译量最大贡献者,却鲜少在群内说话,偶尔露面,被戏称为“鸡排兄”。
|
||||
- GOLinux,紧追“鸡排兄”的第二位强人,嗯,群内大部分人的昵称都是他起的,包括楼上。
|
||||
- tinyeyeser,“小眼儿”以翻译风趣幽默著称,是 LCTT 早期初创成员之一。
|
||||
- Vito-L,早期成员,LCTT 的多数 Wiki 出自于其手。
|
||||
- DeadFire,创始成员,从最开始到其离世,一直负责 LCTT 的所有选题工作。
|
||||
- oska874,在接过选题工作的重任后,全面主持 LCTT 的工作。
|
||||
- carolinewuyan,承担了相当多的校对工作。
|
||||
- alim0x,独立完成了 Android 编年史系列的翻译(多达 26 篇,现在还没发布完)等等。
|
||||
|
||||
其它还有 ictlyh、strugglingyouth、FSSlc、zpl1025、runningwater、bazz2、Vic020、dongfengweixiao、jasminepeng、willqian、vizv、ZTinoZ、martin2011qi、felixonmars、su-kaiyao、GHLandy、flsf、H-mudcup、StdioA、crowner、vim-kakali 等等,以及还有很多这里没有提到名字的人,都对 LCTT 做出不可磨灭的贡献。
|
||||
|
||||
具体的贡献排行榜,可以看[这里](https://github.com/LCTT/TranslateProject/graphs/contributors)。
|
||||
|
||||
每年写总结时,我都需要和 gource 以及 ffmpeg 搏斗半天,今年,我又用 gource 重新制作了一份 LCTT 的 GitHub 版本仓库的变迁视频,以飨众人。
|
||||
|
||||
本来想写很多,或许 LCTT 和 Linux 中国已经成了我的生活的一部分,竟然不知道该写点什么了,那就此搁笔罢。
|
||||
|
||||
另外,为 LCTT 的诸位兄弟姐妹们献上我及管理团队的祝福,也欢迎更多的志愿者加入 LCTT ,传送门在此:
|
||||
|
||||
- 项目网站:https://lctt.github.io/ ,请先访问此处了解情况。
|
||||
- “Linux中国”开源社区:https://linux.cn/ ,所有翻译的文章都在这里以及它的同名微博、微信发布。
|
||||
|
||||
LCTT 组长 wxy
|
||||
|
||||
2016/9/10
|
@ -19,7 +19,7 @@ LinuxQuestions 问卷调查揭晓最佳开源项目
|
||||
via: http://ostatic.com/blog/linuxquestions-survey-results-surface-top-open-source-projects
|
||||
|
||||
作者:[Sam Dean][a]
|
||||
译者:[jerryling315](https://github.com/jerryling315)
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](http://linux.cn/) 荣誉推出
|
||||
|
@ -98,7 +98,7 @@ Debian 在 Linux 生态环境中的贡献是难以用语言描述的。 如果 D
|
||||
via: http://www.tecmint.com/happy-birthday-to-debian-gnu-linux/
|
||||
|
||||
作者:[Avishek Kumar][a]
|
||||
译者:[jerryling315](http://moelf.xyz)
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -69,7 +69,7 @@ b、 一旦你保存了这个文件,你应该能在 Wifi 菜单里看到你刚
|
||||
via: http://www.linuxveda.com/2015/08/23/how-to-create-an-ap-in-ubuntu-15-04-to-connect-to-androidiphone/
|
||||
|
||||
作者:[Sayantan Das][a]
|
||||
译者:[jerryling315](https://github.com/jerryling315)
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -222,7 +222,7 @@ KDE Plasma 5 – 第五代 KDE。大幅改进了设计和系统,新的默认
|
||||
via: [https://tlhp.cf/kde-history/](https://tlhp.cf/kde-history/)
|
||||
|
||||
作者:[Pavlo Rudyi][a]
|
||||
译者:[jerryling315](https://github.com/jerryling315)
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,129 @@
|
||||
马克·沙特尔沃思 – Ubuntu 背后的那个男人
|
||||
================================================================================
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2015/10/Mark-Shuttleworth-652x445.jpg)
|
||||
|
||||
**马克·理查德·沙特尔沃思(Mark Richard Shuttleworth)** 是 Ubuntu 的创始人,也被称作 [Debian 背后的人][1]([之一][2])。他于 1973 年出生在南非的韦尔科姆(Welkom)。他不仅是个企业家,还是个太空游客——他是第一个前往太空旅行的非洲独立国家的公民。
|
||||
|
||||
马克曾在 1996 年成立了一家名为 **Thawte** 的互联网商务安全公司,那时他还在开普敦大学( University of Cape Town)的学习金融和信息技术。
|
||||
|
||||
2000 年,马克创立了 HBD(Here be Dragons (此处有龙/危险)的缩写,所以其吉祥物是一只龙),这是一家投资公司,同时他还创立了沙特尔沃思基金会(Shuttleworth Foundation),致力于以奖金和投资等形式给社会中有创新性的领袖提供资助。
|
||||
|
||||
> “移动设备对于个人电脑行业的未来而言至关重要。比如就在这个月,相对于平板电脑的发展而言,传统 PC 行业很明显正在萎缩。所以如果我们想要涉足个人电脑产业,我们必须首先涉足移动行业。移动产业之所以有趣,是因为在这里没有盗版 Windows 操作系统的市场。所以如果你为你的操作系统赢得了一台设备的市场份额,这台设备会一直使用你的操作系统。在传统 PC 行业,我们时不时得和“免费”的 Windows 产生竞争,这是一种非常微妙的挑战。所以我们现在的重心是围绕 Ubuntu 和移动设备——手机和平板——以图与普通用户建立更深层次的联系。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
2002 年,他在俄罗斯的星城(Star City)接受了为期一年的训练,随后作为联盟号 TM-34 任务组的一员飞往了国际空间站。再后来,在面向有志于航空航天或者其相关学科的南非学生群体发起了推广科学、编程及数学的运动后,马克 创立了 **Canonical Ltd**。此后直至2013年,他一直在领导 Ubuntu 操作系统的开发。
|
||||
|
||||
现今,沙特尔沃思拥有英国与南非双重国籍并和 18 只可爱的鸭子住在英国的 Isle of Man 小岛上的一处花园,一同的还有他可爱的女友 Claire,两条黑色母狗以及时不时经过的羊群。
|
||||
|
||||
> “电脑不仅仅是一台电子设备了。它现在是你思维的延续,以及通向他人的大门。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
### 马克·沙特尔沃思的早年生活###
|
||||
|
||||
正如我们之前提到的,马克出生在南非的奥兰治自由邦(Orange Free State)的韦尔科姆(Welkom)。他是一名外科医生和护士学校教师的孩子。他在西部省预科学校就读并在 1986 年成为了学生会主席,一个学期后就读于 Rondebosch 男子高中,再之后入学 Bishops Diocesan 学院并在 1991 年再次成为那里的学生会主席。
|
||||
|
||||
马克在开普敦大学( University of Cape Town)拿到了金融和信息系统的商业科学双学士学位,他在学校就读时住在 Smuts Hall。作为学生,他也在那里帮助安装了学校的第一条宿舍互联网接入。
|
||||
|
||||
>“无数的企业和国家已经证明,引入开源政策能提高竞争力和效率。在不同层面上创造生产力对于公司和国家而言都是至关重要的。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
### 马克·沙特尔沃思的职业生涯 ###
|
||||
|
||||
马克在 1995 年创立了 Thawte,公司专注于数字证书和互联网安全,然后在 1999 年把公司卖给了 VeriSign,赚取了大约 5.75 亿美元。
|
||||
|
||||
2000 年,马克创立了 HBD 风险资本公司,成为了商业投资人和项目孵化器。2004 年,他创立了 Canonical Ltd. 以支持和鼓励自由软件开发项目的商业化,特别是 Ubuntu 操作系统的项目。直到 2009 年,马克才从 Canonical CEO 的位置上退下。
|
||||
|
||||
> “在 [DDC](https://en.wikipedia.org/wiki/DCC_Alliance) (LCTT 译注:一个 Debian GNU/Linux 开发者联盟) 的早期,我更倾向于让拥护者们放手去做,看看能发展出什么。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
### Linux、自由开源软件与马克·沙特尔沃思 ###
|
||||
|
||||
在 90 年代后期,马克曾作为一名开发者参与 Debian 操作系统项目。
|
||||
|
||||
2001 年,马克创立了沙特尔沃思基金会,这是个扎根南非的、非赢利性的基金会,专注于赞助社会创新、免费/教育用途开源软件,曾赞助过[自由烤面包机][3](Freedom Toaster)(LCTT 译注:自由烤面包机是一个可以给用户带来的 CD/DVD 上刻录自由软件的公共信息亭)。
|
||||
|
||||
2004 年,马克通过出资开发基于 Debian 的 Ubuntu 操作系统返回了自由软件界,这一切也经由他的 Canonical 公司完成。
|
||||
|
||||
2005 年,马克出资建立了 Ubuntu 基金会并投入了一千万美元作为启动资金。在 Ubuntu 项目内,人们经常用一个朗朗上口的名字称呼他——“**SABDFL :自封的生命之仁慈独裁者(Self-Appointed Benevolent Dictator for Life)**”。为了能够找到足够多的高手开发这个巨大的项目,马克花费了 6 个月的时间从 Debian 邮件列表里寻找,这一切都是在他乘坐在南极洲的一艘破冰船——赫列布尼科夫船长号(Kapitan Khlebnikov)——上完成的。同年,马克买下了 Impi Linux 65% 的股份。
|
||||
|
||||
|
||||
> “我呼吁电信公司的掌权者们尽快开发出跨洲际的高效信息传输服务。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
2006 年,KDE 宣布沙特尔沃思成为 KDE 的**第一赞助人(first patron)**——彼时 KDE 最高级别的赞助。这一赞助协议在 2012 年终止,取而代之的是对 Kubuntu 的资金支持,这是一个使用 KDE 作为默认桌面环境的 Ubuntu 变种。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2015/10/shuttleworth-kde.jpg)
|
||||
|
||||
2009 年,Shuttleworth 宣布他会从 Canonical 的 CEO 上退位以更好地关注合作关系、产品设计和客户。从 2004 年起担任公司 COO 的珍妮·希比尔(Jane Silber)晋升为 CEO。
|
||||
|
||||
2010 年,马克由于其贡献而被开放大学(Open University)授予了荣誉学位。
|
||||
|
||||
2012 年,马克和肯尼斯·罗格夫(Kenneth Rogoff)一同在牛津大学与彼得·蒂尔(Peter Thiel)和加里·卡斯帕罗夫(Garry Kasparov)就**创新悖论**(The Innovation Enigma)展开辩论。
|
||||
|
||||
2013 年,马克和 Ubuntu 一同被授予**澳大利亚反个人隐私大哥奖**(Austrian anti-privacy Big Brother Award),理由是默认情况下, Ubuntu 会把 Unity 桌面的搜索框的搜索结果发往 Canonical 服务器(LCTT 译注:因此侵犯了个人隐私)。而一年前,马克曾经申明过这一过程进行了匿名化处理。
|
||||
|
||||
> “所有主流 PC 厂家现在都提供 Ubuntu 预安装选项,所以我们和业界的合作已经相当紧密了。但那些 PC 厂家对于给买家推广新东西这件事都很紧张。如果我们可以让 PC 买家习惯 Ubuntu 的平板/手机操作系统的体验,那他们也应该更愿意买预装 Ubuntu 的 PC。没有哪个操作系统是通过抄袭模仿获得成功的,Android 很棒,但如果我们想成功的话我们必须给市场带去更新更好的东西(LCTT 译注:而不是改进或者模仿 Android)。如果我们中没有人追寻未来的话,我们将陷入停滞不前的危险。但如果你尝试去追寻未来了,那你必须接受不是所有人对未来的预见都和你一样这一事实。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
### 马克·沙特尔沃思的太空之旅 ###
|
||||
|
||||
马克在 2002 年作为世界第二名自费太空游客而闻名世界,同时他也是南非第一个旅行太空的人。这趟旅行中,马克作为俄罗斯联盟号 TM-34 任务的一名乘员加入,并为此支付了约两千万美元。2 天后,联盟号宇宙飞船抵达了国际空间站,在那里马克呆了 8 天并参与了艾滋病和基因组研究的相关实验。同年晚些时候,马克随联盟号 TM-33 任务返回了地球。为了参与这趟旅行,马克花了一年时间准备与训练,其中有 7 个月居住在俄罗斯的星城。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2015/10/Mark-Shuttleworth1.jpg)
|
||||
|
||||
在太空中,马克与纳尔逊·曼德拉(Nelson Mandela)和另一个 14 岁的南非女孩米歇尔·福斯特(Michelle Foster) (她问马克要不要娶她)通过无线电进行了交谈。马克礼貌地回避了这个结婚问题,但在巧妙地改换话题之前他说他感到很荣幸。身患绝症的女孩福斯特通过梦想基金会( Dream foundation)的赞助获得了与马克和纳尔逊·曼德拉交谈的机会。
|
||||
|
||||
归来后,马克在世界各地做了旅行,并和各地的学生就太空之旅发表了感言。
|
||||
|
||||
>“粗略的统计数据表明 Ubuntu 的实际用户依然在增长。而我们的合作方——戴尔、惠普、联想和其他硬件生产商,以及游戏厂商 EA、Valve 都在加入我们——这让我觉得我们在关键的领域继续领先。”
|
||||
>
|
||||
> — 马克·沙特尔沃思
|
||||
|
||||
### 马克·沙特尔沃思的交通工具 ###
|
||||
|
||||
马克有他自己的私人客机庞巴迪全球特快(Bombardier Global Express),虽然它经常被称为 Canonical 一号,但事实上此飞机是通过 HBD 风险投资公司注册拥有的。涂画在飞机侧面的龙图案是 HBD 风投公司的吉祥物 ,名叫 Norman。
|
||||
|
||||
![](http://www.leader.co.za/leadership/logos/logomarkshuttleworthdirectory_31ce.gif)
|
||||
|
||||
### 与南非储备银行的法律冲突 ###
|
||||
|
||||
在从南非转移 25 亿南非兰特去往 Isle of Man 的过程中,南非储备银行征收了 2.5 亿南非兰特的税金。马克上诉了,经过冗长的法庭唇枪舌战,南非储备银行被勒令返还 2.5 亿征税,以及其利息。马克宣布他会把这 2.5 亿存入信托基金,以用于帮助那些上诉到宪法法院的案子。
|
||||
|
||||
|
||||
> “离境征税倒也不和宪法冲突。但离境征税的主要目的不是提高税收,而是通过监管资金流出来保护本国经济。”
|
||||
>
|
||||
> — Dikgang Moseneke 法官
|
||||
|
||||
2015 年,南非宪法法院修正了低级法院的判决结果,并宣布了上述对于离岸征税的理解。
|
||||
|
||||
### 马克·沙特尔沃思喜欢的东西 ###
|
||||
|
||||
Cesária Évora、mp3、春天、切尔西(Chelsea)、“恍然大悟”(finally seeing something obvious for first time)、回家、辛纳屈(Sinatra)、白日梦、暮后小酌、挑逗、苔丝(d’Urberville)、弦理论、Linux、粒子物理、Python、转世、米格-29、雪、旅行、Mozilla、酸橙果酱、激情代价(body shots)、非洲丛林、豹、拉贾斯坦邦、俄罗斯桑拿、单板滑雪、失重、Iain m 银行、宽度、阿拉斯泰尔·雷诺兹(Alastair Reynolds)、化装舞会服装、裸泳、灵机一动、肾上腺素激情消退、莫名(the inexplicable)、活动顶篷式汽车、Clifton、国家公路、国际空间站、机器学习、人工智能、维基百科、Slashdot、风筝冲浪(kitesurfing)和 Manx lanes。
|
||||
|
||||
|
||||
|
||||
### 马克·沙特尔沃思不喜欢的东西 ###
|
||||
|
||||
行政、涨工资、法律术语和公众演讲。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.unixmen.com/mark-shuttleworth-man-behind-ubuntu-operating-system/
|
||||
|
||||
作者:[M.el Khamlichi][a]
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[PurlingNayuki](https://github.com/PurlingNayuki), [wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.unixmen.com/author/pirat9/
|
||||
[1]:https://wiki.debian.org/PeopleBehindDebian
|
||||
[2]:https://raphaelhertzog.com/2011/11/17/people-behind-debian-mark-shuttleworth-ubuntus-founder/
|
||||
[3]:https://en.wikipedia.org/wiki/Freedom_Toaster
|
@ -1,8 +1,7 @@
|
||||
|
||||
在 CentOS 7 CPanel 服务器上安装 MariaDB 10
|
||||
================================================================================
|
||||
|
||||
MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主要由 MariaDB 社区在维护,采用 GPL v2 授权许可。软件的安全性是 MariaDB 开发者的主要焦点。他们保持为 MariaDB 的每个版本发布安全补丁。当有任何安全问题被发现时,开发者会尽快修复并推出 MariaDB 的新版本。
|
||||
MariaDB 是一个增强版的、开源的 MySQL 替代品。它主要由 MariaDB 社区在维护,采用 GPL v2 授权许可。软件的安全性是 MariaDB 开发者的主要焦点。他们保持为 MariaDB 的每个版本发布安全补丁。当有任何安全问题被发现时,开发者会尽快修复并推出 MariaDB 的新版本。
|
||||
|
||||
### MariaDB 的优势 ###
|
||||
|
||||
@ -12,7 +11,7 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
- 性能更好
|
||||
- 比 MySQL 的存储引擎多
|
||||
|
||||
在这篇文章中,我将谈论关于如何升级 MySQL5.5 到最新的 MariaDB 在CentOS7 CPanel 服务器上。在安装前先完成以下步骤。
|
||||
在这篇文章中,我将谈论关于如何在 CentOS7 CPanel 服务器上升级 MySQL5.5 到最新的 MariaDB 。在安装前先完成以下步骤。
|
||||
|
||||
### 先决条件: ###
|
||||
|
||||
@ -62,7 +61,7 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
|
||||
#### 3. 从服务器上删除和卸载 MySQL 所有的 RPM 包 ####
|
||||
|
||||
运行以下命令来禁用 MySQL 的 RPM 的目标。通过运行此命令,cPanel 将不再处理 MySQL 的更新,并在系统上将卸载的标记为 rpm.versions。
|
||||
运行以下命令来禁用 MySQL RPM 的目标(target)。通过运行此命令,cPanel 将不再处理 MySQL 的更新,并在系统上将这些 RPM 版本标记为已卸载。
|
||||
|
||||
/scripts/update_local_rpm_versions --edit target_settings.MySQL50 uninstalled
|
||||
/scripts/update_local_rpm_versions --edit target_settings.MySQL51 uninstalled
|
||||
@ -72,7 +71,8 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
现在运行以下命令:
|
||||
|
||||
/scripts/check_cpanel_rpms --fix --targets=MySQL50,MySQL51,MySQL55,MySQL56
|
||||
移除服务器上所有已存在的 MySQL rpms 来为 MariaDB 的安装清理环境。请看下面的输出:
|
||||
|
||||
移除服务器上所有已有的 MySQL RPM 来为 MariaDB 的安装清理环境。请看下面的输出:
|
||||
|
||||
root@server1 [/var/lib/mysql]# /scripts/check_cpanel_rpms --fix --targets=MySQL50,MySQL51,MySQL55,MySQL56
|
||||
[2016-01-31 09:53:59 +0000]
|
||||
@ -97,9 +97,9 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
[2016-01-31 09:54:04 +0000] Removed symlink /etc/systemd/system/multi-user.target.wants/mysql.service.
|
||||
[2016-01-31 09:54:04 +0000] Restoring service monitoring.
|
||||
|
||||
通过这些步骤,我们已经卸载了现有的 MySQL RPMs,并做了标记来防止 MySQL的更新,服务器的环境已经清理然后准备安装 MariaDB。
|
||||
通过这些步骤,我们已经卸载了现有的 MySQL RPM,并做了标记来防止 MySQL的更新,服务器的环境已经清理,然后准备安装 MariaDB。
|
||||
|
||||
开始安装吧,我们需要在 CentOS 为 MariaDB 创建一个 yum 软件库。下面是我的做法!
|
||||
开始安装吧,我们需要根据 CentOS 和 MariaDB 的版本为 MariaDB 创建一个 yum 软件库。下面是我的做法!
|
||||
|
||||
### 安装步骤: ###
|
||||
|
||||
@ -120,18 +120,20 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
|
||||
#### 第2步:打开 /etc/yum.conf 并修改如下行: ####
|
||||
|
||||
**Remove this line** exclude=courier* dovecot* exim* filesystem httpd* mod_ssl* mydns* mysql* nsd* php* proftpd* pure-ftpd* spamassassin* squirrelmail*
|
||||
**删除这一行:**
|
||||
|
||||
**And replace with this line** exclude=courier* dovecot* exim* filesystem httpd* mod_ssl* mydns* nsd* proftpd* pure-ftpd* spamassassin* squirrelmail*
|
||||
exclude=courier* dovecot* exim* filesystem httpd* mod_ssl* mydns* mysql* nsd* php* proftpd* pure-ftpd* spamassassin* squirrelmail*
|
||||
|
||||
**\*\*\* IMPORTANT \*\*\***
|
||||
**替换为:**
|
||||
|
||||
exclude=courier* dovecot* exim* filesystem httpd* mod_ssl* mydns* nsd* proftpd* pure-ftpd* spamassassin* squirrelmail*
|
||||
|
||||
**重要**
|
||||
|
||||
需要确保我们已经从 exclude 列表中移除了 MySQL 和 PHP。
|
||||
|
||||
#### 第3步:运行以下命令来安装 MariaDB 和相关的包。 ####
|
||||
|
||||
**yum install MariaDB-server MariaDB-client MariaDB-devel php-mysql**
|
||||
|
||||
root@server1 [~]#yum install MariaDB-server MariaDB-client MariaDB-devel php-mysql
|
||||
|
||||
Dependencies Resolved
|
||||
@ -174,7 +176,7 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
|
||||
#### 第5步:运行 mysql_upgrade 命令。 ####
|
||||
|
||||
它将检查所有数据库中的所有表与当前安装的版本是否兼容并在必要时会更新系统表采取新的特权或功能,可能会增加当前版本的性能。
|
||||
它将检查所有数据库中的所有表与当前安装的版本是否兼容,并在必要时会更新系统表,以赋予当前版本新增加的权限或能力。
|
||||
|
||||
|
||||
root@server1 [~]# mysql_upgrade
|
||||
@ -274,17 +276,18 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
Jan 31 10:04:11 server1.centos7-test.com mysql[23854]: Starting MySQL. SUCCESS!
|
||||
Jan 31 10:04:11 server1.centos7-test.com systemd[1]: Started LSB: start and stop MySQL.
|
||||
|
||||
#### 第7步:运行 EasyApache 用 MariaDB 重建 Apache/PHP,并确保所有 PHP 的模块保持不变。####
|
||||
#### 第7步:运行 EasyApache,重建 Apache/PHP 以支持 MariaDB,并确保所有 PHP 的模块保持不变。####
|
||||
|
||||
root@server1 [~]#/scripts/easyapache --build
|
||||
|
||||
****IMPORTANT *****
|
||||
If you forget to rebuild Apache/PHP after the MariaDB installation, it will report the library error as below:
|
||||
**重要**
|
||||
|
||||
如果你在安装 MariaDB 之后忘记重建 Apache/PHP,将会报如下库错误:
|
||||
|
||||
root@server1 [/etc/my.cnf.d]# php -v
|
||||
php: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory
|
||||
|
||||
#### 第8步:现在验证安装的数据库。 ####
|
||||
#### 第8步:现在验证安装的程序和数据库。 ####
|
||||
|
||||
root@server1 [/var/lib/mysql]# mysql
|
||||
Welcome to the MariaDB monitor. Commands end with ; or \g.
|
||||
@ -313,13 +316,14 @@ MariaDB 是一个增强版的,开源的并且可以直接替代 MySQL。它主
|
||||
10 rows in set (0.00 sec)
|
||||
|
||||
就这样 :)。现在,我们该去欣赏 MariaDB 完善和高效的特点了。希望你喜欢阅读本文。希望留下您宝贵的建议和反馈!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linoxide.com/how-tos/install-mariadb-10-centos-7-cpanel/
|
||||
|
||||
作者:[Saheetha Shameer][a]
|
||||
译者:[strugglingyouth](https://github.com/strugglingyouth)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,34 +1,29 @@
|
||||
初识 Linux 文件权限
|
||||
================================================================================
|
||||
|
||||
在 Linux 中最基本的任务之一就是设置文件权限。理解如何实现是你进入 LInux 世界的第一步。如您所料,这一基本操作在类 UNIX 操作系统中大同小异。实际上,Linux 文件权限系统就直接取自于 UNIX 文件权限(甚至使用许多相同的工具)。
|
||||
在 Linux 中最基本的任务之一就是设置文件权限。理解如何实现是你进入 Linux 世界的第一步。如您所料,这一基本操作在类 UNIX 操作系统中大同小异。实际上,Linux 文件权限系统就直接取自于 UNIX 文件权限(甚至使用许多相同的工具)。
|
||||
|
||||
![](http://www.linux.com/images/stories/66866/files_a.png)
|
||||
|
||||
但不要以为理解文件权限需要长时间的学习。事实上会很简单,让我们一起来看看你需要了解哪些内容以及如何使用它们。
|
||||
|
||||
##基础概念
|
||||
###基础概念
|
||||
|
||||
你要明白的第一件事是文件权限适用于什么。你做的更有效的就是设置一个分组的权限。当你将其分解,那这个概念就真的简单多了。那到底什么是权限,什么是分组呢?
|
||||
你要明白的第一件事是文件权限可以用来干什么。当你设置一个分组的权限时发生了什么?让我们将其展开来说,这个概念就真的简单多了。那到底什么是权限,什么是分组呢?
|
||||
|
||||
你可以设置的3种权限:
|
||||
|
||||
- 读 — 允许该组读文件(用`r`表示)
|
||||
- 读 — 允许该分组读文件(用`r`表示)
|
||||
- 写 — 允许该分组写文件(用`w`表示)
|
||||
- 执行 — 允许该分组执行(运行)文件(用`x`表示)
|
||||
|
||||
- 写 — 允许该组写文件(用`w`表示)
|
||||
|
||||
- 执行 — 允许该组执行(运行)文件(用`x`表示)
|
||||
|
||||
为了更好地解释这如何应用于一个分组,例如,你允许一个分组读和写一个文件,但不能执行。或者,你可以允许一个组读和执行一个文件,但不能写。甚至你可以允许一组有读、写、执行全部的权限,也可以删除全部权限来剥夺组权限。
|
||||
为了更好地解释这如何应用于一个分组,例如,你允许一个分组可以读写一个文件,但不能执行。或者,你可以允许一个分组读和执行一个文件,但不能写。甚至你可以允许一个分组有读、写、执行全部的权限,也可以删除全部权限来去除该组的权限。
|
||||
|
||||
现在,什么是分组呢,有以下4个:
|
||||
|
||||
- user — 文件实际的拥有者
|
||||
|
||||
- group — 用户所在的组
|
||||
|
||||
- group — 用户所在的用户组
|
||||
- others — 用户组外的其他用户
|
||||
|
||||
- all — 所有用户
|
||||
|
||||
大多数情况,你只会对前3组进行操作,`all` 这一组只是作为快捷方式(稍后我会解释)。
|
||||
@ -37,36 +32,31 @@
|
||||
|
||||
如果你打开一个终端并运行命令 `ls -l`,你将会看到逐行列出当前工作目录下所有的文件和文件夹的列表(如图1).
|
||||
|
||||
你会留意到最左边那列是像 `-rw-rw-r--` 这样的。
|
||||
你会留意到最左边那列是像是 `-rw-rw-r--` 这样的。
|
||||
|
||||
实际上这列表该这样看的:
|
||||
实际上这列表应该这样看:
|
||||
|
||||
> rw- rw- r--
|
||||
|
||||
正如你所见,列表将其分为如下3部分:
|
||||
|
||||
- rw-
|
||||
|
||||
- rw-
|
||||
|
||||
- r--
|
||||
|
||||
权限和组的顺序都很重要,顺序总是:
|
||||
权限和组的顺序都很重要,顺序总是:
|
||||
|
||||
- 所属者 所属组 其他人 — 分组
|
||||
|
||||
- 读 写 执行 — 权限
|
||||
|
||||
在我们上面示例的权限列表中,所属者拥有读/写权限,所属组拥有读/写权限,其他人用户仅拥有读权限。这些分组中赋予执行权限的话,就用一个x表示。
|
||||
在我们上面示例的权限列表中,所属者拥有读/写权限,所属组拥有读/写权限,其他人用户仅拥有读权限。这些分组中赋予执行权限的话,就用一个 x 表示。
|
||||
|
||||
## 等效数值
|
||||
### 等效数值
|
||||
|
||||
接下来我们让它更复杂一些,每个权限都可以用一个数字表示。这些数字是:
|
||||
|
||||
- 读 — 4
|
||||
|
||||
- 写 — 2
|
||||
|
||||
- 执行— 1
|
||||
|
||||
数值代替不是一个一个的替换,你不能像这样:
|
||||
@ -77,43 +67,43 @@
|
||||
|
||||
> 664
|
||||
|
||||
如果你想给一个文件664权限,你可以使用chmod命令,如:
|
||||
如果你想给一个文件664权限,你可以使用 `chmod` 命令,如:
|
||||
|
||||
>chmod 664 FILENAME
|
||||
chmod 664 FILENAME
|
||||
|
||||
FILENAME 处为文件名。
|
||||
|
||||
## 更改权限
|
||||
### 更改权限
|
||||
|
||||
既然你已经理解了文件权限,那是时候学习如何更改这些权限了。就是使用chmod命令来实现。第一步你要知道你能否更改文件权限,你必须是文件的所有者或者有权限编辑文件(或者使用su或sudo进行操作)。正因为这样,你不能随意切换目录和更改文件权限。
|
||||
既然你已经理解了文件权限,那是时候学习如何更改这些权限了。就是使用 `chmod` 命令来实现。第一步你要知道你能否更改文件权限,你必须是文件的所有者或者有权限编辑文件(或者通过 `su` 或 `sudo` 得到权限)。正因为这样,你不能随意切换目录和更改文件权限。
|
||||
|
||||
继续用我们的例子 (`-rw-rw-r--`)。假设这个文件(命名为 script.sh)实际是个shell脚本,需要被执行,但是你只想让自己有权限执行这个脚本。这个时候,你可能会想:“我需要是文件的权限如 `-rwx-rw-r--`”。为了设置 `x` 权限位,你可以这样使用 `chmod` 命令:
|
||||
|
||||
>chmod u+x script.sh
|
||||
chmod u+x script.sh
|
||||
|
||||
这时候,列表中显示的应该是 -rwx-rw-r-- 。
|
||||
|
||||
如果你想同时让用户及其所属组同时拥有执行权限,命令应该这样:
|
||||
|
||||
>chmod ug+x script.sh
|
||||
chmod ug+x script.sh
|
||||
|
||||
明白这是怎么工作的了吗?下面我们让它更有趣些。不管什么原因,你不小心给了所有分组对文件的执行权限(列表中是这样的 `-rwx-rwx-r-x`)。
|
||||
|
||||
如果你想去除其他用户的执行权限,只需运行命令:
|
||||
|
||||
>chmod o-x script.sh
|
||||
chmod o-x script.sh
|
||||
|
||||
如果你想完全删除文件的可执行权限,你可以用两种方法:
|
||||
|
||||
>chmod ugo-x script.sh
|
||||
chmod ugo-x script.sh
|
||||
|
||||
或者
|
||||
|
||||
>chmod a-x script.sh
|
||||
chmod a-x script.sh
|
||||
|
||||
以上就是所有内容,能使操作更有效率。我希望能避免哪些可能会导致一些问题的操作(例如你不小心对 script.sh 使用 `a-rwx` 这样的chmod命令)。
|
||||
以上就是所有内容,能使操作更有效率。我希望能避免哪些可能会导致一些问题的操作(例如你不小心对 script.sh 使用 `a-rwx` 这样的 `chmod` 命令)。
|
||||
|
||||
## 目录权限
|
||||
### 目录权限
|
||||
|
||||
你也可以对一个目录执行 `chmod` 命令。当你作为用户创建一个新的目录,通常新建目录具有这样的权限:
|
||||
|
||||
@ -121,19 +111,19 @@ FILENAME 处为文件名。
|
||||
|
||||
注:开头的 `d` 表示这是一个目录。
|
||||
|
||||
正如你所见,用户及其所在组都对文件夹具有操作权限,但这并不意味着在这文件夹中出创建的问价也具有与其相同的权限(创建的文件使用默认系统的权限 `-rw-rw-r--`)。但如果你想在新文件夹中创建文件,并且移除用户组的写权限,你不用切换到该目录下并对所有文件使用chmod命令。你可以用加上参数R(意味着递归)的 `chmod` 命令,同时更改该文件夹及其目录下所有的文件的权限。
|
||||
正如你所见,用户及其所在组都对文件夹具有操作权限,但这并不意味着在这文件夹中出创建的文件也具有与其相同的权限(创建的文件使用默认系统的权限 `-rw-rw-r--`)。但如果你想在新文件夹中创建文件,并且移除用户组的写权限,你不用切换到该目录下并对所有文件使用 `chmod` 命令。你可以用加上参数 R(意味着递归)的 `chmod` 命令,同时更改该文件夹及其目录下所有的文件的权限。
|
||||
|
||||
现在,假设有一文件夹 TEST,里面有一些脚本,所有这些(包括 TEST 文件夹)拥有权限 `-rwxrwxr-x`。如果你想移除用户组的写权限,你可以运行命令:
|
||||
|
||||
>chmod -R g-w TEST
|
||||
chmod -R g-w TEST
|
||||
|
||||
运行命令 `ls -l`,你讲看到列出的 TEST 文件夹的权限信息是 `drwxr-xr-x`。用户组被去除了写权限(其目录下的所有文件也如此)。
|
||||
|
||||
## 总结
|
||||
### 总结
|
||||
|
||||
现在,你应该对基本的Linux文件权限有了深入的理解。对于更高级的东西学起来会很轻松,像`setid`,`setuid` 和 `ACLs` 这些。没有良好的基础,你很快就会混淆不清概念的。
|
||||
现在,你应该对基本的 Linux 文件权限有了深入的理解。对于更高级的东西学起来会很轻松,像 setgid、setuid 和 ACL 这些。没有良好的基础,你很快就会混淆不清概念的。
|
||||
|
||||
Linux 文件权限从早期到现在没有太大变化,而且很可能以后也不会。
|
||||
Linux 文件权限从早期到现在没有太大变化,而且很可能以后也不会变化。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -141,7 +131,7 @@ via: http://www.linux.com/learn/tutorials/885268-getting-to-know-linux-file-perm
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
译者:[ynmlml](https://github.com/ynmlml)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,39 +1,41 @@
|
||||
修补 Linux 系统 glibc 严重漏洞
|
||||
=================================================
|
||||
|
||||
**谷歌揭露的一个严重漏洞影响主流的 Linux 发行版。glibc 的漏洞可能导致远程代码执行。**
|
||||
**谷歌披露的一个严重漏洞影响到了主流的 Linux 发行版。glibc 的漏洞可能导致远程代码执行。**
|
||||
|
||||
Linux 用户今天都竞相给一个可以使系统暴露在远程代码执行风险中的核心 glibc 开放源码库的严重漏洞打补丁。glibc 的漏洞被确定为 CVE-2015-7547,题为“getaddrinfo 基于堆栈的缓冲区溢出”。
|
||||
编者按:这个消息并不是一个新闻,基于技术的原因,我们还是分享给大家。
|
||||
|
||||
Linux 用户都在竞相给一个可以使系统暴露在远程代码执行风险中的核心 glibc 开放源码库的严重漏洞打补丁。这个 glibc 的漏洞编号被确定为 CVE-2015-7547,题为“getaddrinfo 基于堆栈的缓冲区溢出”。
|
||||
|
||||
glibc,或 GNU C 库,是一个开放源码的 C 和 C++ 编程语言库的实现,是每一个主流 Linux 发行版的一部分。谷歌工程师们在他们试图连接到某个主机系统时发生了一个段错误导致连接崩溃,偶然发现了 CVE-2015-7547 问题。进一步的研究表明, glibc 有缺陷而且该崩溃可能实现任意远程代码执行的条件。
|
||||
|
||||
谷歌在一篇博客文章中写道, “当 getaddrinfo() 库函数被使用时,glibc 的 DNS 客户端解析器易受基于堆栈缓冲区溢出的攻击,使用该功能的软件可能被利用为攻击者控制的域名,攻击者控制的 DNS[域名系统] 服务器,或通过中间人攻击。”
|
||||
谷歌在一篇博客文章中写道, “当 getaddrinfo() 库函数被使用时,glibc 的 DNS 客户端解析器易受基于堆栈缓冲区溢出的攻击,使用该功能的软件可能通过攻击者控制的域名、攻击者控制的 DNS [域名系统] 服务器,或通过中间人攻击方式(MITM)进行破坏。”
|
||||
|
||||
其实利用 CVE-2015-7547 问题并不简单,但它是可能的。为了证明这个问题能被利用,谷歌发布了论证一个终端用户或系统是否易受攻击的概念验证(POC)代码到 GitHub 上。
|
||||
|
||||
GitHub 上的 POC 网页声明“服务器代码触发漏洞,因此会使客户端代码崩溃”。
|
||||
GitHub 上的 POC 网页说“服务器代码会触发漏洞,因此会使客户端代码崩溃”。
|
||||
|
||||
Duo Security 公司的高级安全研究员 Mark Loveless 解释说 CVE-2015-7547 的主要风险在于 Linux 上依赖于 DNS 响应的基于客户端的应用程序。
|
||||
Duo Security 公司的高级安全研究员 Mark Loveless 解释说 CVE-2015-7547 的主要风险在于依赖于 DNS 响应的基于 Linux 客户端的应用程序。
|
||||
|
||||
Loveless 告诉 eWEEK “需要一些特定的条件,所以不是每个应用程序都会受到影响,但似乎一些命令行工具,包括流行的 SSH[安全 Shell] 客户端都可能触发该漏洞,我们认为这是严重的,主要是因为对 Linux 系统存在的风险,但也因为潜在的其他问题。”
|
||||
|
||||
其他问题可能包括一种触发调用易受攻击的 glibc 库 getaddrinfo() 的基于电子邮件攻击的风险。另外值得注意的是,该漏洞被发现之前已存在于代码之中多年。
|
||||
其他问题可能包括一种通过电子邮件触发调用易受攻击的 glibc 库 getaddrinfo() 攻击的风险。另外值得注意的是,该漏洞被发现之前已存在于代码之中多年。
|
||||
|
||||
谷歌的工程师不是第一或唯一发现 glibc 中的安全风险的团体。这个问题于 2015 年 7 月 13 日首先被报告给了 glibc 的 bug[跟踪系统](https://sourceware.org/bugzilla/show_bug.cgi?id=1866)。该缺陷的根源可以更进一步追溯到在 2008 五月发布的 glibc 2.9 的代码提交时首次引入缺陷。
|
||||
谷歌的工程师不是第一或唯一发现这个 glibc 安全风险的团体。这个问题于 2015 年 7 月 13 日首先被报告给了 glibc 的 bug[跟踪系统](https://sourceware.org/bugzilla/show_bug.cgi?id=1866)。该缺陷的根源可以更进一步追溯到在 2008 五月发布的 glibc 2.9 的代码提交时首次引入缺陷。
|
||||
|
||||
Linux 厂商红帽也独立找到了 glibc 中的这个 bug,而且在 2016 年 1 月 6 日,谷歌和红帽开发人员证实,他们作为最初与上游 glibc 的维护者私下讨论的部分人员,已经独立在为同一个漏洞工作。
|
||||
Linux 厂商红帽也独立找到了 glibc 中的这个 bug,而且是在 2016 年 1 月 6 日,谷歌和红帽开发人员证实,他们作为最初与上游 glibc 的维护者私下讨论的部分人员,已经独立在为同一个漏洞工作。
|
||||
|
||||
红帽产品安全首席软件工程师 Florian Weimer 告诉 eWEEK “一旦确认了两个团队都在为同一个漏洞工作,我们合作进行可能的修复,缓解措施和回归测试,我们还共同努力,使测试覆盖尽可能广,捕捉代码中的任何相关问题,以帮助避免今后更多问题。”
|
||||
红帽产品安全首席软件工程师 Florian Weimer 告诉 eWEEK “一旦确认了两个团队都在为同一个漏洞工作,我们会合作进行可能的修复,缓解措施和回归测试,我们还会共同努力,使测试覆盖尽可能广,捕捉代码中的任何相关问题,以帮助避免今后更多问题。”
|
||||
|
||||
由于缺陷不明显或不易立即显现,我们花了几年时间才发现 glibc 代码有一个安全问题。
|
||||
|
||||
Weimer 说“要诊断一个网络组件的漏洞,如 DNS 解析器,当遇到问题时通常要看被抓数据包的踪迹,在这种情况下这样的抓包不适用,所以需要一些实验来重现触发这个 bug 的确切场景。”
|
||||
Weimer 说“要诊断一个网络组件的漏洞,如 DNS 解析器,当遇到问题时通常要看抓到的数据包的踪迹,在这种情况下这样的抓包不适用,所以需要一些实验来重现触发这个 bug 的确切场景。”
|
||||
|
||||
Weimer 补充说,一旦可以抓取数据包,大量精力投入到验证修复程序中,最终导致回归测试套件一系列的改进,有助于上游 glibc 项目。
|
||||
Weimer 补充说,一旦可以抓取数据包,就会投入大量精力到验证修复程序中,最终完成回归测试套件一系列的改进,有助于上游 glibc 项目。
|
||||
|
||||
在许多情况下,安全增强式 Linux (SELinux) 的强制访问安全控制可以减少潜在漏洞风险,除了这个 glibc 的新问题。
|
||||
在许多情况下,安全增强式 Linux (SELinux) 的强制访问安全控制可以减少潜在漏洞风险,但是这个 glibc 的新问题例外。
|
||||
|
||||
Weimer 说“由于攻击者提供的任意代码的执行,风险是重要系统功能的一个妥协。一个合适的 SELinux 策略可以遏制一些攻击者可能会做的损害,并限制他们访问系统,但是 DNS 被许多应用程序和系统组件使用,所以 SELinux 策略只提供了针对此问题有限的遏制。”
|
||||
Weimer 说“由于攻击者提供的任意代码的执行,会对很多重要系统功能带来风险。一个合适的 SELinux 策略可以遏制一些攻击者可能会做的损害,并限制他们访问系统,但是 DNS 被许多应用程序和系统组件使用,所以 SELinux 策略只提供了针对此问题有限的遏制。”
|
||||
|
||||
在揭露漏洞的今天,现在有一个可用的补丁来减少 CVE-2015-7547 的潜在风险。
|
||||
|
||||
@ -43,7 +45,7 @@ via: http://www.eweek.com/security/linux-systems-patched-for-critical-glibc-flaw
|
||||
|
||||
作者:[Michael Kerner][a]
|
||||
译者:[robot527](https://github.com/robot527)
|
||||
校对:[校对者 ID](https://github.com/校对者 ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux 中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,48 @@
|
||||
新的 Docker 数据中心管理套件使容器化变得更加井然有序
|
||||
===============================================================================
|
||||
|
||||
![](https://tctechcrunch2011.files.wordpress.com/2016/02/shutterstock_119411227.jpg?w=738)
|
||||
|
||||
[Docker][1]之前发布了一个新的容器控制中心,称为Docker数据中心(DDC),其设计目的是用于大型和小型企业创建、管理和分发容器的一个集成管理控制台。
|
||||
|
||||
DDC是由包括Docker Universal Control Plane(也是同时发布的)和Docker Trusted Registry等不同的商业组件组成。它也包括了开源组件比如Docker Engine。这个产品让企业在一个中心管理界面中就可以管理整个Docker化程序的生命周期。
|
||||
|
||||
负责产品管理的SVP Scott Johnston告诉TechCrunch:“客户催使了这个新工具的产生。公司不仅喜欢Docker给他们带来的敏捷性,它们也希望在创建和分发容器的过程中可以进行对安全和管理进行控制。”
|
||||
|
||||
Johnston说:“公司称这个为容器即服务(Caas),主要是因为当客户来询问这种类型的管理面板时,他们是这样描述的。”
|
||||
|
||||
![](https://tctechcrunch2011.files.wordpress.com/2016/02/screen-shot-2016-02-23-at-7-56-54-am.png?w=680&h=401)
|
||||
|
||||
像许多开源项目那样,Docker首先获得了许多开发者的追随,但是随着它的流行,那些开发者们所在的公司也希望积极推进它的使用。
|
||||
|
||||
这就是DDC设计的目的。它给开发者创建容器化应用的敏捷性,也让运维变得井井有条。
|
||||
|
||||
实际上这意味着开发者可以创建一系列容器化的组件,将其部署后就可以访问一个完全认证的镜像库。这可以让开发人员用碎片组成应用而不必每次重新发明轮子。这可以加速应用的开发和部署(理论上提升了容器提供的灵活性)。
|
||||
|
||||
这方面吸引了Beta客户ADP。这个服务特别喜欢将这个提供给开发人员的中心镜像仓库。
|
||||
|
||||
ADP的CTO Keith Fulton在声明中称:“作为我们将关键业务微服务化倡议的一部分,ADP正在研究能够让开发人员可以利用IT审核过的中央库和安全的核心服务进行快速迭代的方案。”
|
||||
|
||||
Docker在2010年由dotcloud的Solomon Hykes发布。他在2013年将公司的重心移到Docker上,并在[8月出售了dotCloud][2],2014年完全聚焦在Docker上。
|
||||
|
||||
根据CrunchBase的消息,公司几年来在5轮融资后势如破竹般获得了1亿8000万美元融资(自从成为Docker后获得了1亿6千8百万美元)。吸引投资者关注的是Docker提供了一种称为容器的现在分发应用的方式,可以构建、管理何分发分布式应用。
|
||||
|
||||
容器化可以让开发者创建由多个分布在不同服务器上的碎片组成的分布式应用,而不是一个运行在一个单独服务器上的独立应用。
|
||||
|
||||
DDC服务每月每节点150美金起。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://techcrunch.com/2016/02/23/new-docker-data-center-admin-suite-should-bring-order-to-containerization/
|
||||
|
||||
作者:[Ron Miller][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://techcrunch.com/author/ron-miller/
|
||||
[1]: https://www.docker.com/
|
||||
[2]: http://techcrunch.com/2014/08/04/docker-sells-dotcloud-to-cloudcontrol-to-focus-on-core-container-business/
|
||||
|
||||
|
@ -0,0 +1,97 @@
|
||||
两个出色的一体化 Linux 服务器软件
|
||||
================================================
|
||||
|
||||
回到2000年那时,微软发布小型商务服务器(SBS:Small Business Server)。这个产品改变了很多人们对科技在商务领域的看法。你可以部署一个单独的服务器,它能处理邮件,日历,文件共享,目录服务,VPN,以及更多,而不是很多机器处理不同的任务。对很多小型公司来说,这是实实在在的好处,但是对于一些公司来说 Windows SMB 是昂贵的。对于另外一些人,根本不会考虑使用这种微软设计的单一服务器的想法。
|
||||
|
||||
对于后者也有替代方案。事实上,在 Linux 和开源领域里,你可以选择许多稳定的平台,它可以作为一站式服务商店服务于你的小型企业。如果你的小型企业有10到50员工,一体化服务器也许是你所需的理想方案。
|
||||
|
||||
这里,我将要展示两个 Linux 一体化服务器,你可以看看它们哪个能完美适用于你的公司。
|
||||
|
||||
记住,这些服务器不适用于(不管是哪种方式)大型商务或企业。大公司无法依靠一体化服务器,那是因为一台服务器不能负担得起企业所需的期望。也就是说,Linux 一体化服务器适合于小型企业。
|
||||
|
||||
### ClearOS
|
||||
|
||||
[ClearOS][1] 最初发布于 2009 年,那时名为 ClarkConnect,是一个路由和网关的发行版。从那以后,ClearOS 增加了所有一体化服务器必要的特性。CearOS 提供的不仅仅是一个软件,你可以购买一个 [ClearBox 100][2] 或 [ClearBox 300][3]。这些服务器搭载了完整的 ClearOS,作为一个 IT 设备被销售。在[这里][4]查看特性比对/价格矩阵。
|
||||
|
||||
如果你已经有响应的硬件,你可以下载这些之一:
|
||||
|
||||
- [ClearOS 社区版][5] — 社区(免费)版的 ClearOS
|
||||
- [ClearOS 家庭版][6] — 理想的家庭办公室(详细的功能和订阅费用,见[这里][12])
|
||||
- [ClearOS商务][7] — 理想的小型企业(详细的功能和订阅费用,见[这里][13])
|
||||
|
||||
使用 ClearOS 能给你你带来什么?你得到了一个商业级的服务器,带有单一的精美 Web 界面。是什么让 ClearOS 从标准的服务器所提供的一大堆功能中脱颖而出?除了那些基础的部分,你可以从 [Clear 市场][8] 中增加功能。在这个市场里,你可以安装免费或付费的应用来扩展 ClearOS 服务器的特性。这里你可以找到支持 Windows 服务器活动目录,OpenLDAP,Flexshares,Antimalware,云,Web 访问控制,内容过滤等等很多的补充插件。你甚至可以找到一些第三方组件,比如谷歌应用同步,Zarafa 合作平台,卡巴斯基杀毒。
|
||||
|
||||
ClearOS 的安装就像其他的 Linux 发行版一样(基于红帽的 Anaconda 安装程序)。安装完成后,系统将提示您设置网络接口,这个地址用来供你的浏览器(需要与 ClearOS 服务器在同一个网络里)访问。地址格式如下:
|
||||
|
||||
https://IP_OF_CLEAROS_SERVER:81
|
||||
|
||||
IP_OF_CLEAROS_SERVER 就是服务器的真实 IP 地址。注:当你第一次在浏览器访问这个服务器时,你将收到一个“Connection is not private”的警告。继续访问,以便你可以继续设置。
|
||||
|
||||
当浏览器最终连接上之后,就会提示你 root 用户认证(在初始化安装中你设置的 root 用户密码)。一通过认证,你将看到 ClearOS 的安装向导(图1)
|
||||
|
||||
![](http://www.linux.com/images/stories/66866/jack-clear_a.png)
|
||||
|
||||
*图1: ClearOS安装向导。*
|
||||
|
||||
点击下一步按钮,开始设置你的 ClearOS 服务器。这个向导无需加以说明,在最后还会问你想用那个版本的 ClearOS。点击“社区”,“家庭”,或者“商业”。选择之后,你就被要求注册一个账户。创建了一个账户并注册了你的服务器后,你可以开始更新服务器,配置服务器,从市场添加模块(图2)。
|
||||
|
||||
![](http://www.linux.com/images/stories/66866/jack-clear_b.png)
|
||||
|
||||
*图2: 从市场安装模块。*
|
||||
|
||||
此时,一切准备就绪,可以开始深入挖掘配置你的 ClearOS 小型商务服务器了。
|
||||
|
||||
### Zentyal
|
||||
|
||||
[Zentyal][10] 是一个基于 Ubuntu 的小型商务服务器,有段时期的名字是 eBox。Zentyal 提供了大量的服务器/服务来适应你的小型商务需求:
|
||||
|
||||
- 电子邮件 — 网页邮件;支持原生的微软 Exchange 协议和活动目录;日历和通讯录;手机设备电子邮件同步;反病毒/反垃圾;IMAP,POP,SMTP,CalDAV,和 CardDAV 支持。
|
||||
- 域和目录 — 中央域目录管理;多个组织部门;单点登录身份验证;文件共享;ACL,高级域管理,打印机管理。
|
||||
- 网络和防火墙 — 支持静态和 DHCP 接口;对象和服务;包过滤;端口转发。
|
||||
- 基础设施 — DNS;DHCP;NTP;认证中心;VPN。
|
||||
- 防火墙
|
||||
|
||||
安装 Zentyal 很像Ubuntu服务器的安装,基于文本界面而且很简单:从安装镜像启动,做一些简单的选择,然后等待安装完成。当这个最初的基于文本的安装完成之后,就会显示桌面 GUI,提供选择软件包的向导程序。你可以选择所有你想安装的包,让安装程序继续完成这些工作。
|
||||
|
||||
最终,你可以通过网页界面来访问 Zentyal 服务器(浏览器访问 https://IP_OF_SERVER:8443 - 这里 IP_OF_SERVER是你的 Zentyal 服务器的局域网地址)或使用独立的桌面 GUI 程序来管理服务器(Zentyal 包括一个可以快速访问管理员和用户控制台的 Zentyal 管理控制台)。当真系统已经保存并启动,你将看到 Zentyal 面板(图3)。
|
||||
|
||||
![](http://www.linux.com/images/stories/66866/jack-zentyal_a.png)
|
||||
|
||||
*图3: Zentyal活动面板。*
|
||||
|
||||
这个面板允许你控制服务器所有方面,比如更新,管理服务器/服务,获取服务器的敏捷状态更新。您也可以进入组件区域,然后安装在部署过程中没有选择的组件或更新当前的软件包列表。点击“软件管理” > “系统更新”并选择你想更新的(图4),然后在屏幕最底端点击“更新”按钮。
|
||||
|
||||
![](http://www.linux.com/images/stories/66866/jack-zentyal_b.png)
|
||||
|
||||
*图4: 更新你的Zentyal服务器很简单。*
|
||||
|
||||
### 那个服务器适合你?
|
||||
|
||||
回答这个问题要看你有什么需求。Zentyal 是一个不可思议的服务器,它可以很好的胜任你的小型商务网络。如果你需要更多,如群件,我觉得你可以试试 ClearOS。如果你不需要群件,其它的服务器也不错。
|
||||
|
||||
我强烈建议你安装一下这两个一体化的服务器,看看哪个更适合你的小公司。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linux.com/learn/tutorials/882146-two-outstanding-all-in-one-linux-servers
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
译者:[wyangsun](https://github.com/wyangsun)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.linux.com/community/forums/person/93
|
||||
[1]: http://www.linux.com/learn/tutorials/882146-two-outstanding-all-in-one-linux-servers#clearfoundation-overview
|
||||
[2]: https://www.clearos.com/products/hardware/clearbox-100-series
|
||||
[3]: https://www.clearos.com/products/hardware/clearbox-300-series
|
||||
[4]: https://www.clearos.com/products/hardware/clearbox-overview
|
||||
[5]: http://mirror.clearos.com/clearos/7/iso/x86_64/ClearOS-DVD-x86_64.iso
|
||||
[6]: http://mirror.clearos.com/clearos/7/iso/x86_64/ClearOS-DVD-x86_64.iso
|
||||
[7]: http://mirror.clearos.com/clearos/7/iso/x86_64/ClearOS-DVD-x86_64.iso
|
||||
[8]: https://www.clearos.com/products/purchase/clearos-marketplace-overview
|
||||
[9]: https://ip_of_clearos_server:81/
|
||||
[10]: http://www.zentyal.org/server/
|
||||
[11]: https://ip_of_server:8443/
|
||||
[12]: https://www.clearos.com/products/clearos-editions/clearos-7-home
|
||||
[13]: https://www.clearos.com/products/clearos-editions/clearos-7-business
|
@ -1,10 +1,10 @@
|
||||
# 在NASA中使用开源工具进行图像处理
|
||||
在 NASA 使用开源工具进行图像处理
|
||||
==================
|
||||
|
||||
关键词:NASA,图像处理,Node.js,OpenCV
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/nasa_spitzer_space_pink_spiral.jpg?itok=3XEUstkl)
|
||||
|
||||
在刚结束的这个夏天里,我是 [NASA 格伦中心][1] [GVIS][2] 实验室的实习生,我将我对开源的热情带到了那里。我的任务是改进我们实验室对 Dan Schroeder 开发的一个开源流体动力学模拟器的贡献。原本的模拟器可以显示用户用鼠标绘制的障碍物,并建立计算流体动力学模型。我们团队的贡献是加入图像处理的代码,分析实况视频的每一帧以显示特定的物体如何与液体相互作用。而且,我们还要做更多事情。
|
||||
在刚结束的这个夏天里,我是 [NASA 格伦中心][1] [GVIS][2] 实验室的实习生,我将我对开源的热情带到了那里。我的任务是改进我们实验室对 Dan Schroeder 开发的一个开源流体动力学模拟器的贡献。原本的[模拟器][3]可以显示用户用鼠标绘制的障碍物,并建立计算流体动力学模型。我们团队的贡献是加入图像处理的代码,分析实况视频的每一帧以显示特定的物体如何与液体相互作用。而且,我们还要做更多事情。
|
||||
|
||||
我们想要让图像处理部分更加健壮,所以我致力于改善图像处理库。
|
||||
|
||||
@ -16,33 +16,33 @@
|
||||
2. 找寻物体的质心
|
||||
3. 能对物体中心进行相关的精确转换
|
||||
|
||||
我的导师建议我安装 [Node.js](http://nodejs.org/) 、 [OpenCV](http://opencv.org/) 和 [Node.js bindings for OpenCV](https://github.com/peterbraden/node-opencv)。在等待软件安装的过程中,我查看了 OpenCV 的 [GitHub 主页][3]上的示例源码。我发现示例源码使用 JavaScript 写的,而我还不懂 JavaScript ,所以我在 Codecademy 上学了一些课程。两天后,我对 JavaScript 依旧生疏,不过我还是开始了我的项目…它包含了更多的 JavaScript 。
|
||||
我的导师建议我安装 [Node.js](http://nodejs.org/) 、 [OpenCV](http://opencv.org/) 和 [Node.js bindings for OpenCV](https://github.com/peterbraden/node-opencv)。在等待软件安装的过程中,我查看了 OpenCV 的 [GitHub 主页][4]上的示例源码。我发现示例源码使用 JavaScript 写的,而我还不懂 JavaScript ,所以我在 Codecademy 上学了一些课程。两天后,我对 JavaScript 依旧生疏,不过我还是开始了我的项目……它包含了更多的 JavaScript 。
|
||||
|
||||
检测轮廓的示例代码工作得很好。事实上,它使得我用几个小时就完成了第一个目标!获取一幅图片的轮廓,它看起来像这样:
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/image_processing_nasa_1-520x293.jpg)
|
||||
|
||||
> 包括所有轮廓的原始图,
|
||||
*包括所有轮廓的原始图*
|
||||
|
||||
检测轮廓的示例代码工作得有点好过头了。不仅物体的轮廓被检测到了,整个图片中的轮廓都检测到了。这会导致模拟器要与那些没用的轮廓打交道。这是一个严重的问题,因为它会返回错误的数据。为了避免模拟器接触到不想要的轮廓,我加了一个区域约束。轮廓要位于一定的区域范围内才会被画出来。区域约束使得轮廓变干净了。
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/image_processing_nasa_2-520x293.jpg)
|
||||
|
||||
> 过滤后的轮廓,包含了阴影轮廓
|
||||
*过滤后的轮廓,包含了阴影轮廓*
|
||||
|
||||
虽然无关的轮廓没有了,但是图像还有个问题。图像本该只有一个轮廓,但是它来回绕了自己两次,没有完整地圈起来。区域在这里不能作为决定因素,所以必须试试其他方式。
|
||||
|
||||
这一次,我不是直接去找寻轮廓,而是先将图片转换成二值图。二值图是转换之后只有黑白像素的图片。为了获取到二值图我先把彩色图转成灰度图。转换之后我再用阈值函数对图片进行处理。阈值函数遍历图片每个像素点的值,如果值小于 30 ,像素的颜色就会改成黑色。否则则反。在原始图片转换成二值图之后,结果变成这样:
|
||||
这一次,我不是直接去找寻轮廓,而是先将图片转换成二值图。二值图是转换之后只有黑白像素的图片。为了获取到二值图我先把彩色图转成灰度图。转换之后我再用阈值函数对图片进行处理。阈值函数遍历图片每个像素点的值,如果值小于 30 ,像素的颜色就会改成黑色。否则取反。在原始图片转换成二值图之后,结果变成这样:
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/image_processing_nasa_3-520x293.jpg)
|
||||
|
||||
> 二值图。
|
||||
*二值图*
|
||||
|
||||
然后我获取了二值图的轮廓,结果是一个更干净的轮廓,没有了阴影轮廓。
|
||||
|
||||
![](https://opensource.com/sites/default/files/image_processing_nasa_4.jpg)
|
||||
|
||||
> 最后的干净轮廓。
|
||||
*最后的干净轮廓*
|
||||
|
||||
这个时候,我可以获取干净的轮廓、计算质心了。可惜的是,我没有足够的时间去完成质心的相关变换。由于我的实习时间只剩下几天了,我开始考虑我在这段有限时间内能做的其它事情。其中一个就是边界矩形。边界矩形是包含了图片轮廓的最小四边形。边界矩形很重要,因为它是在页面上缩放轮廓的关键。虽然很遗憾我没时间利用边界矩形做更多事情,但是我仍然想学习它,因为它是个很有用的工具。
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/image_processing_nasa_5-521x293.jpg)
|
||||
|
||||
> 最终图像,红色的边界矩形和质心。
|
||||
*最终图像,红色的边界矩形和质心*
|
||||
|
||||
当这些图像处理代码写完之后,我用我的代码替代了模拟器中的老代码。令我意外的是,它可以工作。
|
||||
|
||||
@ -60,11 +60,11 @@
|
||||
|
||||
( Youtube 演示视频)
|
||||
|
||||
程序有内存泄露,每 1/10 秒泄露 100MB 。我很高兴原因不是我的代码。坏消息是我并不能修复它。好消息是仍然有解决方法。它并非最理想的,但我可以使用。这个方法是不断检查模拟器使用的内存,当使用内存超过 1GB 时,重新启动模拟器。
|
||||
程序有内存泄露,每 1/10 秒泄露 100MB 。我很高兴不是因为我的代码。坏消息是我并不能修复它。另一个好消息是仍然有解决方法,虽然并非最理想的,但我可以使用。这个方法是不断检查模拟器使用的内存,当使用内存超过 1GB 时,重新启动模拟器。
|
||||
|
||||
在 NASA 实验室,我们会使用很多的开源软件,没有这些开源软件的帮助,我不可能完成这些工作。
|
||||
|
||||
* * *
|
||||
-------
|
||||
|
||||
via: [https://opensource.com/life/16/3/image-processing-nasa](https://opensource.com/life/16/3/image-processing-nasa)
|
||||
|
||||
@ -76,4 +76,5 @@ via: [https://opensource.com/life/16/3/image-processing-nasa](https://opensource
|
||||
|
||||
[1]: http://www.nasa.gov/centers/glenn/home/index.html
|
||||
[2]: https://ocio.grc.nasa.gov/gvis/
|
||||
[3]: https://github.com/peterbraden/node-opencv
|
||||
[3]: http://physics.weber.edu/schroeder/fluids/
|
||||
[4]: https://github.com/peterbraden/node-opencv
|
@ -0,0 +1,63 @@
|
||||
65% 的企业正致力于开源项目
|
||||
==========================================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/BUSINESS_openseries.png?itok=s7lXChId)
|
||||
|
||||
今年 Black Duck 和 North Bridge 发布了第十届年度开源软件前景调查,来调查开源软件的发展趋势。今年这份调查的亮点在于,当前主流社会对开源软件的接受程度以及过去的十年中人们对开源软件态度的变化。
|
||||
|
||||
[2016 年的开源软件前景调查][1],分析了来自约3400位专家的反馈。今年的调查中,开发者发表了他们的看法,大约 70% 的参与者是开发者。数据显示,安全专家的参与人数呈指数级增长,增长超过 450% 。他们的参与表明,开源社区开始逐渐关注开源软件中存在的安全问题,以及当新的技术出现时确保它们的安全性。
|
||||
|
||||
Black Duck 的[年度开源新秀奖][2] 涉及到一些新出现的技术,如容器方面的 Docker 和 Kontena。容器技术这一年有了巨大的发展 ———— 76% 的受访者表示,他们的企业有一些使用容器技术的规划。而 59% 的受访者正准备使用容器技术完成大量的部署,从开发与测试,到内部与外部的生产环境部署。开发者社区已经把容器技术作为一种简单快速开发的方法。
|
||||
|
||||
调查显示,几乎每个组织都有开发者致力于开源软件,这一点毫不惊讶。当像微软和苹果这样的大公司将它们的一些解决方案开源时,开发者就获得了更多的机会来参与开源项目。我非常希望这样的趋势会延续下去,让更多的软件开发者无论在工作中,还是工作之余都可以致力于开源项目。
|
||||
|
||||
### 2016 年调查结果中的一些要点
|
||||
|
||||
#### 商业价值
|
||||
|
||||
* 开源软件是发展战略中的一个重要元素,超过 65% 的受访者使用开源软件来加速软件开发的进度。
|
||||
* 超过 55% 的受访者在生产环境中使用开源软件。
|
||||
|
||||
#### 创新的原动力
|
||||
|
||||
* 受访者表示,开源软件的使用让软件开发更加快速灵活,从而推进了创新;同时加速了软件推向市场的时间,也极大地减少了与上司沟通的时间。
|
||||
* 开源软件的优质解决方案,富有竞争力的特性,技术能力,以及可定制化的能力,也促进了更多的创新。
|
||||
|
||||
#### 开源商业模式与投资的激增
|
||||
|
||||
* 更多不同商业模式的出现给开源企业带来了前所未有的价值。这些价值并不依赖于云服务和技术支持。
|
||||
* 开源的私募融资在过去的五年内,已增长了将近四倍。
|
||||
|
||||
#### 安全和管理
|
||||
|
||||
一流的开源安全与管理实践的发展,也没有跟上人们使用开源不断增长的步伐。尽管备受关注的开源项目近年来爆炸式地增长,调查结果却指出:
|
||||
|
||||
* 50% 的企业在选择和批准开源代码这方面没有出台正式的政策。
|
||||
* 47% 的企业没有正式的流程来跟踪开源代码,这就限制了它们对开源代码的了解,以及控制开源代码的能力。
|
||||
* 超过三分之一的企业没有用于识别、跟踪和修复重大开源安全漏洞的流程。
|
||||
|
||||
#### 不断增长的开源参与者
|
||||
|
||||
调查结果显示,一个活跃的企业开源社区,激励创新,提供价值,共享情谊:
|
||||
|
||||
* 67% 的受访者表示,它们积极鼓励开发者参与开源项目。
|
||||
* 65% 的企业正致力于开源项目。
|
||||
* 约三分之一的企业有专门为开源项目设置的全职岗位。
|
||||
* 59% 的受访者参与开源项目以获得竞争优势。
|
||||
|
||||
Black Duck 和 North Bridge 从今年的调查中了解到了很多,如安全,政策,商业模式等。我们很兴奋能够分享这些新发现。感谢我们的合作者,以及所有参与我们调查的受访者。这是一个伟大的十年,我很高兴我们可以肯定地说,开源的未来充满了无限可能。
|
||||
|
||||
想要了解更多内容,可以查看完整的[调查结果][3]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/16/5/2016-future-open-source-survey
|
||||
|
||||
作者:[Haidee LeClair][a]
|
||||
译者:[Cathon](https://github.com/Cathon)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
[a]: https://opensource.com/users/blackduck2016
|
||||
[1]: http://www.slideshare.net/blackducksoftware/2016-future-of-open-source-survey-results
|
||||
[2]: https://info.blackducksoftware.com/OpenSourceRookies2015.html
|
||||
[3]: http://www.slideshare.net/blackducksoftware/2016-future-of-open-source-survey-results%C2%A0
|
@ -1,12 +1,11 @@
|
||||
如何为登录和 sudo 设置双重认证
|
||||
如何为登录和 sudo 设置双因子认证
|
||||
==========================================================
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/auth_crop.png?itok=z_cdYZZf)
|
||||
>[Used with permission][1]
|
||||
|
||||
安全就是一切。我们生活的当今世界,数据具有令人难以置信的价值,而你也一直处于数据丢失的风险之中。因此,你必须想尽办法保证你桌面系统和服务器中东西的安全。结果,管理员和用户就会创建极其复杂的密码、使用密码管理器甚至其它更复杂的东西。但是,如果我告诉你你可以只需要一步-至多两步就能登录到你的 Linux 服务器或桌面系统中呢?多亏了 [Google Authenticator][2],现在你可以做到了。在这之上配置也极其简单。
|
||||
安全就是一切。我们生活的当今世界,数据具有令人难以置信的价值,而你也一直处于数据丢失的风险之中。因此,你必须想尽办法保证你桌面系统和服务器中数据的安全。结果,管理员和用户就会创建极其复杂的密码、使用密码管理器甚至其它更复杂的东西。但是,如果我告诉你你可以只需要一步,至多两步就能登录到你的 Linux 服务器或桌面系统中呢?多亏了 [Google 身份验证器][2],现在你可以做到了。并且,配置也极其简单。
|
||||
|
||||
我会给你简要介绍为登录和 sudo 设值双重认证的步骤。我基于 Ubuntu 16.04 桌面系统进行介绍,但这些步骤也适用于其它服务器。为了做到双重认证,我会使用 Google Authenticator。
|
||||
我会给你简要介绍为登录和 sudo 设置双因子认证的步骤。我基于 Ubuntu 16.04 桌面系统进行介绍,但这些步骤也适用于其它服务器。为了实现双因子认证,我会使用 Google 身份验证器。
|
||||
|
||||
这里有个非常重要的警告:一旦你设置了认证,没有一个从认证器中获得的由 6 个数字组成的验证码你就不可能登录账户(或者执行 sudo 命令)。这也给你增加了一步额外的操作,因此如果你不想每次登录到 Linux 服务器(或者使用 sudo)的时候都要拿出你的智能手机,这个方案就不适合你。但你也要记住,这额外的一个步骤也给你带来一层其它方法无法给予的保护。
|
||||
|
||||
@ -14,38 +13,28 @@
|
||||
|
||||
### 安装必要的组件
|
||||
|
||||
安装 Google 认证,首先要解决两个问题。一是安装智能机应用。下面是如何从 Google 应用商店安装的方法:
|
||||
安装 Google 身份验证器(Google Authenticator),首先要解决两个问题。一是安装智能机应用。下面是如何从 Google 应用商店安装的方法:
|
||||
|
||||
1. 在你的安卓设备中打开 Google 应用商店
|
||||
|
||||
2. 搜索 google 认证
|
||||
|
||||
3. 找到并点击有 Google 标识的应用
|
||||
|
||||
2. 搜索 google 身份验证器
|
||||
3. 找到并点击有 Google Inc. 标识的应用
|
||||
4. 点击安装
|
||||
|
||||
5. 点击 接受
|
||||
|
||||
5. 点击“接受”
|
||||
6. 等待安装完成
|
||||
|
||||
接下来,我们继续在你的 Linux 机器上安装认证。步骤如下:
|
||||
接下来,我们继续在你的 Linux 机器上安装这个认证器。步骤如下:
|
||||
|
||||
1. 打开一个终端窗口
|
||||
|
||||
2. 输入命令 sudo apt-get install google-authenticator
|
||||
|
||||
3. 输入你的 sudo 密码并敲击回车
|
||||
|
||||
4. 如果有弹窗提示,输入 y 并敲击回车
|
||||
|
||||
5. 等待安装完成
|
||||
|
||||
接下来配置使用 google-authenticator 进行登录。
|
||||
|
||||
### 配置
|
||||
|
||||
要为登录和 sudo 添加两阶段认证只需要编辑一个文件。也就是 /etc/pam.d/common-auth。打开并找到如下一行:
|
||||
Just one file must be edited to add two-step authentication for both login and sudo usage. The file is /etc/pam.d/common-auth. Open it and look for the line
|
||||
要为登录和 sudo 添加双因子认证只需要编辑一个文件,即 /etc/pam.d/common-auth。打开并找到如下一行:
|
||||
|
||||
```
|
||||
auth [success=1 default=ignore] pam_unix.so nullok_secure
|
||||
@ -59,57 +48,53 @@ auth required pam_google_authenticator.so
|
||||
|
||||
保存并关闭文件。
|
||||
|
||||
下一步就是为系统中的每个用户设置 google-authenticator(否则会不允许他们登录)。为了简单起见,我们假设你的系统中有两个用户:jack 和 olivia。首先为 jack 设置(我们假设这是我们一直使用的账户)。
|
||||
下一步就是为系统中的每个用户设置 google-authenticator(否则他们就不能登录了)。为了简单起见,我们假设你的系统中有两个用户:jack 和 olivia。首先为 jack 设置(我们假设这是我们一直使用的账户)。
|
||||
|
||||
打开一个终端窗口并输入命令 google-authenticator。之后会问你一系列的问题(每个问题你都应该用 y 回答)。问题包括:
|
||||
|
||||
* 是否允许更新你的 "/home/jlwallen/.google_authenticator" 文件 (y/n) y
|
||||
|
||||
* 是否禁止多个用户使用同一个认证令牌?这会限制你每 30 秒内只能登录一次,但能增加你注意到甚至防止中间人攻击的可能 (y/n)
|
||||
* 默认情况下令牌时长为 30 秒即可,为了补偿客户端和服务器之间可能出现的时间偏差,我们允许使用当前时间之前或之后的其它令牌。如果你无法进行时间同步,你可以把这个时间窗口由默认的 1:30 分钟增加到 4 分钟。是否希望如此 (y/n)
|
||||
* 如果你尝试登录的计算机没有针对暴力破解进行加固,你可以为验证模块启用速率限制。默认情况下,限制攻击者每 30 秒不能尝试登陆超过 3 次。是否启用速率限制 (y/n)
|
||||
|
||||
* 默认情况下令牌时长为 30 秒即可,为了补偿客户端和服务器之间可能出现的时间偏差,我们允许添加一个当前时间之前或之后的令牌。如果你无法进行时间同步,你可以把时间窗口由默认的 1:30 分钟增加到 4 分钟。是否希望如此 (y/n)
|
||||
|
||||
* 如果你尝试登陆的计算机没有针对蛮力登陆进行加固,你可以为验证模块启用速率限制。默认情况下,限制攻击者每 30 秒不能尝试登陆超过 3 次。是否启用速率限制 (y/n)
|
||||
|
||||
一旦完成了问题回答,你就会看到你的密钥、验证码以及 5 个紧急刮码。把刮码输出保存起来。你可以在无法使用手机的时候使用它们(每个刮码仅限使用一次)。密钥用于你在 Google Authenticator 上设置账户,验证码是你能立即使用(如果需要)的一次性验证码。
|
||||
一旦完成了问题回答,你就会看到你的密钥、验证码以及 5 个紧急刮码(emergency scratch code)。把这些刮码打印出来并保存。你可以在无法使用手机的时候使用它们(每个刮码仅限使用一次)。密钥用于你在 Google 身份验证器上设置账户,验证码是你能当下就能够立即使用(如果需要)的一次性验证码。
|
||||
|
||||
### 设置应用
|
||||
|
||||
现在你已经配置好了用户 jack。在设置用户 olivia 之前,你需要在 Google Authenticator 应用上为 jack 添加账户。在主屏幕上打开应用,点击 菜单 按钮(右上角三个竖排点)。点击添加账户然后输入提供的密钥。在下一个窗口(示意图1),你需要输入你运行 google-authenticator 应用时提供的 16 个数字的密钥。给账户取个名字(以便你记住这用于哪个账户),然后点击添加。
|
||||
现在你已经配置好了用户 jack。在设置用户 olivia 之前,你需要在 Google 身份验证器应用上为 jack 添加账户(LCTT 译注:实际操作情形中,是为 jack 的手机上安装的该应用创建一个账户)。在打开应用,点击“菜单”按钮(右上角三个竖排点)。点击“添加账户”然后点击“输入提供的密钥”。在下一个窗口(图1),你需要输入你运行 google-authenticator 应用时提供的 16 个数字的密钥。给账户取个名字(以便你记住这用于哪个账户),然后点击“添加”。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/auth_a.png?itok=xSMkd-Mf)
|
||||
>Figure 1: 在 Google Authenticator 应用上新建账户
|
||||
|
||||
*图1: 在 Google Authenticator 应用上新建账户*
|
||||
|
||||
(LCTT 译注:Google 身份验证器也可以扫描你在服务器上设置时显示的二维码,而不用手工输入密钥)
|
||||
|
||||
添加完账户之后,你就会看到一个 6 个数字的密码,你每次登录或者使用 sudo 的时候都会需要这个密码。
|
||||
|
||||
最后,在系统上设置其它账户。正如之前提到的,我们会设置一个叫 olivia 的账户。步骤如下:
|
||||
|
||||
1. 打开一个终端窗口
|
||||
|
||||
2. 输入命令 sudo su olivia
|
||||
|
||||
3. 在智能机上打开 Google Authenticator
|
||||
|
||||
4. 在终端窗口(示意图2)中输入(应用提供的) 6 位数字验证码并敲击回车
|
||||
|
||||
3. 在智能机上打开 Google 身份验证器
|
||||
4. 在终端窗口(图2)中输入(应用提供的) 6 位数字验证码并敲击回车
|
||||
5. 输入你的 sudo 密码并敲击回车
|
||||
|
||||
6. 以新用户输入命令 google-authenticator,回答问题并记录生成的密钥和验证码。
|
||||
|
||||
成功为 olivia 用户设置好之后,用 google-authenticator 命令,在 Google Authenticator 应用上根据用户信息(和之前为第一个用户添加账户相同)添加一个新的账户。现在你在 Google Authenticator 应用上就会有 jack 和 olivia 两个账户了。
|
||||
成功为 olivia 用户设置好之后,用 google-authenticator 命令,在 Google 身份验证器应用上根据用户信息(和之前为第一个用户添加账户相同)添加一个新的账户。现在你在 Google 身份验证器应用上就会有 jack 和 olivia 两个账户了。(LCTT 译注:在实际操作情形中,通常是为 jack 和 olivia 两个人的手机分别设置。)
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/auth_b.png?itok=FH36V1r0)
|
||||
>Figure 2: 为 sudo 输入 6位数字验证码
|
||||
|
||||
好了,就是这些。每次你尝试登陆系统(或者使用 sudo) 的时候,在你输入用户密码之前,都会要求你输入提供的 6 位数字验证码。现在你的 Linux 机器就比添加双重认证之前安全多了。虽然有些人会认为这非常麻烦,我仍然推荐使用,尤其是那些保存了敏感数据的机器。
|
||||
*图2: 为 sudo 输入 6位数字验证码*
|
||||
|
||||
好了,就是这些。每次你尝试登录系统(或者使用 sudo) 的时候,在你输入用户密码之前,都会要求你输入提供的 6 位数字验证码。现在你的 Linux 机器就比添加双因子认证之前安全多了。虽然有些人会认为这非常麻烦,我仍然推荐使用,尤其是那些保存了敏感数据的机器。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/auth_b.png?itok=FH36V1r0
|
||||
via: https://www.linux.com/learn/how-set-2-factor-authentication-login-and-sudo
|
||||
|
||||
作者:[JACK WALLEN][a]
|
||||
译者:[ictlyh](http://mutouxiaogui.cn/blog/)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
[a]: https://www.linux.com/users/jlwallen
|
||||
[1]: https://www.linux.com/licenses/category/used-permission
|
@ -3,17 +3,17 @@ Linux 上四个最佳的现代开源代码编辑器
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2015/01/Best_Open_Source_Editors.jpeg)
|
||||
|
||||
在寻找 **Linux 上最好的代码编辑器**?如果你问那些老派的 Linux 用户,他们的答案肯定是 Vi,Vim,Emacs,Nano 等等。但我不讨论它们。我要讨论的是最新的,美观,优美强大,功能丰富,能够提高你编程体验的,**最好的 Linux 开源代码编辑器**。
|
||||
在寻找 **Linux 上最好的代码编辑器**?如果你问那些老派的 Linux 用户,他们的答案肯定是 Vi,Vim,Emacs,Nano 等等。但我不讨论它们。我要讨论的是崭新、先进、优美、强大、功能丰富,能够提高你编程体验的**最好的 Linux 开源代码编辑器**。
|
||||
|
||||
### Linux 上最佳的现代开源代码编辑器
|
||||
|
||||
我使用 Ubuntu 作为我的主力系统,因此提供的安装说明适用于基于 Ubuntu 的发行版。但这并不会让这个列表变成 **Ubuntu 上的最佳文本编辑器**,因为这些编辑器对所有 Linux 发行版都适用。多说一句,这个清单没有任何先后顺序。
|
||||
我使用 Ubuntu 作为我的主力系统,因此提供的安装说明适用于基于 Ubuntu 的发行版。但这并不会让这个列表变成 **Ubuntu 上的最佳文本编辑器**,因为这些编辑器对所有 Linux 发行版都适用。多说一句,这个清单的排名没有任何先后顺序。
|
||||
|
||||
### BRACKETS
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2015/01/brackets_UI.jpeg)
|
||||
|
||||
[Brackets][1] 是 [Adobe][2] 的一个开源代码编辑器。Brackets 专注于 web 设计师的需求,内置 HTML,CSS 和 JavaScript 支持。它很轻量,也很强大。它提供了行内编辑和实时预览。还有无数可用的插件,进一步加强你在 Brackets 上的体验。
|
||||
[Brackets][1] 是来自 [Adobe][2] 的一个开源代码编辑器。Brackets 专注于 web 设计师的需求,内置 HTML、CSS 和 JavaScript 支持。它很轻量,也很强大。它提供了行内编辑和实时预览。还有无数可用的插件,可以进一步加强你在 Brackets 上的体验。
|
||||
|
||||
在 Ubuntu 以及基于 Ubuntu 的发行版(比如 Linux Mint)上[安装 Brackets][3] 的话,你可以用这个非官方的 PPA:
|
||||
|
||||
@ -25,52 +25,48 @@ sudo apt-get install brackets
|
||||
|
||||
至于其它 Linux 发行版,你可以从它的网站上获取到适用于 Linux,OS X 和 Windows 源码和二进制文件。
|
||||
|
||||
[下载 Brackets 源码和二进制包](https://github.com/adobe/brackets/releases)
|
||||
- [下载 Brackets 源码和二进制包](https://github.com/adobe/brackets/releases)
|
||||
|
||||
### ATOM
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2014/08/Atom_Editor.jpeg)
|
||||
|
||||
[Atom][4] 是另一个给程序员的开源代码编辑器,现代而且美观。Atom 是由 Github 开发的,宣称是“21世纪的可定制文本编辑器”。Atom 的外观看起来类似 Sublime Text,一个在程序员中很流行但是闭源的文本编辑器。
|
||||
[Atom][4] 是另一个给程序员的开源代码编辑器,现代而且美观。Atom 是由 Github 开发的,宣称是“面向21世纪的可魔改文本编辑器”。Atom 的外观看起来类似 Sublime Text,那是一个在程序员中很流行但是闭源的文本编辑器。
|
||||
|
||||
Atom 最近发布了 .deb 和 .rpm 包,所以你可以轻而易举地在基于 Debian 和 Fedora 的 Linux 发行版上安装它。当然,它也提供了源代码。
|
||||
|
||||
|
||||
[下载 Atom .deb](https://atom.io/download/deb)
|
||||
|
||||
[下载 Atom .rpm](https://atom.io/download/rpm)
|
||||
|
||||
[获取 Atom 源码](https://github.com/atom/atom/blob/master/docs/build-instructions/linux.md)
|
||||
- [下载 Atom .deb](https://atom.io/download/deb)
|
||||
- [下载 Atom .rpm](https://atom.io/download/rpm)
|
||||
- [获取 Atom 源码](https://github.com/atom/atom/blob/master/docs/build-instructions/linux.md)
|
||||
|
||||
### LIME TEXT
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2014/08/LimeTextEditor.jpeg)
|
||||
|
||||
你喜欢 Sublime Text 但是你对它是闭源的这一事实感觉不是很舒服?别担心,我们有 [Sublime Text 的开源克隆版][5],叫做 [Lime Text][6]。它是基于 Go,HTML 和 QT 的。克隆 Sublime Text 的原因是 Sublime Text 2 中有无数 bug,而 Sublime Text 3 看起来会永远处于 beta 之中。它的开发过程并不透明,也就无从得知 bug 是否被修复了。
|
||||
你喜欢 Sublime Text 但是你对它是闭源的这一事实感觉不是很舒服?别担心,我们有 [Sublime Text 的开源克隆版][5],叫做 [Lime Text][6]。它是基于 Go、HTML 和 QT 的。克隆 Sublime Text 的原因是 Sublime Text 2 中有无数 bug,而 Sublime Text 3 看起来会永远处于 beta 之中,而它的开发过程并不透明,也就无从得知 bug 是否被修复了。
|
||||
|
||||
所以开源爱好者们,开心地去下面这个链接下载 Lime Text 的源码吧:
|
||||
|
||||
[获取 Lime Text 源码](https://github.com/limetext/lime)
|
||||
- [获取 Lime Text 源码](https://github.com/limetext/lime)
|
||||
|
||||
### LIGHT TABLE
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2015/01/Light_Table.jpeg)
|
||||
|
||||
[Light Table][7] 是另一个外观现代,功能丰富的开源代码编辑器,标榜“下一代代码编辑器”,它更像一个 IDE 而不仅仅是个文本编辑器。它还有无数扩展用以加强它的功能。也许你会喜欢它的行内求值。你得用用它才会相信 Light Table 有多好用。
|
||||
[Light Table][7] 是另一个外观现代、功能丰富的开源代码编辑器,标榜为“下一代代码编辑器”,它更像一个 IDE 而不仅仅是个文本编辑器。它还有无数可以加强它的功能的扩展。也许你会喜欢它的行内求值。你得用用它才会相信 Light Table 有多好用。
|
||||
|
||||
[在 Ubuntu 上安装 Light Table](http://itsfoss.com/install-lighttable-ubuntu/)
|
||||
- [在 Ubuntu 上安装 Light Table](http://itsfoss.com/install-lighttable-ubuntu/)
|
||||
|
||||
### 你的选择是?
|
||||
|
||||
不,我们的选择没有限制在这四个 Linux 代码编辑器之中。这个清单只是关于程序员的现代编辑器。当然,你还有很多选择,比如 [Notepad++ 的替代选择 Notepadqq][8] 或 [SciTE][9] 以及更多。那么,上面四个中,在 Linux 上而言你最喜欢哪个代码编辑器?
|
||||
|
||||
不,我们的选择没有限制在这四个 Linux 代码编辑器之中。这个清单只是关于程序员的现代编辑器。当然,你还有很多选择,比如 [Notepad++ 的替代选择 Notepadqq][8] 或 [SciTE][9] 等等。那么,上面四个中,在 Linux 上而言你最喜欢哪个代码编辑器?
|
||||
|
||||
----------
|
||||
via: http://itsfoss.com/best-modern-open-source-code-editors-for-linux/?utm_source=newsletter&utm_medium=email&utm_campaign=offline_and_portable_linux_apps_and_other_linux_stories
|
||||
via: http://itsfoss.com/best-modern-open-source-code-editors-for-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,51 +1,54 @@
|
||||
安卓的下一场革命:不安装即可使用应用!
|
||||
===================================================================
|
||||
|
||||
谷歌安卓的一项新创新将可以让你无需安装即可在你的设备上使用应用程序。现在已经初具雏形。
|
||||
|
||||
谷歌安卓的一项新创新将让你可以使用没有在你的设备上安装的应用。现在已经有了一些原型了。
|
||||
还记得那时候吗,某人发给你了一个链接,要求你通过安装一个应用才能查看。
|
||||
|
||||
还记得某人给你发了一个链接,要求你安装一个应用来查看的情形吗?
|
||||
是否要安装这个应用就为了看一下链接,这种进退两难的选择一定让你感到很沮丧。而且,安装应用这个事也会消耗你不少宝贵的时间。
|
||||
|
||||
是否要安装这个应用来查看一个一次性的链接,这个困境一定让你感到很挫败。而且,应用安装本身也会消耗你不少宝贵的时间。
|
||||
上述场景可能大多数人都经历过,或者说大多数现代科技用户都经历过。尽管如此,我们都接受,认为这是天经地义的事情。
|
||||
|
||||
上述场景可能大多数人都经历过,或者说大多数现代科技用户都经历过。尽管如此,我们都接受这是正确且合理的过程。
|
||||
事实真的如此吗?
|
||||
|
||||
真的吗?
|
||||
针对这个问题谷歌的安卓部门给出了一个全新的、开箱即用的答案:
|
||||
|
||||
针对这个问题谷歌的安卓部门给出了一个全新的,开箱即用的答案:
|
||||
### Android Instant Apps (AIA)
|
||||
|
||||
### Android Instant Apps
|
||||
Android Instant Apps 声称可以从一开始就帮你摆脱这样的两难境地,让你简单地点击链接(见打开链接的示例)然后直接开始使用这个应用。
|
||||
|
||||
Android Instant Apps 声称第一时间帮你摆脱这样的两难境地,让你简单地点击链接(见打开链接的示例)然后直接开始使用这个应用。
|
||||
另一个真实生活场景的例子,如果你想停车但是没有停车码表的相应应用,有了 Instant Apps 在这种情况下就方便多了。
|
||||
|
||||
另一个真实生活场景的例子,如果你想停车但是没有停车码表的配对应用,有了 Instant Apps 在这种情况下就方便多了。
|
||||
|
||||
根据谷歌的信息,你可以简单地将你的手机和码表触碰,停车应用就会直接显示在你的屏幕上,并且准备就绪可以使用。
|
||||
根据谷歌提供的信息,你可以简单地将你的手机和码表触碰,停车应用就会直接显示在你的屏幕上,并且准备就绪可以使用。
|
||||
|
||||
#### 它是怎么工作的?
|
||||
|
||||
Instant Apps 和你已经熟悉的应用基本相同,只有一个不同——这些应用为了满足你完成某项任务的需要,只提供给你已经经过**裁剪和模块化**的应用关键部分。
|
||||
Instant Apps 和你已经熟悉的应用基本相同,只有一个不同——这些应用为了满足你完成某项任务的需要,只提供给你已经经过**裁剪和模块化**的应用必要部分。
|
||||
|
||||
例如,展开打开链接的场景作为例子,为了查看一个链接,你不需要拥有一个可以写,发送,做咖啡或其它特性的全功能应用。你所需要的全部就是查看功能——而这就是你所会获取到的部分。
|
||||
例如,展开打开链接的场景作为例子,为了查看一个链接,你不需要拥有一个可以写、发送,做咖啡或其它特性的全功能应用。你所需要的全部就是查看功能——而这就是你所会获取到的部分。
|
||||
|
||||
这样应用就可以快速打开,让你可以完成你的目标任务。
|
||||
|
||||
![](http://www.iwillfolo.com/wordpress/wp-content/uploads/2016/05/AIA-demo.jpg)
|
||||
>AIA 示例
|
||||
|
||||
*AIA 示例*
|
||||
|
||||
![](https://4.bp.blogspot.com/-p5WOrD6wVy8/VzyIpsDqULI/AAAAAAAADD0/xbtQjurJZ6EEji_MPaY1sLK5wVkXSvxJgCKgB/s800/B%2526H%2B-%2BDevice%2B%2528Final%2529.gif)
|
||||
>B&H 图片(通过谷歌搜索)
|
||||
|
||||
*B&H 图片(通过谷歌搜索)*
|
||||
|
||||
![](https://2.bp.blogspot.com/-q5ApCzECuNA/VzyKa9l0t2I/AAAAAAAADEI/nYhhMClDl5Y3qL5-wiOb2J2QjtGWwbF2wCLcB/s800/BuzzFeed-Device-Install%2B%2528Final%2529.gif)
|
||||
>BuzzFeedVideo(通过一个共享链接)
|
||||
|
||||
*BuzzFeedVideo(通过一个共享链接)*
|
||||
|
||||
![](https://2.bp.blogspot.com/-mVhKMMzhxms/VzyKg25ihBI/AAAAAAAADEM/dJN6_8H7qkwRyulCF7Yr2234-GGUXzC6ACLcB/s800/Park%2Band%2BPay%2B-%2BDevice%2Bwith%2BMeter%2B%2528Final%2529.gif)
|
||||
>停车与支付(例)(通过 NFC)
|
||||
|
||||
*停车与支付(例)(通过 NFC)*
|
||||
|
||||
|
||||
听起来很棒,不是吗?但是其中还有很多技术方面的问题需要解决。
|
||||
|
||||
比如,从安全的观点来说:如果任何应用从理论上来说都能在你的设备上运行,甚至你都不用安装它——你要怎么保证设备远离恶意软件攻击?
|
||||
比如,从安全的观点来说:从理论上来说,如果任何应用都能在你的设备上运行,甚至你都不用安装它——你要怎么保证设备远离恶意软件攻击?
|
||||
|
||||
因此,为了消除这类威胁,谷歌还在这个项目上努力,目前只有少数合作伙伴,未来将逐步扩展。
|
||||
|
||||
@ -59,7 +62,7 @@ via: http://www.iwillfolo.com/androids-next-revolution-use-apps-even-without-ins
|
||||
|
||||
作者:[iwillfolo][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[Caroline](https://github.com/carolinewuyan)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -5,19 +5,19 @@ ORB:新一代 Linux 应用
|
||||
|
||||
我们之前讨论过[在 Ubuntu 上离线安装应用][1]。我们现在要再次讨论它。
|
||||
|
||||
[Orbital Apps][2] 给我们带来了新的软件包类型,**ORB**,它带有便携软件,交互式安装向导支持,以及离线使用的能力。
|
||||
[Orbital Apps][2] 给我们带来了一种新的软件包类型 **ORB**,它具有便携软件、交互式安装向导支持,以及离线使用的能力。
|
||||
|
||||
便携软件很方便。主要是因为它们能够无需任何管理员权限直接运行,也能够带着所有的设置和数据随 U 盘存储。而交互式的安装向导也能让我们轻松地安装应用。
|
||||
|
||||
### 开放可运行包 OPEN RUNNABLE BUNDLE (ORB)
|
||||
### 开放式可运行的打包(OPEN RUNNABLE BUNDLE) (ORB)
|
||||
|
||||
ORB 是一个免费和开源的包格式,它和其它包格式在很多方面有所不同。ORB 的一些特性:
|
||||
ORB 是一个自由开源的包格式,它和其它包格式在很多方面有所不同。ORB 的一些特性:
|
||||
|
||||
- **压缩**:所有的包经过压缩,使用 squashfs,体积最多减少 60%。
|
||||
- **便携模式**:如果一个便携 ORB 应用是从可移动设备运行的,它会把所有设置和数据存储在那之上。
|
||||
- **压缩**:所有的包都经过 squashfs 压缩,体积最多可减少 60%。
|
||||
- **便携模式**:如果一个便携 ORB 应用是在可移动设备上运行的,它会把所有设置和数据存储在那之上。
|
||||
- **安全**:所有的 ORB 包使用 PGP/RSA 签名,通过 TLS 1.2 分发。
|
||||
- **离线**:所有的依赖都打包进软件包,所以不再需要下载依赖。
|
||||
- **开放包**:ORB 包可以作为 ISO 镜像挂载。
|
||||
- **开放式软件包**:ORB 软件包可以作为 ISO 镜像挂载。
|
||||
|
||||
### 种类
|
||||
|
||||
@ -26,19 +26,19 @@ ORB 应用现在有两种类别:
|
||||
- 便携软件
|
||||
- SuperDEB
|
||||
|
||||
#### 1. 便携 ORB 软件
|
||||
### 1. 便携 ORB 软件
|
||||
|
||||
便携 ORB 软件可以立即运行而不需要任何的事先安装。那意味着它不需要管理员权限和依赖!你可以直接从 Orbital Apps 网站下载下来就能使用。
|
||||
便携 ORB 软件可以立即运行而不需要任何的事先安装。这意味着它不需要管理员权限,也没有依赖!你可以直接从 Orbital Apps 网站下载下来就能使用。
|
||||
|
||||
并且由于它支持便携模式,你可以将它拷贝到 U 盘携带。它所有的设置和数据会和它一起存储在 U 盘。只需将 U 盘连接到任何运行 Ubuntu 16.04 的机器上就行了。
|
||||
|
||||
##### 可用便携软件
|
||||
#### 可用便携软件
|
||||
|
||||
目前有超过 35 个软件以便携包的形式提供,包括一些十分流行的软件,比如:[Deluge][3],[Firefox][4],[GIMP][5],[Libreoffice][6],[uGet][7] 以及 [VLC][8]。
|
||||
|
||||
完整的可用包列表可以查阅 [便携 ORB 软件列表][9]。
|
||||
|
||||
##### 使用便携软件
|
||||
#### 使用便携软件
|
||||
|
||||
按照以下步骤使用便携 ORB 软件:
|
||||
|
||||
@ -47,56 +47,48 @@ ORB 应用现在有两种类别:
|
||||
- 打开存储 ORB 包的目录。
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/using-portable-orb-app-1-1024x576.jpg)
|
||||
|
||||
- 打开 ORB 包的属性。
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/using-portable-orb-app-2.jpg)
|
||||
>给 ORB 包添加运行权限
|
||||
![给 ORB 包添加运行权限](http://itsfoss.com/wp-content/uploads/2016/05/using-portable-orb-app-2.jpg)
|
||||
|
||||
- 在权限标签页添加运行权限。
|
||||
- 双击打开它。
|
||||
|
||||
等待几秒,让它准备好运行。大功告成。
|
||||
|
||||
#### 2. SuperDEB
|
||||
### 2. SuperDEB
|
||||
|
||||
另一种类型的 ORB 软件是 SuperDEB。SuperDEB 很简单,交互式安装向导能够让软件安装过程顺利得多。如果你不喜欢从终端或软件中心安装软件,superDEB 就是你的菜。
|
||||
|
||||
最有趣的部分是你安装时不需要一个互联网连接,因为所有的依赖都由安装向导打包了。
|
||||
|
||||
##### 可用的 SuperDEB
|
||||
#### 可用的 SuperDEB
|
||||
|
||||
超过 60 款软件以 SuperDEB 的形式提供。其中一些流行的有:[Chromium][10],[Deluge][3],[Firefox][4],[GIMP][5],[Libreoffice][6],[uGet][7] 以及 [VLC][8]。
|
||||
|
||||
完整的可用 SuperDEB 列表,参阅 [SuperDEB 列表][11]。
|
||||
|
||||
##### 使用 SuperDEB 安装向导
|
||||
#### 使用 SuperDEB 安装向导
|
||||
|
||||
- 从 Orbital Apps 网站下载需要的 SuperDEB。
|
||||
- 像前面一样给它添加**运行权限**(属性 > 权限)。
|
||||
- 双击 SuperDEB 安装向导并按下列说明操作:
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-1.png)
|
||||
>点击 OK
|
||||
![点击 OK](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-1.png)
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-2.png)
|
||||
>输入你的密码并继续
|
||||
![输入你的密码并继续](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-2.png)
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-3.png)
|
||||
>它会开始安装…
|
||||
![它会开始安装…](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-3.png)
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-4.png)
|
||||
>一会儿他就完成了…
|
||||
![一会儿它就完成了…](http://itsfoss.com/wp-content/uploads/2016/05/Using-SuperDEB-Installer-4.png)
|
||||
|
||||
- 完成安装之后,你就可以正常使用了。
|
||||
|
||||
### ORB 软件兼容性
|
||||
|
||||
从 Orbital Apps 可知,它们完全适配 Ubuntu 16.04 [64 bit]。
|
||||
从 Orbital Apps 可知,它们完全适配 Ubuntu 16.04 [64 位]。
|
||||
|
||||
>阅读建议:[如何在 Ubuntu 获知你的是电脑 32 位还是 64 位的][12]。
|
||||
|
||||
至于其它发行版兼容性不受保证。但我们可以说,它在所有 Ubuntu 16.04 衍生版(UbuntuMATE,UbuntuGNOME,Lubuntu,Xubuntu 等)以及基于 Ubuntu 16.04 的发行版(比如即将到来的 Linux Mint 18)上都适用。我们现在还不清楚 Orbital Apps 是否有计划拓展它的支持到其它版本 Ubuntu 或 Linux 发行版上。
|
||||
至于其它发行版兼容性则不受保证。但我们可以说,它在所有 Ubuntu 16.04 衍生版(UbuntuMATE,UbuntuGNOME,Lubuntu,Xubuntu 等)以及基于 Ubuntu 16.04 的发行版(比如即将到来的 Linux Mint 18)上都适用。我们现在还不清楚 Orbital Apps 是否有计划拓展它的支持到其它版本 Ubuntu 或 Linux 发行版上。
|
||||
|
||||
如果你在你的系统上经常使用便携 ORB 软件,你可以考虑安装 ORB 启动器。它不是必需的,但是推荐安装它以获取更佳的体验。最简短的 ORB 启动器安装流程是打开终端输入以下命令:
|
||||
|
||||
@ -116,11 +108,11 @@ wget -O - https://www.orbital-apps.com/orb.sh | bash
|
||||
|
||||
|
||||
----------------------------------
|
||||
via: http://itsfoss.com/orb-linux-apps/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29
|
||||
via: http://itsfoss.com/orb-linux-apps/
|
||||
|
||||
作者:[Munif Tanjim][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,106 @@
|
||||
与 Linux 一同驾车奔向未来
|
||||
===========================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/open-snow-car-osdc-lead.png?itok=IgYZ6mNY)
|
||||
|
||||
当我驾车的时候并没有这么想过,但是我肯定喜欢一个配有这样系统的车子,它可以让我按下几个按钮就能与我的妻子、母亲以及孩子们语音通话。这样的系统也可以让我选择是否从云端、卫星广播、以及更传统的 AM/FM 收音机收听音乐流媒体。我也会得到最新的天气情况,以及它可以引导我的车载 GPS 找到抵达下一个目的地的最快路线。[车载娱乐系统(In-vehicle infotainment)][1],业界常称作 IVI,它已经普及出现在最新的汽车上了。
|
||||
|
||||
前段时间,我乘坐飞机跨越了数百英里,然后租了一辆汽车。令人愉快的是,我发现我租赁的汽车上配置了类似我自己车上同样的 IVI 技术。毫不犹豫地,我就通过蓝牙连接把我的联系人上传到了系统当中,然后打电话回家给我的家人,让他们知道我已经安全抵达了,然后我的主机会让他们知道我正在去往他们家的路上。
|
||||
|
||||
在最近的[新闻综述][2]中,Scott Nesbitt 引述了一篇文章,说福特汽车公司因其开源的[智能设备连接(Smart Device Link)][3](SDL)从竞争对手汽车制造商中得到了足够多的回报,这个中间件框架可以用于支持移动电话。 SDL 是 [GENIVI 联盟][4]的一个项目,这个联盟是一个非营利性组织,致力于建设支持开源车载娱乐系统的中间件。据 GENIVI 的执行董事 [Steven Crumb][5] 称,他们的[成员][6]有很多,包括戴姆勒集团、现代、沃尔沃、日产、本田等等 170 个企业。
|
||||
|
||||
为了在同行业间保持竞争力,汽车生产企业需要一个中间设备系统,以支持现代消费者所使用的各种人机界面技术。无论您使用的是 Android、iOS 还是其他设备,汽车 OEM 厂商都希望自己的产品能够支持这些。此外,这些的 IVI 系统必须有足够适应能力以支持日益变化的移动技术。OEM 厂商希望提供有价值的服务,并可以在他们的 IVI 之上增加服务,以满足他们客户的各种需求。
|
||||
|
||||
### 步入 Linux 和开源软件
|
||||
|
||||
除了 GENIVI 在努力之外,[Linux 基金会][7]也赞助支持了[车载 Linux(Automotive Grade Linux)][8](AGL)工作组,这是一个致力于为汽车应用寻求开源解决方案的软件基金会。虽然 AGL 初期将侧重于 IVI 系统,但是未来他们希望发展到不同的方向,包括[远程信息处理(telematics)][9]、抬头显示器(HUD)及其他控制系统等等。 现在 AGL 已经有超过 50 名成员,包括捷豹、丰田、日产,并在其[最近发布的一篇公告][10]中宣称福特、马自达、三菱、和斯巴鲁也加入了。
|
||||
|
||||
为了了解更多信息,我们采访了这一新兴领域的两位领导人。具体来说,我们想知道 Linux 和开源软件是如何被使用的,并且它们是如何事实上改变了汽车行业的面貌。首先,我们将与 [Alison Chaiken][11] 谈谈,她是一位任职于 Peloton Technology 的软件工程师,也是一位在车载 Linux 、网络安全和信息透明化方面的专家。她曾任职于 [Alison Chaiken][11] 公司、诺基亚和斯坦福直线性加速器。然后我们和 [Steven Crumb][12] 进行了交谈,他是 GENIVI 执行董事,他之前从事于高性能计算环境(超级计算机和早期的云计算)的开源工作。他说,虽然他再不是一个程序员了,但是他乐于帮助企业解决在使用开源软件时的实际业务问题。
|
||||
|
||||
### 采访 Alison Chaiken (by [Deb Nicholson][13])
|
||||
|
||||
#### 你是如何开始对汽车软件领域感兴趣的?
|
||||
|
||||
我曾在诺基亚从事于手机上的 [MeeGo][14] 产品,2009 年该项目被取消了。我想,我下一步怎么办?其时,我的一位同事正在从事于 [MeeGo-IVI][15],这是一个早期的车载 Linux 发行版。 “Linux 在汽车方面将有很大发展,” 我想,所以我就朝着这个方向努力。
|
||||
|
||||
#### 你能告诉我们你在这些日子里工作在哪些方面吗?
|
||||
|
||||
我目前正在启动一个高级巡航控制系统的项目,它用在大型卡车上,使用实时 Linux 以提升安全性和燃油经济性。我喜欢在这方面的工作,因为没有人会反对提升货运的能力。
|
||||
|
||||
#### 近几年有几则汽车被黑的消息。开源代码方案可以帮助解决这个问题吗?
|
||||
|
||||
我恰好针对这一话题准备了一次讲演,我会在南加州 Linux 2016 博览会上就 Linux 能否解决汽车上的安全问题做个讲演 ([讲演稿在此][16])。值得注意的是,GENIVI 和车载 Linux 项目已经公开了他们的代码,这两个项目可以通过 Git 提交补丁。(如果你有补丁的话),请给上游发送您的补丁!许多眼睛都盯着,bug 将无从遁形。
|
||||
|
||||
#### 执法机构和保险公司可以找到很多汽车上的数据的用途。他们获取这些信息很容易吗?
|
||||
|
||||
好问题。IEEE-1609 专用短程通信标准(Dedicated Short Range Communication Standard)就是为了让汽车的 WiFi 消息可以安全、匿名地传递。不过,如果你从你的车上发推,那可能就有人能够跟踪到你。
|
||||
|
||||
#### 开发人员和公民个人可以做些什么,以在汽车技术进步的同时确保公民自由得到保护?
|
||||
|
||||
电子前沿基金会( Electronic Frontier Foundation)(EFF)在关注汽车问题方面做了出色的工作,包括对哪些数据可以存储在汽车 “黑盒子”里通过官方渠道发表了看法,以及 DMCA 规定 1201 如何应用于汽车上。
|
||||
|
||||
#### 在未来几年,你觉得在汽车方面会发生哪些令人激动的发展?
|
||||
|
||||
可以拯救生命的自适应巡航控制系统和防撞系统将取得长足发展。当它们大量进入汽车里面时,我相信这会使得(因车祸而导致的)死亡人数下降。如果这都不令人激动,我不知道还有什么会更令人激动。此外,像自动化停车辅助功能,将会使汽车更容易驾驶,减少汽车磕碰事故。
|
||||
|
||||
#### 我们需要做什么?人们怎样才能参与?
|
||||
|
||||
车载 Linux 开发是以开源的方式开发,它运行在每个人都能买得起的廉价硬件上(如树莓派 2 和中等价位的 Renesas Porter 主板)。 GENIVI 汽车 Linux 中间件联盟通过 Git 开源了很多软件。此外,还有很酷的 [OSVehicle 开源硬件][17]汽车平台。
|
||||
|
||||
只需要不太多的预算,人们就可以参与到 Linux 软件和开放硬件中。如果您感兴趣,请加入我们在 Freenode 上的IRC #automotive 吧。
|
||||
|
||||
### 采访 Steven Crumb (by Don Watkins)
|
||||
|
||||
#### GENIVI 在 IVI 方面做了哪些巨大贡献?
|
||||
|
||||
GENIVI 率先通过使用自由开源软件填补了汽车行业的巨大空白,这包括 Linux、非安全关键性汽车软件(如车载娱乐系统(IVI))等。作为消费者,他们很期望在车辆上有和智能手机一样的功能,对这种支持 IVI 功能的软件的需求量成倍地增长。不过不断提升的软件数量也增加了建设 IVI 系统的成本,从而延缓了其上市时间。
|
||||
|
||||
GENIVI 使用开源软件和社区开发的模式为汽车制造商及其软件提供商节省了大量资金,从而显著地缩短了产品面市时间。我为 GENIVI 而感到激动,我们有幸引导了一场革命,在缓慢进步的汽车行业中,从高度结构化和专有的解决方案转换为以社区为基础的开发方式。我们还没有完全达成目标,但是我们很荣幸在这个可以带来实实在在好处的转型中成为其中的一份子。
|
||||
|
||||
#### 你们的主要成员怎样推动了 GENIVI 的发展方向?
|
||||
|
||||
GENIVI 有很多成员和非成员致力于我们的工作。在许多开源项目中,任何公司都可以通过通过技术输出而发挥影响,包括简单地贡献代码、补丁、花点时间测试。前面说过,宝马、奔驰、现代汽车、捷豹路虎、标致雪铁龙、雷诺/日产和沃尔沃都是 GENIVI 积极的参与者和贡献者,其他的许多 OEM 厂商也在他们的汽车中采用了 IVI 解决方案,广泛地使用了 GENIVI 的软件。
|
||||
|
||||
#### 这些贡献的代码使用了什么许可证?
|
||||
|
||||
GENIVI 采用了一些许可证,包括从(L)GPLv2 到 MPLv2 和 Apache2.0。我们的一些工具使用的是 Eclipse 许可证。我们有一个[公开许可策略][18],详细地说明了我们的许可证偏好。
|
||||
|
||||
#### 个人或团体如何参与其中?社区的参与对于这个项目迈向成功有多重要?
|
||||
|
||||
GENIVI 的开发完全是开放的([projects.genivi.org][19]),因此,欢迎任何有兴趣在汽车中使用开源软件的人参加。也就是说,公司可以通过成员的方式[加入该联盟][20],联盟以开放的方式资助其不断进行开发。GENIVI 的成员可以享受各种各样的便利,在过去六年中,已经有多达 140 家公司参与到这个全球性的社区当中。
|
||||
|
||||
社区对于 GENIVI 是非常重要的,没有一个活跃的贡献者社区,我们不可能在这些年开发和维护了这么多有价值的软件。我们努力让参与到 GENIVI 更加简单,现在只要加入一个[邮件列表][21]就可以接触到各种软件项目中的人们。我们使用了许多开源项目采用的标准做法,并提供了高品质的工具和基础设施,以帮助开发人员宾至如归而富有成效。
|
||||
|
||||
无论你是否熟悉汽车软件,都欢迎你加入我们的社区。人们已经对汽车改装了许多年,所以对于许多人来说,在汽车上修修改改是自热而然的做法。对于汽车来说,软件是一个新的领域,GENIVI 希望能为对汽车和开源软件有兴趣的人打开这扇门。
|
||||
|
||||
-------------------------------
|
||||
via: https://opensource.com/business/16/5/interview-alison-chaiken-steven-crumb
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
译者:[erlinux](https://github.com/erlinux)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[1]: https://en.wikipedia.org/wiki/In_car_entertainment
|
||||
[2]: https://opensource.com/life/16/1/weekly-news-jan-9
|
||||
[3]: http://projects.genivi.org/smartdevicelink/home
|
||||
[4]: http://www.genivi.org/
|
||||
[5]: https://www.linkedin.com/in/stevecrumb
|
||||
[6]: http://www.genivi.org/genivi-members
|
||||
[7]: http://www.linuxfoundation.org/
|
||||
[8]: https://www.automotivelinux.org/
|
||||
[9]: https://en.wikipedia.org/wiki/Telematics
|
||||
[10]: https://www.automotivelinux.org/news/announcement/2016/01/ford-mazda-mitsubishi-motors-and-subaru-join-linux-foundation-and
|
||||
[11]: https://www.linkedin.com/in/alison-chaiken-3ba456b3
|
||||
[12]: https://www.linkedin.com/in/stevecrumb
|
||||
[13]: https://opensource.com/users/eximious
|
||||
[14]: https://en.wikipedia.org/wiki/MeeGo
|
||||
[15]: http://webinos.org/deliverable-d026-target-platform-requirements-and-ipr/automotive/
|
||||
[16]: http://she-devel.com/Chaiken_automotive_cybersecurity.pdf
|
||||
[17]: https://www.osvehicle.com/
|
||||
[18]: http://projects.genivi.org/how
|
||||
[19]: http://projects.genivi.org/
|
||||
[20]: http://genivi.org/join
|
||||
[21]: http://lists.genivi.org/mailman/listinfo/genivi-projects
|
@ -0,0 +1,77 @@
|
||||
在 OpenStack 云中测试 Fedora 24 Beta
|
||||
===========================================
|
||||
|
||||
![](https://major.io/wp-content/uploads/2012/01/fedorainfinity.png)
|
||||
|
||||
虽然离 [Fedora 24][1] 还有几周,你现在可以就测试Fedora 24 Beta了。这是一个[窥探新特性][2]的好机会,并且可以帮助他们找出仍需要修复的 bug。
|
||||
|
||||
[Fedora Cloud][3] 镜像可以从你常用的[本地镜像][4]或者 [Fedora 的服务器][5]中下载。本篇文章我将向你展示如何将这个镜像导入 OpenStack 环境并且测试 Fedora 24 Beta。
|
||||
|
||||
最后说一下:这还是 beta 软件。目前对我来说是可靠的,但是你的体验可能会不同。我建议你等到正式版发布再在上面部署关键的应用。
|
||||
|
||||
### 导入镜像
|
||||
|
||||
旧版的 glance 客户端(版本1)允许你在 OpenStack 环境中导入一个可通过 URL 访问的镜像。由于我 OpenStack 云的连接速度(1 Gbps)比我家 (大约 20 mbps 上传速度)快,这个功能对我很有用。然而,从 URL 导入的功能[在 glance v2 中被移除了]。[OpenStackClient][7] 也不支持这个功能。
|
||||
|
||||
现在由两个选择:
|
||||
|
||||
- 安装旧版的 glance 客户端
|
||||
- 使用 Horizon (网页面板)
|
||||
|
||||
获取旧版本的 glance 是有挑战性的。OpenStack liberty 版本的需求文件[对 glance 客户端没有最高版本上限][8],并且很难找到让旧版客户端工作的依赖文件。
|
||||
|
||||
让我们使用 Horizon,这就是写这篇文章的原因。
|
||||
|
||||
### 在 Horizon 中添加一个镜像
|
||||
|
||||
登录 Horizon 面板,点击 Compute->Image。点击页面右上方的“+ Create Image”,一个新的窗口会显示出来。并且窗口中有这些信息:
|
||||
|
||||
- **Name**: Fedora 24 Cloud Beta
|
||||
- **Image Source**: 镜像位置
|
||||
- **Image Location**: http://mirrors.kernel.org/fedora/releases/test/24_Beta/CloudImages/x86_64/images/Fedora-Cloud-Base-24_Beta-1.6.x86_64.qcow2
|
||||
- **Format**: QCOW2 – QEMU 模拟器
|
||||
- **Copy Data**: 确保勾选了
|
||||
|
||||
完成后,你会看到这个:
|
||||
|
||||
![](https://major.io/wp-content/uploads/2016/05/horizon_image.png)
|
||||
|
||||
点击“创建镜像(Creat Image)”,接着镜像列表会显示一段时间的 Saving 信息。一旦切换到 Active,你就可以构建一个实例了。
|
||||
|
||||
### 构建实例
|
||||
|
||||
既然我们在使用 Horizon,我们可以在此完成构建过程。
|
||||
|
||||
在镜像列表页面,找出我们上传的镜像并且点击右边的启动实例(Launch Instance)。一个新的窗口会显示出来。镜像名(Image Name)下拉框中应该已经选择了 Fedora 24 Beta 的镜像。在这里,选择一个实例名,选择一个安全组和密钥对(在 Access & Security 标签中)和网络(在 Networking 标签)。确保选择有足够容量的存储(m1.tiny 不太够)。
|
||||
|
||||
点击启动(Launch)并且等待实例启动。
|
||||
|
||||
一旦实例构建完成,你能以用户 fedora 通过 ssh 连接到实例。如果你的[安全组允许连接][9]并且你的密钥对正确配置了,你应该进入到 Fedora 24 Beta 中了!
|
||||
|
||||
还不确定接下来做什么?有下面几点建议:
|
||||
|
||||
- 升级所有的包并且重启(确保你测试的是最新的更新)
|
||||
- 安装一些熟悉的应用并且验证它们可以正常工作
|
||||
- 测试你已有的自动化或者配置管理工具
|
||||
- 打开 bug 报告
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://major.io/2016/05/24/test-fedora-24-beta-openstack-cloud/
|
||||
|
||||
作者:[major.io][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://major.io/about-the-racker-hacker/
|
||||
[1]: https://fedoraproject.org/wiki/Releases/24/Schedule
|
||||
[2]: https://fedoraproject.org/wiki/Releases/24/ChangeSet
|
||||
[3]: https://getfedora.org/en/cloud/
|
||||
[4]: https://admin.fedoraproject.org/mirrormanager/mirrors/Fedora/24/x86_64
|
||||
[5]: https://getfedora.org/en/cloud/download/
|
||||
[6]: https://wiki.openstack.org/wiki/Glance-v2-v1-client-compatability
|
||||
[7]: http://docs.openstack.org/developer/python-openstackclient/
|
||||
[8]: https://github.com/openstack/requirements/blob/stable/liberty/global-requirements.txt#L159
|
||||
[9]: https://major.io/2016/05/16/troubleshooting-openstack-network-connectivity/
|
@ -11,119 +11,111 @@
|
||||
|
||||
这个列表和我们先前的 [最佳图像程序应用][1] 有些差别,上次我们介绍了图像编辑软件,绘图软件等,而这次的介绍主要集中在图像管理软件上。
|
||||
|
||||
好,下面我们开始介绍。我会详细说明在 Ubuntu 下的安装命令以及衍生的命令,我们只需要打开终端运行这些命令。
|
||||
好,下面我们开始介绍。我会详细说明在 Ubuntu 及其衍生版下的安装命令,我们只需要打开终端运行这些命令。
|
||||
|
||||
### [GTHUMB](https://wiki.gnome.org/Apps/gthumb)
|
||||
### [gThumb](https://wiki.gnome.org/Apps/gthumb)
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/gThumb-1-1024x540.jpg)
|
||||
>gThumb 图像编辑器
|
||||
|
||||
gThumb 是在 GNOME 桌面环境下的一个轻量级的图像管理应用,它涵盖了基本图像管理功能,编辑图片以及更加高级的操作,gThumb 主要功能如下:
|
||||
*gThumb 图像编辑器*
|
||||
|
||||
- 图片查看:支持所有主流的图片格式(包括gif)和元数据(EXIF, XMP 等)。
|
||||
gThumb 是在 GNOME 桌面环境下的一个轻量级的图像管理应用,它涵盖了基本图像管理功能,比如编辑图片以及更加高级的操作等,gThumb 主要功能如下:
|
||||
|
||||
- 图片浏览:所有基础的浏览操作(缩略图,移动,复制,删除等)以及书签支持。
|
||||
- 图片查看:支持所有主流的图片格式(包括 gif)和元数据(EXIF、 XMP 等)。
|
||||
- 图片浏览:所有基础的浏览操作(缩略图、移动、复制、删除等)以及书签支持。
|
||||
- 图片管理:使用标签、目录和库来组织图片。从数码相机导入图片,集成了网络相册(Picasa,Flickr,Facebook等)。
|
||||
- 图片编辑:基本图像编辑操作、滤镜、格式转换等。
|
||||
|
||||
- 图片管理:使用标签操作图片,目录和图片库。从数码相机,网络相册(Picasa,Flickr,Facebook等)整合,导入图片。
|
||||
更多功能请参考官方 [gThumb 功能][2] 列表。如果你使用的是 GNOME 或者基于 GNOME 的桌面环境(如 MATE),那么你一定要试用一下。
|
||||
|
||||
- 图片编辑:基本图像编辑操作,滤镜,格式转换等。
|
||||
|
||||
- 更多功能请参考官方 [gThumb功能][2] 列表。如果你使用的是 GNOME 或者基于 GNOME 的桌面环境(如 MATE),那么你一定要试用一下。
|
||||
|
||||
#### GTHUMB 安装
|
||||
#### gThumb 安装
|
||||
|
||||
```
|
||||
sudo apt-get install gthumb
|
||||
```
|
||||
|
||||
|
||||
### [DIGIKAM][3]
|
||||
### [digiKam][3]
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/digiKam-1-1024x540.png)
|
||||
>digiKam
|
||||
|
||||
*digiKam*
|
||||
|
||||
digiKam 主要为 KDE 而设计,在其他桌面环境下也可以使用。它有很多很好的图像界面功能,主要功能如下所示:
|
||||
|
||||
- 图片管理:相册,子相册,标签,评论,元数据,排序支持。
|
||||
|
||||
- 图片导入:支持从数码相机,USB设备,网络相册(包括 Picasa 和 Facebook)导入,以及另外一些功能。
|
||||
|
||||
- 图片输出:支持输出至很多网络在线平台,以及各式转换。
|
||||
|
||||
- 图片管理:相册、子相册、标签、评论、元数据、排序支持。
|
||||
- 图片导入:支持从数码相机、USB设备、网络相册(包括 Picasa 和 Facebook)导入,以及另外一些功能。
|
||||
- 图片输出:支持输出至很多网络在线平台,以及格式转换。
|
||||
- 图片编辑:支持很多图像编辑的操作。
|
||||
|
||||
digiKam 是众多优秀图像管理软件之一。
|
||||
毫无疑问,digiKam 如果不是最好的图像管理软件,也是之一。
|
||||
|
||||
#### DIGIKAM 安装
|
||||
#### digiKam 安装
|
||||
|
||||
```
|
||||
sudo apt-get install digikam
|
||||
```
|
||||
|
||||
### [SHOTWELL][4]
|
||||
### [Shotwell][4]
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Shotwell-1-1024x540.png)
|
||||
>Shotwell
|
||||
|
||||
*Shotwell*
|
||||
|
||||
Shotwell 图像管理也是为 GNOME 桌面环境设计,虽然功能不及 gThumb 多,但满足了基本需求。主要功能如下:
|
||||
|
||||
- 从磁盘或数码相机导入图片。
|
||||
|
||||
- 项目,标签和文件夹管理。
|
||||
|
||||
- 事件、标签和基于文件夹的图片管理方式。
|
||||
- 基本图片编辑功能和格式转换。
|
||||
|
||||
- 支持上传至网络平台(Facebook,Flickr,Tumblr 等)。
|
||||
|
||||
如果你想要一款功能相对简单的应用,你可以尝试一下这个。
|
||||
|
||||
#### SHOTWELL 安装
|
||||
#### Shotwell 安装
|
||||
|
||||
```
|
||||
sudo apt-get install shotwell
|
||||
```
|
||||
|
||||
### [KPHOTOALBUM][5]
|
||||
### [KPhotoAlbum][5]
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/KPhotoAlbum-1-1024x540.png)
|
||||
>KPhotoAlbum
|
||||
|
||||
KPhotoAlbum 是一款在 KDE 桌面环境下的图像管理应用。它有一些独特的功能:分类和基于时间浏览。你可以基于人物,地点,时间分类;另外在用户图形界面底部会显示时间栏。
|
||||
*KPhotoAlbum*
|
||||
|
||||
KPhotoAlbum 是一款在 KDE 桌面环境下的图像管理应用。它有一些独特的功能:分类和基于时间浏览。你可以基于人物、地点、时间分类;另外在用户图形界面底部会显示时间栏。
|
||||
|
||||
KPhotoAlbum 有很多图像管理和编辑功能,主要功能包括:
|
||||
|
||||
- 高级图片操作(目录,子目录,标签,元数据,注释等)。
|
||||
|
||||
- 高级图片操作(分类、子分类、标签、元数据、注释等等)。
|
||||
- 图片导入导出功能(包括主流图片分享平台)。
|
||||
|
||||
- 众多编辑功能(包括批量处理)。
|
||||
|
||||
这些高级的功能有它们的缺点,就是用户需要手工操作。但如果你是KDE爱好者,这是个好的选择。它完美适用 KDE,但是你也可以在非 KDE 桌面环境下使用 KPhotoAlbum。
|
||||
这些高级的功能有一些缺点,就是用户大多需要手工操作。但如果你是 KDE 爱好者,这是个好的选择。它完美适用 KDE,但是你也可以在非 KDE 桌面环境下使用 KPhotoAlbum。
|
||||
|
||||
#### KPHOTOALBUM 安装
|
||||
#### KPhotoAlbum 安装
|
||||
|
||||
```
|
||||
sudo apt-get install kphotoalbum
|
||||
```
|
||||
|
||||
### [DARKTABLE][7]
|
||||
### [Darktable][7]
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/darktable-1-1024x540.png)
|
||||
>Darktable
|
||||
|
||||
Darktable 相较于图像管理更偏向于图像编辑。Darktable 有良好的用户图形界面,对桌面环境没有特殊的要求,以及图像编辑功能。它的基本功能如下:
|
||||
*Darktable*
|
||||
|
||||
Darktable 与其说是图像管理工具,不如说是图像编辑软件。Darktable 有良好的用户图形界面,对桌面环境没有特殊的要求,这也不会影响到它的图像编辑功能。它的基本功能如下:
|
||||
|
||||
- 基本图片管理。
|
||||
|
||||
- 众多高级的图片编辑功能。
|
||||
|
||||
- 支持导出至 Picasa 和 Flickr 和格式转换。
|
||||
|
||||
如果你喜欢照片编辑和润色,Darktable 是个好的选择。
|
||||
|
||||
> 推荐阅读:[怎样在 Ubuntu 下通过 PPA 安装 Darktable 2.0][8]
|
||||
|
||||
#### DARKTABLE 安装
|
||||
#### Darktable 安装
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:pmjdebruijn/darktable-release
|
||||
@ -133,7 +125,7 @@ sudo apt-get install darktable
|
||||
|
||||
### 其它
|
||||
|
||||
如果你想要功能简单的应用,比如从便携设备(相机,手机,便携设备等)中导入照片并存入磁盘,使用 [Rapid Photo Downloader][9],它很适合从便携设备中导入和备份图片,而且安装配置过程简单。
|
||||
如果你想要功能简单的应用,比如从便携设备(相机、手机、便携设备等)中导入照片并存入磁盘,毫无疑问该使用 [Rapid Photo Downloader][9],它很适合从便携设备中导入和备份图片,而且安装配置过程简单。
|
||||
|
||||
在 Ubuntu 上安装 Rapid Photo Downloade,打开终端输入命令:
|
||||
|
||||
@ -142,18 +134,19 @@ sudo apt-get install rapid-photo-downloader
|
||||
```
|
||||
|
||||
如果你想尝试更多的选择:
|
||||
|
||||
- [GNOME Photos][10] (GNOME 桌面环境下的图像查看器)
|
||||
- [Gwenview][11] (KDE 桌面环境下的图像查看器)
|
||||
- [Picty][12] (开源图像管理器)
|
||||
|
||||
那么,你正在使用,或者打算使用其中一款应用吗?你有其它更好的推荐吗?你有最喜欢的 Linux 图像管理软件吗?分享你的观点。
|
||||
那么,你正在使用,或者打算使用其中一款应用吗?在 Ubuntu 或其它 Linux 上你有其它更好的推荐吗?你有最喜欢的 Linux 图像管理软件吗?分享你的观点给我们。
|
||||
|
||||
----------
|
||||
via: http://itsfoss.com/linux-photo-management-software/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29
|
||||
via: http://itsfoss.com/linux-photo-management-software/
|
||||
|
||||
作者:[Munif Tanjim][a]
|
||||
译者:[sarishinohara](https://github.com/sarishinohara)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,159 @@
|
||||
在 Ubuntu Server 16.04 LTS 上安装 LAMP
|
||||
=========================================================
|
||||
|
||||
LAMP 方案是一系列自由和开源软件的集合,包含了 **Linux**、Web 服务器 (**Apache**)、 数据库服务器 (**MySQL / MariaDB**) 和 **PHP** (脚本语言)。LAMP 是那些需要安装和构建动态网页应用的基础平台,比如WordPress、Joomla、OpenCart 和 Drupal。
|
||||
|
||||
在这篇文章中,我将描述如何在 Ubuntu Server 16.04 LTS 上安装 LAMP,众所周知 Ubuntu 是一个基于 Linux 的操作系统,因此它构成了 LAMP 的第一个部分,在接下来的操作中,我将默认你已经安装了 Ubuntu Server 16.04。
|
||||
|
||||
### Apache2 web 服务器的安装 :
|
||||
|
||||
在 Ubuntu linux 中,web 服务器是 Apache2,我们可以利用下面的命令来安装它:
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo apt update
|
||||
linuxtechi@ubuntu:~$ sudo apt install apache2 -y
|
||||
```
|
||||
|
||||
当安装 Apache2 包之后,Apache2 相关的服务是启用的,并在重启后自动运行。在某些情况下,如果你的 Apache2 服务并没有自动运行和启用,你可以利用如下命令来启动和启用它。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo systemctl start apache2.service
|
||||
linuxtechi@ubuntu:~$ sudo systemctl enable apache2.service
|
||||
linuxtechi@ubuntu:~$ sudo systemctl status apache2.service
|
||||
```
|
||||
|
||||
如果你开启了 Ubuntu 的防火墙(ufw),那么你可以使用如下的命令来解除 web 服务器的端口(80和443)限制
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo ufw status
|
||||
Status: active
|
||||
linuxtechi@ubuntu:~$ sudo ufw allow in 'Apache Full'
|
||||
Rule added
|
||||
Rule added (v6)
|
||||
linuxtechi@ubuntu:~$
|
||||
```
|
||||
|
||||
### 现在开始访问你的 web 服务器 :
|
||||
|
||||
打开浏览器并输入服务器的IP地址或者主机名(http://IP\_Address\_OR\_Host\_Name),在我的例子中我的服务器 IP是‘192.168.1.13’
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/Apache2-Ubuntu-server-16.04-1024x955.jpg)
|
||||
|
||||
### 数据库服务器的安装 (MySQL Server 5.7) :
|
||||
|
||||
MySQL 和 MariaDB 都是 Ubuntu 16.04 中的数据库服务器。 MySQL Server 和 MariaDB Server的安装包都可以在Ubuntu 的默认软件源中找到,我们可以选择其中的一个来安装。通过下面的命令来在终端中安装mysql服务器。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo apt install mysql-server mysql-client
|
||||
```
|
||||
|
||||
在安装过程中,它会要求你设置 mysql 服务器 root 帐户的密码。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/Enter-root-password-mysql-server-ubuntu-16-04.jpg)
|
||||
|
||||
确认 root 帐户的密码,并点击确定。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/confirm-root-password-mysql-server-ubuntu-16-04.jpg)
|
||||
|
||||
MySQL 服务器的安装到此已经结束了, MySQL 服务会自动启动并启用。我们可以通过如下的命令来校验 MySQL 服务的状态。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo systemctl status mysql.service
|
||||
```
|
||||
|
||||
### MariaDB Server的安装 :
|
||||
|
||||
在终端中使用如下的命令来安装 Mariadb 10.0 服务器。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo apt install mariadb-server
|
||||
```
|
||||
|
||||
运行如下的命令来设置 MariaDB root 帐户的密码,还可以用来关闭某些选项,比如关闭远程登录功能。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo mysql_secure_installation
|
||||
```
|
||||
|
||||
### PHP 脚本语言的安装:
|
||||
|
||||
PHP 7 已经存在于 Ubuntu 的软件源中了,在终端中执行如下的命令来安装 PHP 7:
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo apt install php7.0-mysql php7.0-curl php7.0-json php7.0-cgi php7.0 libapache2-mod-php7.0
|
||||
```
|
||||
|
||||
创建一个简单的 php 页面,并且将它移动到 apache 的文档根目录下 (/var/ww/html)
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ vi samplepage.php
|
||||
<?php
|
||||
phpinfo();
|
||||
?>
|
||||
```
|
||||
|
||||
在 vi 中编辑之后,保存并退出该文件。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo mv samplepage.php /var/www/html/
|
||||
```
|
||||
|
||||
现在你可以从 web 浏览器中访问这个页面, 输入 : “http://<Server\_IP>/samplepage.php” ,你可以看到如下页面。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/Sample-PHP-Page-Ubuntu-Server-16-04.jpg)
|
||||
|
||||
以上的页面向我们展示了 PHP 已经完全安装成功了。
|
||||
|
||||
### phpMyAdmin 的安装:
|
||||
|
||||
phpMyAdmin 可以让我们通过它的 web 界面来执行所有与数据库管理和其他数据库操作相关的任务,这个安装包已经存在于 Ubuntu 的软件源中。
|
||||
|
||||
利用如下的命令来在 Ubuntu server 16.04 LTS 中安装 phpMyAdmin。
|
||||
|
||||
```
|
||||
linuxtechi@ubuntu:~$ sudo apt install php-mbstring php7.0-mbstring php-gettext
|
||||
linuxtechi@ubuntu:~$ sudo systemctl restart apache2.service
|
||||
linuxtechi@ubuntu:~$ sudo apt install phpmyadmin
|
||||
```
|
||||
|
||||
在以下的安装过程中,它会提示我们选择 phpMyAdmin 运行的目标服务器。
|
||||
|
||||
选择 Apache2 并点击确定。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/Web-Server-for-phpMyAdmin-Ubuntu-Server-16-04.jpg)
|
||||
|
||||
点击确定来配置 phpMyAdmin 管理的数据库。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/configure-database-for-phpmyadmin-ubuntu-server-16-04.jpg)
|
||||
|
||||
指定 phpMyAdmin 向数据库服务器注册时所用的密码。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/Select-Password-for-phpMyadmin-ubuntu-16-04-1024x433.jpg)
|
||||
|
||||
确认 phpMyAdmin 所需的密码,并点击确认。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/confirm-password-for-phpmyadmin-ubuntu-server-16-04.jpg)
|
||||
|
||||
现在可以开始尝试访问 phpMyAdmin,打开浏览器并输入 : “http://Server\_IP\_OR\_Host\_Name/phpmyadmin”
|
||||
|
||||
使用我们安装时设置的 root 帐户和密码。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/phpMyAdmin-Ubuntu-Server-16-04-1024x557.jpg)
|
||||
|
||||
当我们点击“Go”的时候,将会重定向到如下所示的 ‘phpMyAdmin’ web界面。
|
||||
|
||||
![](http://www.linuxtechi.com/wp-content/uploads/2016/05/phpMyAdmin-portal-overview-ubuntu-server-16-04-1024x557.jpg)
|
||||
|
||||
到现在,LAMP 方案已经被成功安装并可以使用了,欢迎分享你的反馈和评论。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linuxtechi.com/lamp-stack-installation-on-ubuntu-server-16-04/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
译者:[陆建波](https://github.com/lujianbo)
|
||||
校对:[Caroline](https://github.com/carolinewuyan)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.linuxtechi.com/author/pradeep/
|
@ -1,12 +1,11 @@
|
||||
Linux中的scp命令
|
||||
在 Linux 下使用 scp 命令
|
||||
=======================
|
||||
|
||||
![](https://www.unixmen.com/wp-content/uploads/2016/05/SCP-LOGO-1.jpg)
|
||||
|
||||
scp 是安全拷贝协议 (Secure Copy Protocol)的缩写,和众多 Linux/Unix 使用者所熟知的拷贝(cp)命令一样。scp 的使用方式类似于 cp 命令,cp 命令将一个文件或文件夹从本地操作系统的一个位置(源)拷贝到目标位置(目的),而 scp 用来将文件或文件夹从网络上的一个主机拷贝到另一个主机当中去。
|
||||
|
||||
scp 意味着安全拷贝协议 (Secure Copy Protocol), 和众多Linux/Unix使用者所了解的拷贝(cp)命令一样. scp 的使用方式跟 cp命令是很相似的, cp命令将一个文件或文件夹从本地操作系统的一个位置拷贝到目标位置上,而scp用来将一个文件或者文件夹通过网络传输从一个主机拷贝到另一个主机当中去。
|
||||
|
||||
scp命令的使用方法如下所示,在这个例子中,我将一个叫 “imporimposetantfile”的文件从本机(10.10.16.147)拷贝到远程主机(10.0.0.6)中。在这个命令里,你也可以使用主机名字来替代IP地址。
|
||||
scp 命令的使用方法如下所示,在这个例子中,我将一个叫 “importantfile” 的文件从本机(10.10.16.147)拷贝到远程主机(10.0.0.6)中。在这个命令里,你也可以使用主机名字来替代IP地址。
|
||||
|
||||
```
|
||||
[root@localhost ~]# scp importantfile admin@10.0.0.6:/home/admin/
|
||||
@ -20,7 +19,7 @@ importantfile 100% 0 0.0KB/s 00:00
|
||||
[root@localhost ~]#
|
||||
```
|
||||
|
||||
同样的,如果你想从一个远程主机中获取文件,你可以利用如下的scp命令。
|
||||
类似的,如果你想从一个远程主机中取得文件,你可以利用如下的 scp 命令。
|
||||
|
||||
```
|
||||
[root@localhost ~]# scp root@10.10.16.137:/root/importantfile /home/admin/
|
||||
@ -33,50 +32,39 @@ importantfile 100% 0 0.0KB/s 00:00
|
||||
[root@localhost ~]#
|
||||
```
|
||||
|
||||
你同样可以像cp命令一样,在scp命令中使用不同的选项,scp的man文件详细地阐述了不同选项的用法和优点。
|
||||
你也可以像 cp 命令一样,在 scp 命令中使用不同的选项,scp 的 man 帮助详细地阐述了不同选项的用法和用处。
|
||||
|
||||
**简单输出.**
|
||||
**示例输出**
|
||||
|
||||
![](https://www.unixmen.com/wp-content/uploads/2016/05/scp.jpg)
|
||||
|
||||
```
|
||||
|
||||
scp 可选参数如下所示:
|
||||
|
||||
-B 采取批量模式 (prevents asking for passwords or passphrases).
|
||||
|
||||
-C 允许压缩. 通过指明-C来开启压缩模式.
|
||||
|
||||
-B 采取批量模式(避免询问密码或口令)
|
||||
-C 启用压缩。通过指明 -C 参数来开启压缩模式。
|
||||
-c 加密方式
|
||||
选择在传输过程中用来加密的加密方式
|
||||
这个选项会被直接传递到ssh(1).
|
||||
|
||||
选择在传输过程中用来加密的加密方式 这个选项会被直接传递到 ssh(1)。
|
||||
-F ssh 配置
|
||||
为ssh指定一个用来替代默认配置的文件.
|
||||
这个选项会被直接传递到ssh(1).
|
||||
|
||||
给 ssh 指定一个用来替代默认配置的配置文件。这个选项会被直接传递到 ssh(1)。
|
||||
-l 限速
|
||||
限制命令使用的带宽, 默认单位是 Kbit/s.
|
||||
|
||||
限制命令使用的带宽,默认单位是 Kbit/s。
|
||||
-P 端口
|
||||
指定需要的连接的远程主机的端口.
|
||||
注意,这个选项使用的是一个大写的"P", 因为小写的 -p 已经用来保留目标文件的时间和模式相关信息。
|
||||
指定需要的连接的远程主机的端口。
|
||||
注意,这个选项使用的是一个大写的“P”,因为小写的“-p”已经用来保留目标文件的时间和模式相关信息。(LCTT 译注:ssh 命令中使用小写的“-p”来指定目标端口。)
|
||||
-p 保留文件原来的修改时间,访问时间以及权限模式。
|
||||
-q 静默模式:不显示来自 ssh(1) 命令的进度信息,警告和诊断信息。
|
||||
-r 递归拷贝整个目录。
|
||||
注意,scp 命令在树形遍历的时候同样会跟随符号连接,复制所连接的文件。
|
||||
-v 详细模式。scp 和 ssh(1) 将会打印出处理过程中的调试信息。这可以帮助你调试连接、认证和配置方面的问题。
|
||||
|
||||
-p 保留目标文件的修改时间,访问时间以及权限模式.
|
||||
**详细模式**
|
||||
|
||||
-q 静默模式: 不显示来自ssh(1)命令的进度信息,警告和诊断信息.
|
||||
|
||||
-r 递归拷贝整个目录.
|
||||
注意,scp命令在树形遍历的时候同样会对符号连接进行相同的处理。
|
||||
|
||||
-v 详细模式.scp和ssh(1)将会打印出处理过程中的调试信息.当你要调试连接,认证和配置问题的时候这将会帮助到你。
|
||||
|
||||
```
|
||||
|
||||
利用scp命令的-v选项,你可以获得认证,调试相关的处理信息.
|
||||
利用 scp 命令的 -v 选项,你可以得到认证、调试等的相关细节信息。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-v.jpg)
|
||||
|
||||
当我们使用-v选项的时候,一个简单的输出如下所示
|
||||
当我们使用 -v 选项的时候,一个简单的输出如下所示:
|
||||
|
||||
```
|
||||
[root@localhost ~]# scp -v abc.txt admin@10.0.0.6:/home/admin
|
||||
@ -115,22 +103,23 @@ debug1: Exit status 0
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-with-r.jpg)
|
||||
|
||||
静默模式:
|
||||
**静默模式**
|
||||
|
||||
如果你想要关闭进度信息以及警告和诊断信息,你可以通过使用scp命令中的-q选项.
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-with-q.jpg)
|
||||
|
||||
上一次我们仅仅使用-r参数,它显示了逐个文件的信息,但这一次当我们使用了-q参数,它就不显示进度信息.
|
||||
上一次我们仅仅使用 -r 参数,它显示了逐个文件的信息,但这一次当我们使用了 -q 参数,它就不显示进度信息。
|
||||
|
||||
利用scp的-p选项来保留目标文件的更新时间,访问时间和权限模式.
|
||||
利用 scp 的 -p 选项来保留目标文件的更新时间,访问时间和权限模式。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-with-p.jpg)
|
||||
|
||||
通过 -P 选项来指定远程主机的连接端口。
|
||||
scp使用ssh命令来在两个主机之间传输文件,因为ssh使用的是22端口号,所以scp也使用相同的22端口号.
|
||||
**通过 -P 选项来指定远程主机的连接端口**
|
||||
|
||||
如果我们希望改变这个端口号,我们可以使用-P(大写的P,因为小写的p用来保存文件的访问时间等) 选项来指定所需的端口号
|
||||
scp 使用 ssh 命令来在两个主机之间传输文件,因为 ssh 默认使用的是22端口号,所以 scp 也使用相同的22端口号。
|
||||
|
||||
如果我们希望改变这个端口号,我们可以使用 -P(大写的 P,因为小写的 p 用来保持文件的访问时间等)选项来指定所需的端口号。
|
||||
|
||||
举个例子,如果我们想要使用2222端口号,我们可以使用如下的命令
|
||||
|
||||
@ -138,33 +127,33 @@ scp使用ssh命令来在两个主机之间传输文件,因为ssh使用的是22
|
||||
[root@localhost ~]# scp -P 2222 abcd1 root@10.10.16.137:/root/
|
||||
```
|
||||
|
||||
**限制命令使用的带宽, 指定的单位是 Kbit/s**
|
||||
**限制命令使用的带宽,指定的单位是 Kbit/s**
|
||||
|
||||
如下所示,我们可以使用-l参数来指定scp命令所使用的带宽,在此我们将速度限制为512kbit/s
|
||||
如下所示,我们可以使用 -l 参数来指定 scp 命令所使用的带宽,在此我们将速度限制为512kbit/s。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-with-l.jpg)
|
||||
|
||||
**开启压缩**
|
||||
|
||||
如下所示,我们可以通过开启scp命令的压缩模式来节省传输过程中的带宽和时间
|
||||
如下所示,我们可以通过开启 scp 命令的压缩模式来节省传输过程中的带宽和时间。
|
||||
|
||||
![](https://www.unixmen.com/wp-content/uploads/2016/05/scp-with-C.jpg)
|
||||
|
||||
**选择加密数据的加密方式**
|
||||
|
||||
scp默认使用 AES-128的加密方式,如果我们想要改变这个加密方式,可以通过-c(小写的c) 参数来指定其他的加密方式
|
||||
scp 默认使用 AES-128 的加密方式,如果我们想要改变这个加密方式,可以通过 -c(小写的 c) 参数来指定其他的加密方式。
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/scp-with-cipher.jpg)
|
||||
|
||||
现在你可以利用scp(Secure copy)命令在你所属网络中的两个结点之间安全地拷贝文件了.
|
||||
现在你可以利用 scp(Secure copy)命令在你所属网络中的两个节点之间安全地拷贝文件了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.unixmen.com/scp-command-linuxunix/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+unixmenhowtos+%28Unixmen+Howtos+%26+Tutorials%29
|
||||
via: https://www.unixmen.com/scp-command-linuxunix/
|
||||
|
||||
作者:[Naga Ramesh][a]
|
||||
译者:[lujianbo](https://github.com/lujianbo)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,212 @@
|
||||
如何在 Linux 及 Unix 系统中添加定时任务
|
||||
======================================
|
||||
|
||||
![](https://www.unixmen.com/wp-content/uploads/2016/05/HOW-TO-ADD-CRON-JOBS-IN-LINUX-AND-UNIX-696x334.png)
|
||||
|
||||
### 导言
|
||||
|
||||
![](http://www.unixmen.com/wp-content/uploads/2016/05/cronjob.gif)
|
||||
|
||||
定时任务 (cron job) 被用于安排那些需要被周期性执行的命令。利用它,你可以配置某些命令或者脚本,让它们在某个设定的时间周期性地运行。`cron` 是 Linux 或者类 Unix 系统中最为实用的工具之一。cron 服务(守护进程)在系统后台运行,并且会持续地检查 `/etc/crontab` 文件和 `/etc/cron.*/ `目录。它同样也会检查 `/var/spool/cron/` 目录。
|
||||
|
||||
### crontab 命令
|
||||
|
||||
`crontab` 是用来安装、卸载或者列出定时任务列表的命令。cron 配置文件则用于驱动 `Vixie Cron` 的 [cron(8)][1] 守护进程。每个用户都可以拥有自己的 crontab 文件,虽然这些文件都位于 `/var/spool/cron/crontabs` 目录中,但并不意味着你可以直接编辑它们。你需要通过 `crontab` 命令来编辑或者配置你自己的定时任务。
|
||||
|
||||
### 定时配置文件的类型
|
||||
|
||||
配置文件分为以下不同的类型:
|
||||
|
||||
- **UNIX 或 Linux 系统的 crontab** : 此类型通常由那些需要 root 或类似权限的系统服务和重要任务使用。第六个字段(见下方的字段介绍)为用户名,用来指定此命令以哪个用户身份来执行。如此一来,系统的 `crontab` 就能够以任意用户的身份来执行操作。
|
||||
|
||||
- **用户的 crontab**: 用户可以使用 `crontab` 命令来安装属于他们自己的定时任务。 第六个字段为需要运行的命令, 所有的命令都会以创建该 crontab 任务的用户的身份运行。
|
||||
|
||||
**注意**: 这种问答形式的 `Cron` 实现由 Paul Vixie 所编写,并且被包含在许多 [Linux][2] 发行版本和类 Unix 系统(如广受欢迎的第四版 BSD)中。它的语法被各种 crond 的实现所[兼容][3]。
|
||||
|
||||
那么我该如何安装、创建或者编辑我自己的定时任务呢?
|
||||
|
||||
要编辑你的 crontab 文件,需要在 Linux 或 Unix 的 shell 提示符后键入以下命令:
|
||||
|
||||
```
|
||||
$ crontab -e
|
||||
```
|
||||
|
||||
`crontab` 语法(字段介绍)
|
||||
|
||||
语法为:
|
||||
|
||||
```
|
||||
1 2 3 4 5 /path/to/command arg1 arg2
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```
|
||||
1 2 3 4 5 /root/ntp_sync.sh
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- 第1个字段:分钟 (0-59)
|
||||
- 第2个字段:小时 (0-23)
|
||||
- 第3个字段:日期 (0-31)
|
||||
- 第4个字段:月份 (0-12 [12 代表 December])
|
||||
- 第5个字段:一周当中的某天 (0-7 [7 或 0 代表星期天])
|
||||
- /path/to/command - 计划执行的脚本或命令的名称
|
||||
|
||||
便于记忆的格式:
|
||||
|
||||
```
|
||||
* * * * * 要执行的命令
|
||||
----------------
|
||||
| | | | |
|
||||
| | | | ---- 周当中的某天 (0 - 7) (周日为 0 或 7)
|
||||
| | | ------ 月份 (1 - 12)
|
||||
| | -------- 一月当中的某天 (1 - 31)
|
||||
| ---------- 小时 (0 - 23)
|
||||
------------ 分钟 (0 - 59)
|
||||
```
|
||||
|
||||
简单的 `crontab` 示例:
|
||||
|
||||
````
|
||||
## 每隔 5 分钟运行一次 backupscript 脚本 ##
|
||||
*/5 * * * * /root/backupscript.sh
|
||||
|
||||
## 每天的凌晨 1 点运行 backupscript 脚本 ##
|
||||
|
||||
0 1 * * * /root/backupscript.sh
|
||||
|
||||
## 每月的第一个凌晨 3:15 运行 backupscript 脚本 ##
|
||||
|
||||
15 3 1 * * /root/backupscript.sh
|
||||
```
|
||||
|
||||
### 如何使用操作符
|
||||
|
||||
操作符允许你为一个字段指定多个值,这里有三个操作符可供使用:
|
||||
|
||||
- **星号 (*)** : 此操作符为字段指定所有可用的值。举个例子,在小时字段中,一个星号等同于每个小时;在月份字段中,一个星号则等同于每月。
|
||||
|
||||
- **逗号 (,)** : 这个操作符指定了一个包含多个值的列表,例如:`1,5,10,15,20,25`.
|
||||
|
||||
- **横杠 (-)** : 此操作符指定了一个值的范围,例如:`5-15` ,等同于使用逗号操作符键入的 `5,6,7,8,9,...,13,14,15`。
|
||||
|
||||
- **分隔符 (/)** : 此操作符指定了一个步进值,例如: `0-23/` 可以用于小时字段来指定某个命令每小时被执行一次。步进值也可以跟在星号操作符后边,如果你希望命令行每 2 小时执行一次,则可以使用 `*/2`。
|
||||
|
||||
### 如何禁用邮件输出
|
||||
|
||||
默认情况下,某个命令或者脚本的输出内容(如果有的话)会发送到你的本地邮箱账户中。若想停止收到 `crontab` 发送的邮件,需要添加 `>/dev/null 2>&1` 这段内容到执行的命令的后面,例如:
|
||||
|
||||
```
|
||||
0 3 * * * /root/backup.sh >/dev/null 2>&1
|
||||
```
|
||||
|
||||
如果想将输出内容发送到特定的邮件账户中,比如说 vivek@nixcraft.in 这个邮箱, 则你需要像下面这样定义一个 MAILTO 变量:
|
||||
|
||||
```
|
||||
MAILTO="vivek@nixcraft.in"
|
||||
0 3 * * * /root/backup.sh >/dev/null 2>&1
|
||||
```
|
||||
|
||||
访问 “[禁用 Crontab 命令的邮件提示](http://www.cyberciti.biz/faq/disable-the-mail-alert-by-crontab-command/)” 查看更多信息。
|
||||
|
||||
|
||||
### 任务:列出你所有的定时任务
|
||||
|
||||
键入以下命令:
|
||||
|
||||
```
|
||||
# crontab -l
|
||||
# crontab -u username -l
|
||||
```
|
||||
|
||||
要删除所有的定时任务,可以使用如下命令:
|
||||
|
||||
```
|
||||
# 删除当前定时任务 #
|
||||
crontab -r
|
||||
```
|
||||
|
||||
```
|
||||
## 删除某用户名下的定时任务,此命令需以 root 用户身份执行 ##
|
||||
crontab -r -u username
|
||||
```
|
||||
|
||||
### 使用特殊字符串来节省时间
|
||||
|
||||
你可以使用以下 8 个特殊字符串中的其中一个替代头五个字段,这样不但可以节省你的时间,还可以提高可读性。
|
||||
|
||||
特殊字符 |含义
|
||||
|:-- |:--
|
||||
@reboot | 在每次启动时运行一次
|
||||
@yearly | 每年运行一次,等同于 “0 0 1 1 *”.
|
||||
@annually | (同 @yearly)
|
||||
@monthly | 每月运行一次, 等同于 “0 0 1 * *”.
|
||||
@weekly | 每周运行一次, 等同于 “0 0 * * 0”.
|
||||
@daily | 每天运行一次, 等同于 “0 0 * * *”.
|
||||
@midnight | (同 @daily)
|
||||
@hourly | 每小时运行一次, 等同于 “0 * * * *”.
|
||||
|
||||
示例:
|
||||
|
||||
#### 每小时运行一次 ntpdate 命令 ####
|
||||
|
||||
```
|
||||
@hourly /path/to/ntpdate
|
||||
```
|
||||
|
||||
### 关于 `/etc/crontab` 文件和 `/etc/cron.d/*` 目录的更多内容
|
||||
|
||||
** /etc/crontab ** 是系统的 crontab 文件。通常只被 root 用户或守护进程用于配置系统级别的任务。每个独立的用户必须像上面介绍的那样使用 `crontab` 命令来安装和编辑自己的任务。`/var/spool/cron/` 或者 `/var/cron/tabs/` 目录存放了个人用户的 crontab 文件,它必定会备份在用户的家目录当中。
|
||||
|
||||
###理解默认的 `/etc/crontab` 文件
|
||||
|
||||
典型的 `/etc/crontab` 文件内容是这样的:
|
||||
|
||||
```
|
||||
SHELL=/bin/bash
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
MAILTO=root
|
||||
HOME=/
|
||||
# run-parts
|
||||
01 * * * * root run-parts /etc/cron.hourly
|
||||
02 4 * * * root run-parts /etc/cron.daily
|
||||
22 4 * * 0 root run-parts /etc/cron.weekly
|
||||
42 4 1 * * root run-parts /etc/cron.monthly
|
||||
```
|
||||
|
||||
首先,环境变量必须被定义。如果 SHELL 行被忽略,cron 会使用默认的 sh shell。如果 PATH 变量被忽略,就没有默认的搜索路径,所有的文件都需要使用绝对路径来定位。如果 HOME 变量被忽略,cron 会使用调用者(用户)的家目录替代。
|
||||
|
||||
另外,cron 会读取 `/etc/cron.d/`目录中的文件。通常情况下,像 sa-update 或者 sysstat 这样的系统守护进程会将他们的定时任务存放在此处。作为 root 用户或者超级用户,你可以使用以下目录来配置你的定时任务。你可以直接将脚本放到这里。`run-parts`命令会通过 `/etc/crontab` 文件来运行位于某个目录中的脚本或者程序。
|
||||
|
||||
目录 |描述
|
||||
|:-- |:--
|
||||
/etc/cron.d/ | 将所有的脚本文件放在此处,并从 /etc/crontab 文件中调用它们。
|
||||
/etc/cron.daily/ | 运行需要 每天 运行一次的脚本
|
||||
/etc/cron.hourly/ | 运行需要 每小时 运行一次的脚本
|
||||
/etc/cron.monthly/ | 运行需要 每月 运行一次的脚本
|
||||
/etc/cron.weekly/ | 运行需要 每周 运行一次的脚本
|
||||
|
||||
### 备份定时任务
|
||||
|
||||
```
|
||||
# crontab -l > /path/to/file
|
||||
|
||||
# crontab -u user -l > /path/to/file
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.unixmen.com/add-cron-jobs-linux-unix/
|
||||
|
||||
作者:[Duy NguyenViet][a]
|
||||
译者:[mr-ping](https://github.com/mr-ping)
|
||||
校对:[FSSlc](https://github.com/FSSlc)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.unixmen.com/author/duynv/
|
||||
[1]: http://www.manpager.com/linux/man8/cron.8.html
|
||||
[2]: http://www.linuxsecrets.com/
|
||||
[3]: http://www.linuxsecrets.com/linux-hardware/
|
@ -14,7 +14,8 @@
|
||||
基于这个信任分,一个需要登录认证的应用可以验证你确实可以授权登录,从而不会提示需要密码。
|
||||
|
||||
![](http://www.iwillfolo.com/wordpress/wp-content/uploads/2016/05/Abacus-to-Trust-API.jpg)
|
||||
>Abacus 到 Trust API
|
||||
|
||||
*Abacus 到 Trust API*
|
||||
|
||||
### 需要思考的地方
|
||||
|
||||
@ -31,7 +32,7 @@ via: http://www.iwillfolo.com/will-google-replace-passwords-with-a-new-trust-bas
|
||||
|
||||
作者:[iWillFolo][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,102 @@
|
||||
vlock – 一个锁定 Linux 用户虚拟控制台或终端的好方法
|
||||
=======================================================================
|
||||
|
||||
虚拟控制台是 Linux 上非常重要的功能,它们给系统用户提供了 shell 提示符,以保证用户在登录和远程登录一个未安装图形界面的系统时仍能使用。
|
||||
|
||||
一个用户可以同时操作多个虚拟控制台会话,只需在虚拟控制台间来回切换即可。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/vlock-Lock-User-Terminal-in-Linux.png)
|
||||
|
||||
*用 vlock 锁定 Linux 用户控制台或终端*
|
||||
|
||||
这篇使用指导旨在教会大家如何使用 vlock 来锁定用户虚拟控制台和终端。
|
||||
|
||||
### vlock 是什么?
|
||||
|
||||
vlock 是一个用于锁定一个或多个用户虚拟控制台用户会话的工具。在多用户系统中 vlock 扮演着重要的角色,它让用户可以在锁住自己会话的同时不影响其他用户通过其他虚拟控制台操作同一个系统。必要时,还可以锁定所有的控制台,同时禁止在虚拟控制台间切换。
|
||||
|
||||
vlock 的主要功能面向控制台会话方面,同时也支持非控制台会话的锁定,但该功能的测试还不完全。
|
||||
|
||||
### 在 Linux 上安装 vlock
|
||||
|
||||
根据你的 Linux 系统选择 vlock 安装指令:
|
||||
|
||||
```
|
||||
# yum install vlock [On RHEL / CentOS / Fedora]
|
||||
$ sudo apt-get install vlock [On Ubuntu / Debian / Mint]
|
||||
```
|
||||
|
||||
### 在 Linux 上使用 vlock
|
||||
|
||||
vlock 操作选项的常规语法:
|
||||
|
||||
```
|
||||
# vlock option
|
||||
# vlock option plugin
|
||||
# vlock option -t <timeout> plugin
|
||||
```
|
||||
|
||||
#### vlock 常用选项及用法:
|
||||
|
||||
1、 锁定用户的当前虚拟控制台或终端会话,如下:
|
||||
|
||||
```
|
||||
# vlock --current
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Lock-User-Terminal-Session-in-Linux.png)
|
||||
|
||||
*锁定 Linux 用户终端会话*
|
||||
|
||||
选项 -c 或 --current,用于锁定当前的会话,该参数为运行 vlock 时的默认行为。
|
||||
|
||||
2、 锁定所有你的虚拟控制台会话,并禁用虚拟控制台间切换,命令如下:
|
||||
|
||||
```
|
||||
# vlock --all
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Lock-All-Linux-Terminal-Sessions.png)
|
||||
|
||||
*锁定所有 Linux 终端会话*
|
||||
|
||||
选项 -a 或 --all,用于锁定所有用户的控制台会话,并禁用虚拟控制台间切换。
|
||||
|
||||
其他的选项只有在编译 vlock 时编入了相关插件支持和引用后,才能发挥作用:
|
||||
|
||||
3、 选项 -n 或 --new,调用时后,会在锁定用户的控制台会话前切换到一个新的虚拟控制台。
|
||||
|
||||
```
|
||||
# vlock --new
|
||||
```
|
||||
|
||||
4、 选项 -s 或 --disable-sysrq,在禁用虚拟控制台的同时禁用 SysRq 功能,只有在与 -a 或 --all 同时使用时才起作用。
|
||||
|
||||
```
|
||||
# vlock -sa
|
||||
```
|
||||
|
||||
5、 选项 -t 或 --timeout <time_in_seconds>,用以设定屏幕保护插件的 timeout 值。
|
||||
|
||||
```
|
||||
# vlock --timeout 5
|
||||
```
|
||||
|
||||
你可以使用 `-h` 或 `--help` 和 `-v` 或 `--version` 分别查看帮助消息和版本信息。
|
||||
|
||||
我们的介绍就到这了,提示一点,你可以将 vlock 的 `~/.vlockrc` 文件包含到系统启动中,并参考入门手册[添加环境变量][1],特别是 Debian 系的用户。
|
||||
|
||||
想要找到更多或是补充一些这里没有提及的信息,可以直接在写在下方评论区。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/vlock-lock-user-virtual-console-terminal-linux/
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[martin2011qi](https://github.com/martin2011qi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: http://www.tecmint.com/set-path-variable-linux-permanently/
|
@ -0,0 +1,98 @@
|
||||
用 Docker 创建 serverless 应用
|
||||
======================================
|
||||
|
||||
当今世界会时不时地出现一波波科技浪潮,将以前的技术拍死在海滩上。针对 serverless 应用的概念我们已经谈了很多,它是指将你的应用程序按功能来部署,这些功能在被用到时才会启动。你不用费心去管理服务器和程序规模,因为它们会在需要的时候在一个集群中启动并运行。
|
||||
|
||||
但是 serverless 并不意味着没有 Docker 什么事儿,事实上 Docker 就是 serverless 的。你可以使用 Docker 来容器化这些功能,然后在 Swarm 中按需求来运行它们。serverless 是一项构建分布式应用的技术,而 Docker 是它们完美的构建平台。
|
||||
|
||||
### 从 servers 到 serverless
|
||||
|
||||
那如何才能写一个 serverless 应用呢?来看一下我们的例子,[5个服务组成的投票系统][1]:
|
||||
|
||||
![](https://blog.docker.com/wp-content/uploads/Picture1.png)
|
||||
|
||||
投票系统由下面5个服务组成:
|
||||
|
||||
- 两个 web 前端
|
||||
- 一个后台处理投票的进程
|
||||
- 一个计票的消息队列
|
||||
- 一个数据库
|
||||
|
||||
后台处理投票的进程很容易转换成 serverless 构架,我们可以使用以下代码来实现:
|
||||
|
||||
```
|
||||
import dockerrun
|
||||
client = dockerrun.from_env()
|
||||
client.run("bfirsh/serverless-record-vote-task", [voter_id, vote], detach=True)
|
||||
```
|
||||
|
||||
这个投票处理进程和消息队列可以用运行在 Swarm 上的 Docker 容器来代替,并实现按需自动部署。
|
||||
|
||||
我们也可以用容器替换 web 前端,使用一个轻量级 HTTP 服务器来触发容器响应一个 HTTP 请求。Docker 容器代替长期运行的 HTTP 服务器来挑起响应请求的重担,这些容器可以自动扩容来支撑更大访问量。
|
||||
|
||||
新的架构就像这样:
|
||||
|
||||
![](https://blog.docker.com/wp-content/uploads/Picture2.png)
|
||||
|
||||
红色框内是持续运行的服务,绿色框内是按需启动的容器。这个架构里需要你来管理的长期运行服务更少,并且可以自动扩容(最大容量由你的 Swarm 决定)。
|
||||
|
||||
### 我们可以做点什么?
|
||||
|
||||
你可以在你的应用中使用3种技术:
|
||||
|
||||
1. 在 Docker 容器中按需运行代码。
|
||||
2. 使用 Swarm 来部署集群。
|
||||
3. 通过使用 Docker API 套接字在容器中运行容器。
|
||||
|
||||
结合这3种技术,你可以有很多方法搭建你的应用架构。用这种方法来部署后台环境真是非常有效,而在另一些场景,也可以这么玩,比如说:
|
||||
|
||||
- 由于存在延时,使用容器实现面向用户的 HTTP 请求可能不是很合适,但你可以写一个负载均衡器,使用 Swarm 来对自己的 web 前端进行自动扩容。
|
||||
- 实现一个 MongoDB 容器,可以自检 Swarm 并且启动正确的分片和副本(LCTT 译注:分片技术为大规模并行检索提供支持,副本技术则是为数据提供冗余)。
|
||||
|
||||
### 下一步怎么做
|
||||
|
||||
我们提供了这些前卫的工具和概念来构建应用,并没有深入发掘它们的功能。我们的架构里还是存在长期运行的服务,将来我们需要使用 Swarm 来把所有服务都用按需扩容的方式实现。
|
||||
|
||||
希望本文能在你搭建架构时给你一些启发,但我们还是需要你的帮助。我们提供了所有的基本工具,但它们还不是很完善,我们需要更多更好的工具、库、应用案例、文档以及其他资料。
|
||||
|
||||
[我们在这里发布了工具、库和文档][3]。如果想了解更多,请贡献给我们一些你知道的资源,以便我们能够完善这篇文章。
|
||||
|
||||
玩得愉快。
|
||||
|
||||
### 更多关于 Docker 的资料
|
||||
|
||||
- New to Docker? Try our 10 min [online tutorial][4]
|
||||
- Share images, automate builds, and more with [a free Docker Hub account][5]
|
||||
- Read the Docker [1.12 Release Notes][6]
|
||||
- Subscribe to [Docker Weekly][7]
|
||||
- Sign up for upcoming [Docker Online Meetups][8]
|
||||
- Attend upcoming [Docker Meetups][9]
|
||||
- Watch [DockerCon EU 2015 videos][10]
|
||||
- Start [contributing to Docker][11]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://blog.docker.com/2016/06/building-serverless-apps-with-docker/
|
||||
|
||||
作者:[Ben Firshman][a]
|
||||
译者:[bazz2](https://github.com/bazz2)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://blog.docker.com/author/bfirshman/
|
||||
|
||||
[1]: https://github.com/docker/example-voting-app
|
||||
[3]: https://github.com/bfirsh/serverless-docker
|
||||
[4]: https://docs.docker.com/engine/understanding-docker/
|
||||
[5]: https://hub.docker.com/
|
||||
[6]: https://docs.docker.com/release-notes/
|
||||
[7]: https://www.docker.com/subscribe_newsletter/
|
||||
[8]: http://www.meetup.com/Docker-Online-Meetup/
|
||||
[9]: https://www.docker.com/community/meetup-groups
|
||||
[10]: https://www.youtube.com/playlist?list=PLkA60AVN3hh87OoVra6MHf2L4UR9xwJkv
|
||||
[11]: https://docs.docker.com/contributing/contributing/
|
||||
|
||||
|
||||
|
@ -0,0 +1,80 @@
|
||||
Linus Torvalds 是一个糟糕的老板吗?
|
||||
================================================================================
|
||||
|
||||
![linus torvalds](http://images.techhive.com/images/article/2015/08/linus_torvalds-100600260-primary.idge.jpg)
|
||||
|
||||
*1999 年 8 月 10 日,加利福尼亚州圣何塞市,在 LinuxWorld Show 上 Linus Torvalds 在一个坐满 Linux 爱好者的礼堂中发表了一篇演讲。图片来自:James Niccolai*
|
||||
|
||||
**这取决于所处的领域。在软件开发的世界中,他也是个普通人。问题是,这种情况是否应该继续下去?**
|
||||
|
||||
Linus Torvalds 是 Linux 的发明者,我认识他超过 20 年了。我们不是密友,但是我们欣赏彼此。
|
||||
|
||||
最近,因为 Linus Torvalds 的管理风格,他正遭到严厉的炮轰。Linus 无法忍受胡来的人。“代码的质量有多好?”是他在 Linux 内核的开发过程中评判人的一种方式。
|
||||
|
||||
没有什么比这个更重要了。正如 Linus 今年(2015年)早些时候在 Linux.conf.au 会议上说的那样,“我不是一个友好的人,我也不在意你。对我重要的是『[我所关心的技术和内核][1]』。”
|
||||
|
||||
现在我也可以和这种只关心技术的人打交道了。如果你不能,你应当避免参加 Linux 内核会议,因为在那里你会遇到许多有这种精英思想的人。这不代表我认为在 Linux 领域所有东西都是极好的,并且不应该受到其他影响而带来改变。我能够和一个精英待在一起;而在一个男性做主导的大城堡中遇到的问题是,女性经常受到蔑视和无礼的对待。
|
||||
|
||||
这就是我看到的最近关于 Linus 管理风格所引发争论的原因 -- 或者更准确的说,他对于个人管理方面是完全冷漠的 -- 就像是在软件开发世界的标准操作流程一样。与此同时,我看到了揭示了这个事情需要改变的另外一个证据。
|
||||
|
||||
第一次是在 [Linux 4.3 发布][2]的时候出现的这个情况,Linus 使用 Linux 内核邮件列表来狠狠的数落了一个插入了一些网络方面的代码的开发者——这些代码很“烂”,“[生成了如此烂的代码][3]。这看起来太糟糕了,并且完全没有理由这样做。”他继续咆哮了半天。这里使用“烂”这个词,相对他早期使用的“愚蠢的”这个同义词来说还算好的。
|
||||
|
||||
但是,事情就是这样。Linus 是对的。我读了代码后,发现代码确实很烂,并且开发者只是为了用新的“overflow_usub()” 函数而用的。
|
||||
|
||||
现在,一些人把 Linus 的这种谩骂的行为看作他脾气不好而且恃强凌弱的证据。我见过一个完美主义者,在他的领域中,他无法忍受这种糟糕。
|
||||
|
||||
许多人告诉我,这不是一个专业的程序员应当有的行为。群众们,你曾经和最优秀的开发者一起工作过吗?据我所知道的,在 Apple,Microsoft,Oracle 这就是他们的行为。
|
||||
|
||||
我曾经听过 Steve Jobs 攻击一个开发者,就像要把他撕成碎片那样。我也被一个 Oracle 的高级开发者攻击一屋子的新开发者吓到过,就像食人鱼穿过一群金鱼那样。
|
||||
|
||||
在 Robert X. Cringely 关于 PC 崛起的经典书籍《[意外帝国(Accidental Empires)][5]》,中,他这样描述了微软的软件管理风格,比尔·盖茨像计算机系统一样管理他们,“比尔·盖茨的是最高等级,从他开始每一个等级依次递减,上级会向下级叫嚷,刺激他们,甚至羞辱他们。”
|
||||
|
||||
Linus 和所有大型的商业软件公司的领导人不同的是,Linus 说在这里所有的东西是向全世界公开的。而其他人是在自己的会议室中做东西的。我听有人说 Linus 在那种公司中可能会被开除。这是不可能的。他会处于他现在所处的地位,他在编程世界的最顶端。
|
||||
|
||||
但是,这里有另外一个不同。如果 Larry Ellison (Oracle 的首席执行官)向你发火,你就别想在这里干了。如果 Linus 向你发火,你会在邮件中收到他的责骂。这就是差别。
|
||||
|
||||
你知道的,Linus 不是任何人的老板。他完全没有雇佣和解聘的权利,他只是负责着有 10000 个贡献者的一个项目而已。他仅仅能做的就是从心理上伤害你。
|
||||
|
||||
这说明,在开源软件开发圈和商业软件开发圈中同时存在一个非常严重的问题。不管你是一个多么好的编程者,如果你是一个女性,你的这个身份就是对你不利的。
|
||||
|
||||
这种情况并没有在 Sarah Sharp 的身上有任何好转,她现在是一个 Intel 的开发者,以前是一个顶尖的 Linux 程序员。[在她博客上10月份的一个帖子中][4],她解释道:“我最终发现,我不能够再为 Linux 社区做出贡献了。因为在那里,我虽然能够得到技术上的尊重,却得不到个人的尊重……我不想专职于同那些有着轻微的性别歧视或开同性恋玩笑的人一起工作。”
|
||||
|
||||
谁会责怪她呢?我不会。很抱歉,我必须说,Linus 就像所有我见过的软件经理一样,是他造成了这种不利的工作环境。
|
||||
|
||||
他可能会说,确保 Linux 的贡献者都表现出专业精神和相互尊重不应该是他的工作。除了代码以外,他不关心任何其他事情。
|
||||
|
||||
就像 Sarah Sharp 写的那样:
|
||||
|
||||
|
||||
> 我对于 Linux 内核社区做出的技术努力表示最大尊重。他们在那维护一些最高标准的代码,以此来平衡并且发展一个项目。他们专注于优秀的技术,以及超过负荷的维护人员,他们有不同的文化背景和社会规范,这些意味着这些 Linux 内核维护者说话非常直率、粗鲁,或者为了完成他们的任务而不讲道理。顶尖的 Linux 内核开发者经常为了使别人改正行为而向他们大喊大叫。
|
||||
>
|
||||
> 这种事情发生在我身上,但它不是一种有效的沟通方式。
|
||||
>
|
||||
> 许多高级的 Linux 内核开发者支持那些技术上和人性上不讲道理的维护者的权利。即使他们自己是非常友好的人,他们不想看到 Linux 内核交流方式改变。
|
||||
|
||||
她是对的。
|
||||
|
||||
我和其他观察者不同的是,我不认为这个问题对于 Linux 或开源社区在任何方面有特殊之处。作为一个从事技术商业工作超过五年和有着 25 年技术工作经历的记者,我见多了这种不成熟的小孩子行为。
|
||||
|
||||
这不是 Linus 的错误。他不是一个经理,他是一个有想象力的技术领导者。看起来真正的问题是,在软件开发领域没有人能够用一种支持的语气来对待团队和社区。
|
||||
|
||||
展望未来,我希望像 Linux 基金会这样的公司和组织,能够找到一种方式去授权社区经理或其他经理来鼓励并且强制实施民主的行为。
|
||||
|
||||
非常遗憾的是,我们不能够在我们这种纯技术或纯商业的领导人中找到这种管理策略。它不存在于这些人的基因中。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.computerworld.com/article/3004387/it-management/how-bad-a-boss-is-linus-torvalds.html
|
||||
|
||||
作者:[Steven J. Vaughan-Nichols][a]
|
||||
译者:[FrankXinqi](https://github.com/FrankXinqi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.computerworld.com/author/Steven-J.-Vaughan_Nichols/
|
||||
[1]:http://www.computerworld.com/article/2874475/linus-torvalds-diversity-gaffe-brings-out-the-best-and-worst-of-the-open-source-world.html
|
||||
[2]:http://www.zdnet.com/article/linux-4-3-released-after-linus-torvalds-scraps-brain-damage-code/
|
||||
[3]:http://lkml.iu.edu/hypermail/linux/kernel/1510.3/02866.html
|
||||
[4]:http://sarah.thesharps.us/2015/10/05/closing-a-door/
|
||||
[5]:https://www.amazon.cn/Accidental-Empires-Cringely-Robert-X/dp/0887308554/479-5308016-9671450?ie=UTF8&qid=1447101469&ref_=sr_1_1&tag=geo-23
|
@ -0,0 +1,462 @@
|
||||
Securi-Pi:使用树莓派作为安全跳板
|
||||
================================================================================
|
||||
|
||||
像很多 LinuxJournal 的读者一样,我也过上了当今非常普遍的“科技游牧”生活,在网络之间,从一个接入点到另一个接入点,我们身处现实世界的不同地方却始终保持连接到互联网和日常使用的其它网络上。近来我发现越来越多的网络环境开始屏蔽对外的常用端口比如 SMTP(端口25),SSH(端口22)之类的。当你走进一家咖啡馆然后想 SSH 到你的一台服务器上做点事情的时候发现端口 22 被屏蔽了是一件很烦的事情。
|
||||
|
||||
不过,我到目前为止还没发现有什么网络环境会把 HTTPS 给墙了(端口443)。在稍微配置了一下家中的树莓派 2 之后,我成功地让自己通过接入树莓派的 443 端口充当跳板,从而让我在各种网络环境下都能连上想要的目标端口。简而言之,我把家中的树莓派设置成了一个 OpenVPN 的端点和 SSH 端点,同时也是一个 Apache 服务器,所有这些服务都监听在 443 端口上,以便可以限制我不想暴露的网络服务。
|
||||
|
||||
|
||||
### 备注
|
||||
|
||||
此解决方案能搞定大多数有限制的网络环境,但有些防火墙会对外部流量调用深度包检查(Deep packet inspection),它们时常能屏蔽掉用本篇文章里的方式传输的信息。不过我到目前为止还没在这样的防火墙后测试过。同时,尽管我使用了很多基于密码学的工具(OpenVPN,HTTPS,SSH),我并没有非常严格地审计过这套配置方案(LCTT 译注:作者的意思是指这套方案能帮你绕过端口限制,但不代表你的活动就是完全安全的)。有时候甚至 DNS 服务都会泄露你的信息,很可能在我没有考虑周到的角落里会有遗漏。我强烈不推荐把此跳板配置方案当作是万无一失的隐藏网络流量的办法,此配置只是希望能绕过一些端口限制连上网络,而不是做一些危险的事情。
|
||||
|
||||
### 起步
|
||||
|
||||
让我们先从你需要什么说起,我用的是树莓派 2,装载了最新版本的 Raspbian,不过这个配置也应该能在树莓派 Model B 上运行;512MB 的内存对我们来说绰绰有余了,虽然性能可能没有树莓派 2这么好,毕竟相比于四核心的树莓派 2, Model B 只有一颗单核心 CPU。我的树莓派放置在家里的防火墙和路由器的后面,所以我还能用这个树莓派作为跳板访问家里的其他电子设备。同时这也意味着我的流量在互联网上看起来仿佛来自我家的 ip 地址,所以这也算某种意义上保护了我的匿名性。如果你没有树莓派,或者不想从家里运行这个服务,那你完全可以把这个配置放在一台小型云服务器上(LCTT 译注:比如 IPS )。你只要确保服务器运行着基于 Debian 的 Linux 发行版即可,这份指南依然可用。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1002061/11913f1.jpg)
|
||||
|
||||
*图 1 树莓派,即将成为我们的加密网络端点*
|
||||
|
||||
|
||||
### 安装并配置 BIND
|
||||
|
||||
无论你是用树莓派还是一台服务器,当你成功启动之后你就可以安装 BIND 了,这是一个驱动了互联网相当一部分的域名服务软件。你将会把 BIND 仅仅作为缓存域名服务使用,而不用把它配置为用来处理来自互联网的域名请求。安装 BIND 会让你拥有一个可以被 OpenVPN 使用的 DNS 服务器。安装 BIND 十分简单,`apt-get` 就可以直接搞定:
|
||||
|
||||
```
|
||||
root@test:~# apt-get install bind9
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
The following extra packages will be installed:
|
||||
bind9utils
|
||||
Suggested packages:
|
||||
bind9-doc resolvconf ufw
|
||||
The following NEW packages will be installed:
|
||||
bind9 bind9utils
|
||||
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
|
||||
Need to get 490 kB of archives.
|
||||
After this operation, 1,128 kB of additional disk space will be used.
|
||||
Do you want to continue [Y/n]? y
|
||||
```
|
||||
|
||||
在我们把 BIND 作为缓存域名服务器之前,还有一些小细节需要配置。两个修改都在`/etc/bind/named.conf.options`里完成。首先你要取消注释掉 forwarders 这一节内容,同时你还要增加一个可以转发域名请求的目标服务器。作为例子我会用 Google 的 DNS 服务器(8.8.8.8)(LCTT 译注:国内的话需要找一个替代品);文件的 forwarders 节看上去大致是这样的:
|
||||
|
||||
|
||||
```
|
||||
forwarders {
|
||||
8.8.8.8;
|
||||
};
|
||||
```
|
||||
|
||||
第二点你需要做的更改是允许来自内网和本机的查询请求,直接把这一行加入配置文件的后面,记得放在最后一个`};`之前就可以了:
|
||||
|
||||
|
||||
```
|
||||
allow-query { 192.168.1.0/24; 127.0.0.0/16; };
|
||||
```
|
||||
|
||||
上面那行配置会允许此 DNS 服务器接收来自其所在的网络(在本例中,我的网络就在我的防火墙之后)和本机的请求。下一步,你需要重启一下 BIND 的服务:
|
||||
|
||||
```
|
||||
root@test:~# /etc/init.d/bind9 restart
|
||||
[....] Stopping domain name service...: bind9waiting for pid 13209 to die
|
||||
. ok
|
||||
[ ok ] Starting domain name service...: bind9.
|
||||
```
|
||||
|
||||
现在你可以测试一下 `nslookup` 来确保你的服务正常运行了:
|
||||
|
||||
|
||||
```
|
||||
root@test:~# nslookup
|
||||
> server localhost
|
||||
Default server: localhost
|
||||
Address: 127.0.0.1#53
|
||||
> www.google.com
|
||||
Server: localhost
|
||||
Address: 127.0.0.1#53
|
||||
|
||||
Non-authoritative answer:
|
||||
Name: www.google.com
|
||||
Address: 173.194.33.176
|
||||
Name: www.google.com
|
||||
Address: 173.194.33.177
|
||||
Name: www.google.com
|
||||
Address: 173.194.33.178
|
||||
Name: www.google.com
|
||||
Address: 173.194.33.179
|
||||
Name: www.google.com
|
||||
Address: 173.194.33.180
|
||||
```
|
||||
|
||||
完美!现在你的系统里已经有一个正常的域名服务在工作了,下一步我们来配置一下OpenVPN。
|
||||
|
||||
|
||||
### 安装并配置 OpenVPN
|
||||
|
||||
OpenVPN 是一个运用 SSL/TLS 作为密钥交换的开源 VPN 解决方案。同时它也非常便于在 Linux 环境下部署。配置 OpenVPN 可能有一点点难,不过其实你也不需要在默认的配置文件里做太多修改。首先你需要运行一下 `apt-get` 来安装 OpenVPN:
|
||||
|
||||
|
||||
```
|
||||
root@test:~# apt-get install openvpn
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
The following extra packages will be installed:
|
||||
liblzo2-2 libpkcs11-helper1
|
||||
Suggested packages:
|
||||
resolvconf
|
||||
The following NEW packages will be installed:
|
||||
liblzo2-2 libpkcs11-helper1 openvpn
|
||||
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
|
||||
Need to get 621 kB of archives.
|
||||
After this operation, 1,489 kB of additional disk space will be used.
|
||||
Do you want to continue [Y/n]? y
|
||||
```
|
||||
|
||||
现在 OpenVPN 已经安装好了,你需要去配置它了。OpenVPN 是基于 SSL 的,并且它同时依赖于服务端和客户端两方的证书来工作。为了生成这些证书,你需要在机器上配置一个证书签发(CA)。幸运地,OpenVPN 在安装中自带了一些用于生成证书的脚本比如 “easy-rsa” 来帮助你加快这个过程。你将要创建一个文件目录用于放置 easy-rsa 脚本,从模板目录复制过来:
|
||||
|
||||
|
||||
```
|
||||
root@test:~# mkdir /etc/openvpn/easy-rsa
|
||||
root@test:~# cp -rpv /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
|
||||
```
|
||||
|
||||
下一步,把 vars 文件复制一个备份:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# cp vars vars.bak
|
||||
```
|
||||
|
||||
接下来,编辑一下 vars 以让其中的信息符合你的状态。我将以我需要编辑的信息作为例子:
|
||||
|
||||
```
|
||||
KEY_SIZE=4096
|
||||
KEY_COUNTRY="US"
|
||||
KEY_PROVINCE="CA"
|
||||
KEY_CITY="Silicon Valley"
|
||||
KEY_ORG="Linux Journal"
|
||||
KEY_EMAIL="bill.childers@linuxjournal.com"
|
||||
```
|
||||
|
||||
下一步是导入(source)一下 vars 中的环境变量,这样系统就能把其中的信息当作环境变量处理了:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# source ./vars
|
||||
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
|
||||
```
|
||||
|
||||
### 搭建 CA(证书签发)
|
||||
|
||||
接下来你要运行一下 `clean-all` 来确保有一个清理干净的系统工作环境,紧接着你就要做证书签发了。注意一下我修改了一些 changeme 的所提示修改的内容以符合我需要的安装情况:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# ./clean-all
|
||||
root@test:/etc/openvpn/easy-rsa# ./build-ca
|
||||
Generating a 4096 bit RSA private key
|
||||
...................................................++
|
||||
...................................................++
|
||||
writing new private key to 'ca.key'
|
||||
-----
|
||||
You are about to be asked to enter information that
|
||||
will be incorporated into your certificate request.
|
||||
What you are about to enter is what is called a
|
||||
Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some
|
||||
blank. For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [US]:
|
||||
State or Province Name (full name) [CA]:
|
||||
Locality Name (eg, city) [Silicon Valley]:
|
||||
Organization Name (eg, company) [Linux Journal]:
|
||||
Organizational Unit Name (eg, section) [changeme]:SecTeam
|
||||
Common Name (eg, your name or your server's hostname) [changeme]:test.linuxjournal.com
|
||||
Name [changeme]:test.linuxjournal.com
|
||||
Email Address [bill.childers@linuxjournal.com]:
|
||||
```
|
||||
|
||||
|
||||
### 生成服务端证书
|
||||
|
||||
一旦 CA 创建好了,你接着就可以生成客户端的 OpenVPN 证书了:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# ./build-key-server test.linuxjournal.com
|
||||
Generating a 4096 bit RSA private key
|
||||
...................................................++
|
||||
writing new private key to 'test.linuxjournal.com.key'
|
||||
-----
|
||||
You are about to be asked to enter information that
|
||||
will be incorporated into your certificate request.
|
||||
What you are about to enter is what is called a
|
||||
Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some
|
||||
blank. For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [US]:
|
||||
State or Province Name (full name) [CA]:
|
||||
Locality Name (eg, city) [Silicon Valley]:
|
||||
Organization Name (eg, company) [Linux Journal]:
|
||||
Organizational Unit Name (eg, section) [changeme]:SecTeam
|
||||
Common Name (eg, your name or your server's hostname) [test.linuxjournal.com]:
|
||||
Name [changeme]:test.linuxjournal.com
|
||||
Email Address [bill.childers@linuxjournal.com]:
|
||||
|
||||
Please enter the following 'extra' attributes
|
||||
to be sent with your certificate request
|
||||
A challenge password []:
|
||||
An optional company name []:
|
||||
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
|
||||
Check that the request matches the signature
|
||||
Signature ok
|
||||
The Subject's Distinguished Name is as follows
|
||||
countryName :PRINTABLE:'US'
|
||||
stateOrProvinceName :PRINTABLE:'CA'
|
||||
localityName :PRINTABLE:'Silicon Valley'
|
||||
organizationName :PRINTABLE:'Linux Journal'
|
||||
organizationalUnitName:PRINTABLE:'SecTeam'
|
||||
commonName :PRINTABLE:'test.linuxjournal.com'
|
||||
name :PRINTABLE:'test.linuxjournal.com'
|
||||
emailAddress :IA5STRING:'bill.childers@linuxjournal.com'
|
||||
Certificate is to be certified until Sep 1 06:23:59 2025 GMT (3650 days)
|
||||
Sign the certificate? [y/n]:y
|
||||
|
||||
1 out of 1 certificate requests certified, commit? [y/n]y
|
||||
Write out database with 1 new entries
|
||||
Data Base Updated
|
||||
```
|
||||
|
||||
下一步需要用掉一些时间来生成 OpenVPN 服务器需要的 Diffie-Hellman 密钥。这个步骤在一般的桌面级 CPU 上会需要几分钟的时间,但在 ARM 构架的树莓派上,会用掉超级超级长的时间。耐心点,只要终端上的点还在跳,那么一切就在按部就班运行(下面的示例省略了不少的点):
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# ./build-dh
|
||||
Generating DH parameters, 4096 bit long safe prime, generator 2
|
||||
This is going to take a long time
|
||||
....................................................+
|
||||
<snipped out many more dots>
|
||||
```
|
||||
|
||||
### 生成客户端证书
|
||||
|
||||
现在你要生成一下客户端用于登录 OpenVPN 的密钥。通常来说 OpenVPN 都会被配置成使用证书验证的加密方式,在这个配置下客户端需要持有由服务端签发的一份证书:
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa# ./build-key bills-computer
|
||||
Generating a 4096 bit RSA private key
|
||||
...................................................++
|
||||
...................................................++
|
||||
writing new private key to 'bills-computer.key'
|
||||
-----
|
||||
You are about to be asked to enter information that
|
||||
will be incorporated into your certificate request.
|
||||
What you are about to enter is what is called a
|
||||
Distinguished Name or a DN. There are quite a few
|
||||
fields but you can leave some blank.
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [US]:
|
||||
State or Province Name (full name) [CA]:
|
||||
Locality Name (eg, city) [Silicon Valley]:
|
||||
Organization Name (eg, company) [Linux Journal]:
|
||||
Organizational Unit Name (eg, section) [changeme]:SecTeam
|
||||
Common Name (eg, your name or your server's hostname) [bills-computer]:
|
||||
Name [changeme]:bills-computer
|
||||
Email Address [bill.childers@linuxjournal.com]:
|
||||
|
||||
Please enter the following 'extra' attributes
|
||||
to be sent with your certificate request
|
||||
A challenge password []:
|
||||
An optional company name []:
|
||||
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
|
||||
Check that the request matches the signature
|
||||
Signature ok
|
||||
The Subject's Distinguished Name is as follows
|
||||
countryName :PRINTABLE:'US'
|
||||
stateOrProvinceName :PRINTABLE:'CA'
|
||||
localityName :PRINTABLE:'Silicon Valley'
|
||||
organizationName :PRINTABLE:'Linux Journal'
|
||||
organizationalUnitName:PRINTABLE:'SecTeam'
|
||||
commonName :PRINTABLE:'bills-computer'
|
||||
name :PRINTABLE:'bills-computer'
|
||||
emailAddress :IA5STRING:'bill.childers@linuxjournal.com'
|
||||
Certificate is to be certified until Sep 1 07:35:07 2025 GMT (3650 days)
|
||||
Sign the certificate? [y/n]:y
|
||||
|
||||
1 out of 1 certificate requests certified, commit? [y/n]y
|
||||
Write out database with 1 new entries
|
||||
Data Base Updated
|
||||
root@test:/etc/openvpn/easy-rsa#
|
||||
```
|
||||
|
||||
现在你需要再生成一个 HMAC 码作为共享密钥来进一步增加整个加密提供的安全性:
|
||||
|
||||
|
||||
```
|
||||
root@test:~# openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key
|
||||
```
|
||||
|
||||
### 配置服务器
|
||||
|
||||
最后,我们到了配置 OpenVPN 服务的时候了。你需要创建一个 `/etc/openvpn/server.conf` 文件;这个配置文件的大多数地方都可以套用模板解决。设置 OpenVPN 服务的主要修改在于让它只用 TCP 而不是 UDP 链接。这是下一步所必需的---如果不是 TCP 连接那么你的服务将不能工作在端口 443 上。创建 `/etc/openvpn/server.conf` 然后把下述配置丢进去:
|
||||
|
||||
|
||||
```
|
||||
port 1194
|
||||
proto tcp
|
||||
dev tun
|
||||
ca easy-rsa/keys/ca.crt
|
||||
cert easy-rsa/keys/test.linuxjournal.com.crt ## or whatever your hostname was
|
||||
key easy-rsa/keys/test.linuxjournal.com.key ## Hostname key - This file should be kept secret
|
||||
management localhost 7505
|
||||
dh easy-rsa/keys/dh4096.pem
|
||||
tls-auth /etc/openvpn/certs/ta.key 0
|
||||
server 10.8.0.0 255.255.255.0 # The server will use this subnet for clients connecting to it
|
||||
ifconfig-pool-persist ipp.txt
|
||||
push "redirect-gateway def1 bypass-dhcp" # Forces clients to redirect all traffic through the VPN
|
||||
push "dhcp-option DNS 192.168.1.1" # Tells the client to use the DNS server at 192.168.1.1 for DNS - replace with the IP address of the OpenVPN machine and clients will use the BIND server setup earlier
|
||||
keepalive 30 240
|
||||
comp-lzo # Enable compression
|
||||
persist-key
|
||||
persist-tun
|
||||
status openvpn-status.log
|
||||
verb 3
|
||||
```
|
||||
|
||||
最后,你将需要在服务器上启用 IP 转发,配置 OpenVPN 为开机启动,并立刻启动 OpenVPN 服务:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa/keys# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
|
||||
root@test:/etc/openvpn/easy-rsa/keys# sysctl -p /etc/sysctl.conf
|
||||
net.core.wmem_max = 12582912
|
||||
net.core.rmem_max = 12582912
|
||||
net.ipv4.tcp_rmem = 10240 87380 12582912
|
||||
net.ipv4.tcp_wmem = 10240 87380 12582912
|
||||
net.core.wmem_max = 12582912
|
||||
net.core.rmem_max = 12582912
|
||||
net.ipv4.tcp_rmem = 10240 87380 12582912
|
||||
net.ipv4.tcp_wmem = 10240 87380 12582912
|
||||
net.core.wmem_max = 12582912
|
||||
net.core.rmem_max = 12582912
|
||||
net.ipv4.tcp_rmem = 10240 87380 12582912
|
||||
net.ipv4.tcp_wmem = 10240 87380 12582912
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv4.ip_forward = 1
|
||||
|
||||
root@test:/etc/openvpn/easy-rsa/keys# update-rc.d openvpn defaults
|
||||
update-rc.d: using dependency based boot sequencing
|
||||
|
||||
root@test:/etc/openvpn/easy-rsa/keys# /etc/init.d/openvpn start
|
||||
[ ok ] Starting virtual private network daemon:.
|
||||
```
|
||||
|
||||
### 配置 OpenVPN 客户端
|
||||
|
||||
客户端的安装取决于客户端的操作系统,但你需要将之前生成的证书和密钥复制到你的客户端上,并导入你的 OpenVPN 客户端并新建一个配置文件。每种操作系统下的 OpenVPN 客户端在操作上会有些稍许不同,这也不在这篇文章的覆盖范围内,所以你最好去看看特定操作系统下的 OpenVPN 文档来获取更多信息。请参考本文档里的资源那一节。
|
||||
|
||||
### 安装 SSLH —— "魔法"多协议切换工具
|
||||
|
||||
本文章介绍的解决方案最有趣的部分就是运用 SSLH 了。SSLH 是一个多重协议工具——它可以监听 443 端口的流量,然后分析他们是 SSH,HTTPS 还是 OpenVPN 的通讯包,并把它们分别转发给正确的系统服务。这就是为何本解决方案可以让你绕过大多数端口封杀——你可以一直使用 HTTPS 通讯,因为它几乎从来不会被封杀。
|
||||
|
||||
同样,直接 `apt-get` 安装:
|
||||
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa/keys# apt-get install sslh
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
The following extra packages will be installed:
|
||||
apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common
|
||||
libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libconfig9
|
||||
Suggested packages:
|
||||
apache2-doc apache2-suexec apache2-suexec-custom openbsd-inetd inet-superserver
|
||||
The following NEW packages will be installed:
|
||||
apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common
|
||||
libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libconfig9 sslh
|
||||
0 upgraded, 11 newly installed, 0 to remove and 0 not upgraded.
|
||||
Need to get 1,568 kB of archives.
|
||||
After this operation, 5,822 kB of additional disk space will be used.
|
||||
Do you want to continue [Y/n]? y
|
||||
```
|
||||
|
||||
在 SSLH 被安装之后,包管理器会询问要在 inetd 还是 standalone 模式下允许。选择 standalone 模式,因为你希望 SSLH 在它自己的进程里运行。如果你没有安装 Apache,apt 包管理器会自动帮你下载并安装的,尽管它也不是完全不可或缺。如果你已经有 Apache 了,那你需要确保它只监听 localhost 端口而不是所有的端口(不然的话 SSLH 会无法运行,因为 443 端口已经被 Apache 监听占用)。安装后,你会看到一个如下所示的错误信息:
|
||||
|
||||
```
|
||||
[....] Starting ssl/ssh multiplexer: sslhsslh disabled, please adjust the configuration to your needs
|
||||
[FAIL] and then set RUN to 'yes' in /etc/default/sslh to enable it. ... failed!
|
||||
failed!
|
||||
```
|
||||
|
||||
这其实并不是错误信息,只是 SSLH 在提醒你它还未被配置所以无法启动,这很正常。配置 SSLH 相对来说比较简单。它的配置文件放置在 `/etc/default/sslh`,你只需要修改 `RUN` 和 `DAEMON_OPTS` 变量就可以了。我的 SSLH 配置文件如下所示:
|
||||
|
||||
```
|
||||
# Default options for sslh initscript
|
||||
# sourced by /etc/init.d/sslh
|
||||
|
||||
# Disabled by default, to force yourself
|
||||
# to read the configuration:
|
||||
# - /usr/share/doc/sslh/README.Debian (quick start)
|
||||
# - /usr/share/doc/sslh/README, at "Configuration" section
|
||||
# - sslh(8) via "man sslh" for more configuration details.
|
||||
# Once configuration ready, you *must* set RUN to yes here
|
||||
# and try to start sslh (standalone mode only)
|
||||
|
||||
RUN=yes
|
||||
|
||||
# binary to use: forked (sslh) or single-thread (sslh-select) version
|
||||
DAEMON=/usr/sbin/sslh
|
||||
|
||||
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --openvpn 127.0.0.1:1194 --pidfile /var/run/sslh/sslh.pid"
|
||||
```
|
||||
|
||||
保存编辑并启动 SSLH:
|
||||
|
||||
```
|
||||
root@test:/etc/openvpn/easy-rsa/keys# /etc/init.d/sslh start
|
||||
[ ok ] Starting ssl/ssh multiplexer: sslh.
|
||||
```
|
||||
|
||||
现在你应该可以从 443 端口 ssh 到你的树莓派了,它会正确地使用 SSLH 转发:
|
||||
|
||||
```
|
||||
$ ssh -p 443 root@test.linuxjournal.com
|
||||
root@test:~#
|
||||
```
|
||||
|
||||
SSLH 现在开始监听端口 443 并且可以转发流量信息到 SSH、Apache 或者 OpenVPN ,这取决于抵达流量包的类型。这套系统现已整装待发了!
|
||||
|
||||
### 结论
|
||||
|
||||
现在你可以启动 OpenVPN 并且配置你的客户端连接到服务器的 443 端口了,然后 SSLH 会从那里把流量转发到服务器的 1194 端口。但鉴于你正在和服务器的 443 端口通信,你的 VPN 流量不会被封锁。现在你可以舒服地坐在陌生小镇的咖啡店里,畅通无阻地通过你的树莓派上的 OpenVPN 浏览互联网。你顺便还给你的链接增加了一些安全性,这个额外作用也会让你的链接更安全和私密一些。享受通过安全跳板浏览互联网把!
|
||||
|
||||
|
||||
### 参考资源
|
||||
|
||||
- 安装与配置 OpenVPN: [https://wiki.debian.org/OpenVPN](https://wiki.debian.org/OpenVPN) 和 [http://cryptotap.com/articles/openvpn](http://cryptotap.com/articles/openvpn)
|
||||
- OpenVPN 客户端下载: [https://openvpn.net/index.php/open-source/downloads.html](https://openvpn.net/index.php/open-source/downloads.html)
|
||||
- OpenVPN iOS 客户端: [https://itunes.apple.com/us/app/openvpn-connect/id590379981?mt=8](https://itunes.apple.com/us/app/openvpn-connect/id590379981?mt=8)
|
||||
- OpenVPN Android 客户端: [https://play.google.com/store/apps/details?id=net.openvpn.openvpn&hl=en](https://play.google.com/store/apps/details?id=net.openvpn.openvpn&hl=en)
|
||||
- Tunnelblick for Mac OS X (OpenVPN 客户端): [https://tunnelblick.net](https://tunnelblick.net)
|
||||
- SSLH 介绍: [http://www.rutschle.net/tech/sslh.shtml](http://www.rutschle.net/tech/sslh.shtml) 和 [https://github.com/yrutschle/sslh](https://github.com/yrutschle/sslh)
|
||||
|
||||
|
||||
----------
|
||||
via: http://www.linuxjournal.com/content/securi-pi-using-raspberry-pi-secure-landing-point?page=0,0
|
||||
|
||||
作者:[Bill Childers][a]
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linuxjournal.com/users/bill-childers
|
@ -0,0 +1,111 @@
|
||||
JStock:Linux 上不错的股票投资组合管理软件
|
||||
================================================================================
|
||||
|
||||
如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受的风险,时间层面的长短和资金盈利的目标去为你量身打造的一种投资计划。鉴于这类软件的重要性,因此从来不会缺乏商业性的 app 和股票行情检测软件,每一个都可以兜售复杂的投资组合以及跟踪报告功能。
|
||||
|
||||
对于我们这些 Linux 爱好者们,我也找到了一些**好用的开源投资组合管理工具**,用来在 Linux 上管理和跟踪股票的投资组合,这里高度推荐一个基于 java 编写的管理软件 [JStock][1]。如果你不是一个 java 粉,也许你会放弃它,JStock 需要运行在沉重的 JVM 环境上。但同时,在每一个安装了 JRE 的环境中它都可以马上运行起来,在你的 Linux 环境中它会运行的很顺畅。
|
||||
|
||||
“开源”就意味着免费或标准低下的时代已经过去了。鉴于 JStock 只是一个个人完成的产物,作为一个投资组合管理软件它最令人印象深刻的是包含了非常多实用的功能,以上所有的荣誉属于它的作者 Yan Cheng Cheok!例如,JStock 支持通过监视列表去监控价格,多种投资组合,自选/内置的股票指标与相关监测,支持27个不同的股票市场和跨平台的云端备份/还原。JStock 支持多平台部署(Linux, OS X, Android 和 Windows),你可以通过云端保存你的 JStock 投资组合,并通过云平台无缝的备份/还原到其他的不同平台上面。
|
||||
|
||||
现在我将向你展示如何安装以及使用过程的一些具体细节。
|
||||
|
||||
### 在 Linux 上安装 JStock ###
|
||||
|
||||
因为 JStock 使用Java编写,所以必须[安装 JRE][2]才能让它运行起来。小提示,JStock 需要 JRE1.7 或更高版本。如你的 JRE 版本不能满足这个需求,JStock 将会运行失败然后出现下面的报错。
|
||||
|
||||
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/yccheok/jstock/gui/JStock : Unsupported major.minor version 51.0
|
||||
|
||||
|
||||
在你的 Linux 上安装好了 JRE 之后,从其官网下载最新的发布的 JStock,然后加载启动它。
|
||||
|
||||
$ wget https://github.com/yccheok/jstock/releases/download/release_1-0-7-13/jstock-1.0.7.13-bin.zip
|
||||
$ unzip jstock-1.0.7.13-bin.zip
|
||||
$ cd jstock
|
||||
$ chmod +x jstock.sh
|
||||
$ ./jstock.sh
|
||||
|
||||
教程的其他部分,让我来给大家展示一些 JStock 的实用功能
|
||||
|
||||
### 监视监控列表中股票价格的波动 ###
|
||||
|
||||
使用 JStock 你可以创建一个或多个监视列表,它可以自动的监视股票价格的波动并给你提供相应的通知。在每一个监视列表里面你可以添加多个感兴趣的股票进去。之后在“Fall Below”和“Rise Above”的表格里添加你的警戒值,分别设定该股票的最低价格和最高价格。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1588/23795349969_37f4b0f23c_c.jpg)
|
||||
|
||||
例如你设置了 AAPL 股票的最低/最高价格分别是 $102 和 $115.50,只要在价格低于 $102 或高于 $115.50 时你就得到桌面通知。
|
||||
|
||||
你也可以设置邮件通知,这样你将收到一些价格信息的邮件通知。设置邮件通知在“Options”菜单里,在“Alert”标签中国,打开“Send message to email(s)”,填入你的 Gmail 账户。一旦完成 Gmail 认证步骤,JStock 就会开始发送邮件通知到你的 Gmail 账户(也可以设置其他的第三方邮件地址)。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1644/24080560491_3aef056e8d_b.jpg)
|
||||
|
||||
### 管理多个投资组合 ###
|
||||
|
||||
JStock 允许你管理多个投资组合。这个功能对于你使用多个股票经纪人时是非常实用的。你可以为每个经纪人创建一个投资组合去管理你的“买入/卖出/红利”用来了解每一个经纪人的业务情况。你也可以在“Portfolio”菜单里面选择特定的投资组合来切换不同的组合项目。下面是一张截图用来展示一个假设的投资组合。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1646/23536385433_df6c036c9a_c.jpg)
|
||||
|
||||
你也可以设置付给中介费,你可以为每个买卖交易设置中介费、印花税以及结算费。如果你比较懒,你也可以在选项菜单里面启用自动费用计算,并提前为每一家经济事务所设置费用方案。当你为你的投资组合增加交易之后,JStock 将自动的计算并计入费用。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1653/24055085262_0e315c3691_b.jpg)
|
||||
|
||||
### 使用内置/自选股票指标来监控 ###
|
||||
|
||||
如果你要做一些股票的技术分析,你可能需要基于各种不同的标准来监控股票(这里叫做“股票指标”)。对于股票的跟踪,JStock提供多个[预设的技术指示器][3] 去获得股票上涨/下跌/逆转指数的趋势。下面的列表里面是一些可用的指标。
|
||||
|
||||
- 平滑异同移动平均线(MACD)
|
||||
- 相对强弱指标 (RSI)
|
||||
- 资金流向指标 (MFI)
|
||||
- 顺势指标 (CCI)
|
||||
- 十字线
|
||||
- 黄金交叉线,死亡交叉线
|
||||
- 涨幅/跌幅
|
||||
|
||||
开启预设指示器能需要在 JStock 中点击“Stock Indicator Editor”标签。之后点击右侧面板中的安装按钮。选择“Install from JStock server”选项,之后安装你想要的指示器。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1476/23867534660_b6a9c95a06_c.jpg)
|
||||
|
||||
一旦安装了一个或多个指示器,你可以用他们来扫描股票。选择“Stock Indicator Scanner”标签,点击底部的“Scan”按钮,选择需要的指示器。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1653/24137054996_e8fcd10393_c.jpg)
|
||||
|
||||
当你选择完需要扫描的股票(例如, NYSE, NASDAQ)以后,JStock 将执行该扫描,并将该指示器捕获的结果通过列表展现。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1446/23795349889_0f1aeef608_c.jpg)
|
||||
|
||||
除了预设指示器以外,你也可以使用一个图形化的工具来定义自己的指示器。下面这张图例用于监控当前价格小于或等于60天平均价格的股票。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1605/24080560431_3d26eac6b5_c.jpg)
|
||||
|
||||
### 通过云在 Linux 和 Android JStock 之间备份/恢复###
|
||||
|
||||
另一个非常棒的功能是 JStock 支持云备份恢复。Jstock 可以通过 Google Drive 把你的投资组合/监视列表在云上备份和恢复,这个功能可以实现在不同平台上无缝穿梭。如果你在两个不同的平台之间来回切换使用 Jstock,这种跨平台备份和还原非常有用。我在 Linux 桌面和 Android 手机上测试过我的 Jstock 投资组合,工作的非常漂亮。我在 Android 上将 Jstock 投资组合信息保存到 Google Drive 上,然后我可以在我的 Linux 版的 Jstock 上恢复它。如果能够自动同步到云上,而不用我手动地触发云备份/恢复就更好了,十分期望这个功能出现。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1537/24163165565_bb47e04d6c_c.jpg)
|
||||
|
||||
![](https://c2.staticflickr.com/2/1556/23536385333_9ed1a75d72_c.jpg)
|
||||
|
||||
如果你在从 Google Drive 还原之后不能看到你的投资信息以及监视列表,请确认你的国家信息与“Country”菜单里面设置的保持一致。
|
||||
|
||||
JStock 的安卓免费版可以从 [Google Play Store][4] 获取到。如果你需要完整的功能(比如云备份,通知,图表等),你需要一次性支付费用升级到高级版。我认为高级版物有所值。
|
||||
|
||||
![](https://c2.staticflickr.com/2/1687/23867534720_18b917028c_c.jpg)
|
||||
|
||||
写在最后,我应该说一下它的作者,Yan Cheng Cheok,他是一个十分活跃的开发者,有bug及时反馈给他。这一切都要感谢他!!!
|
||||
|
||||
关于 JStock 这个投资组合跟踪软件你有什么想法呢?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://xmodulo.com/stock-portfolio-management-software-Linux.html
|
||||
|
||||
作者:[Dan Nanni][a]
|
||||
译者:[ivo-wang](https://github.com/ivo-wang)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://Linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://xmodulo.com/author/nanni
|
||||
[1]:http://jstock.org/
|
||||
[2]:http://ask.xmodulo.com/install-java-runtime-Linux.html
|
||||
[3]:http://jstock.org/ma_indicator.html
|
||||
[4]:https://play.google.com/store/apps/details?id=org.yccheok.jstock.gui
|
@ -0,0 +1,104 @@
|
||||
在 Linux 上管理加密密钥的最佳体验
|
||||
=============================================
|
||||
|
||||
存储 SSH 的加密秘钥和记住密码一直是一个让人头疼的问题。但是不幸的是,在当前这个充满了恶意黑客和攻击的世界中,基本的安全预防是必不可少的。对于许多普通用户来说,大多数人只能是记住密码,也可能寻找到一个好程序去存储密码,正如我们提醒这些用户不要在每个网站采用相同的密码。但是对于在各个 IT 领域的人们,我们需要将这个事情提高一个层面。我们需要使用像 SSH 密钥这样的加密秘钥,而不只是密码。
|
||||
|
||||
设想一个场景:我有一个运行在云上的服务器,用作我的主 git 库。我有很多台工作电脑,所有这些电脑都需要登录到这个中央服务器去做 push 与 pull 操作。这里我设置 git 使用 SSH。当 git 使用 SSH 时,git 实际上是以 SSH 的方式登录到服务器,就好像你通过 SSH 命令打开一个服务器的命令行一样。为了把这些配置好,我在我的 .ssh 目录下创建一个配置文件,其中包含一个有服务器名字、主机名、登录用户、密钥文件路径等信息的主机项。之后我可以通过输入如下命令来测试这个配置是否正确。
|
||||
|
||||
ssh gitserver
|
||||
|
||||
很快我就可以访问到服务器的 bash shell。现在我可以配置 git 使用相同配置项以及存储的密钥来登录服务器。这很简单,只是有一个问题:对于每一个我要用它登录服务器的电脑,我都需要有一个密钥文件,那意味着需要密钥文件会放在很多地方。我会在当前这台电脑上存储这些密钥文件,我的其他电脑也都需要存储这些。就像那些有特别多的密码的用户一样,我们这些 IT 人员也被这些特别多的密钥文件淹没。怎么办呢?
|
||||
|
||||
### 清理
|
||||
|
||||
在我们开始帮助你管理密钥之前,你需要有一些密钥应该怎么使用的基础知识,以及明白我们下面的提问的意义所在。同时,有个前提,也是最重要的,你应该知道你的公钥和私钥该放在哪里。然后假设你应该知道:
|
||||
|
||||
1. 公钥和私钥之间的差异;
|
||||
2. 为什么你不可以从公钥生成私钥,但是反之则可以?
|
||||
3. `authorized_keys` 文件的目的以及里面包含什么内容;
|
||||
4. 如何使用私钥去登录一个你的对应公钥存储在其上的 `authorized_keys` 文件中的服务器。
|
||||
|
||||
![](http://www.linux.com/images/stories/41373/key-management-diagram.png)
|
||||
|
||||
这里有一个例子。当你在亚马逊的网络服务上创建一个云服务器,你必须提供一个用于连接你的服务器的 SSH 密钥。每个密钥都有一个公开的部分(公钥)和私密的部分(私钥)。你要想让你的服务器安全,乍看之下你可能应该将你的私钥放到服务器上,同时你自己带着公钥。毕竟,你不想你的服务器被公开访问,对吗?但是实际上的做法正好是相反的。
|
||||
|
||||
你应该把自己的公钥放到 AWS 服务器,同时你持有用于登录服务器的私钥。你需要保护好私钥,并让它处于你的控制之中,而不是放在一些远程服务器上,正如上图中所示。
|
||||
|
||||
原因如下:如果公钥被其他人知道了,它们不能用于登录服务器,因为他们没有私钥。进一步说,如果有人成功攻入你的服务器,他们所能找到的只是公钥,他们不可以从公钥生成私钥。同时,如果你在其他的服务器上使用了相同的公钥,他们不可以使用它去登录别的电脑。
|
||||
|
||||
这就是为什么你要把你自己的公钥放到你的服务器上以便通过 SSH 登录这些服务器。你持有这些私钥,不要让这些私钥脱离你的控制。
|
||||
|
||||
但是还有一点麻烦。试想一下我 git 服务器的例子。我需要做一些抉择。有时我登录架设在别的地方的开发服务器,而在开发服务器上,我需要连接我的 git 服务器。如何使我的开发服务器连接 git 服务器?显然是通过使用私钥,但这样就会有问题。在该场景中,需要我把私钥放置到一个架设在别的地方的服务器上,这相当危险。
|
||||
|
||||
一个进一步的场景:如果我要使用一个密钥去登录许多的服务器,怎么办?如果一个入侵者得到这个私钥,这个人就能用这个私钥得到整个服务器网络的权限,这可能带来一些严重的破坏,这非常糟糕。
|
||||
|
||||
同时,这也带来了另外一个问题,我真的应该在这些其他服务器上使用相同的密钥吗?因为我刚才描述的,那会非常危险的。
|
||||
|
||||
最后,这听起来有些混乱,但是确实有一些简单的解决方案。让我们有条理地组织一下。
|
||||
|
||||
(注意,除了登录服务器,还有很多地方需要私钥密钥,但是我提出的这个场景可以向你展示当你使用密钥时你所面对的问题。)
|
||||
|
||||
### 常规口令
|
||||
|
||||
当你创建你的密钥时,你可以选择是否包含一个密钥使用时的口令。有了这个口令,私钥文件本身就会被口令所加密。例如,如果你有一个公钥存储在服务器上,同时你使用私钥去登录服务器的时候,你会被提示输入该口令。没有口令,这个密钥是无法使用的。或者你也可以配置你的密钥不需要口令,然后只需要密钥文件就可以登录服务器了。
|
||||
|
||||
一般来说,不使用口令对于用户来说是更方便的,但是在很多情况下我强烈建议使用口令,原因是,如果私钥文件被偷了,偷密钥的人仍然不可以使用它,除非他或者她可以找到口令。在理论上,这个将节省你很多时间,因为你可以在攻击者发现口令之前,从服务器上删除公钥文件,从而保护你的系统。当然还有一些使用口令的其它原因,但是在很多场合这个原因对我来说更有价值。(举一个例子,我的 Android 平板上有 VNC 软件。平板上有我的密钥。如果我的平板被偷了之后,我会马上从服务器上删除公钥,使得它的私钥没有作用,无论有没有口令。)但是在一些情况下我不使用口令,是因为我正在登录的服务器上没有什么有价值的数据,这取决于情境。
|
||||
|
||||
### 服务器基础设施
|
||||
|
||||
你如何设计自己服务器的基础设施将会影响到你如何管理你的密钥。例如,如果你有很多用户登录,你将需要决定每个用户是否需要一个单独的密钥。(一般来说,应该如此;你不会想在用户之间共享私钥。那样当一个用户离开组织或者失去信任时,你可以删除那个用户的公钥,而不需要必须给其他人生成新的密钥。相似地,通过共享密钥,他们能以其他人的身份登录,这就更糟糕了。)但是另外一个问题是你如何配置你的服务器。举例来说,你是否使用像 Puppet 这样工具配置大量的服务器?你是否基于你自己的镜像创建大量的服务器?当你复制你的服务器,是否每一个的密钥都一样?不同的云服务器软件允许你配置如何选择;你可以让这些服务器使用相同的密钥,也可以给每一个服务器生成一个新的密钥。
|
||||
|
||||
如果你在操作这些复制的服务器,如果用户需要使用不同的密钥登录两个不同但是大部分都一样的系统,它可能导致混淆。但是另一方面,服务器共享相同的密钥会有安全风险。或者,第三,如果你的密钥有除了登录之外的需要(比如挂载加密的驱动),那么你会在很多地方需要相同的密钥。正如你所看到的,你是否需要在不同的服务器上使用相同的密钥不是我能为你做的决定;这其中有权衡,你需要自己去决定什么是最好的。
|
||||
|
||||
最终,你可能会有:
|
||||
|
||||
- 需要登录的多个服务器
|
||||
- 多个用户登录到不同的服务器,每个都有自己的密钥
|
||||
- 每个用户使用多个密钥登录到不同的服务器
|
||||
|
||||
(如果你正在别的情况下使用密钥,这个同样的普适理论也能应用于如何使用密钥,需要多少密钥,它们是否共享,你如何处理公私钥等方面。)
|
||||
|
||||
### 安全方法
|
||||
|
||||
了解你的基础设施和特有的情况,你需要组合一个密钥管理方案,它会指导你如何去分发和存储你的密钥。比如,正如我之前提到的,如果我的平板被偷了,我会从我服务器上删除公钥,我希望这在平板在用于访问服务器之前完成。同样的,我会在我的整体计划中考虑以下内容:
|
||||
|
||||
1. 私钥可以放在移动设备上,但是必须包含口令;
|
||||
2. 必须有一个可以快速地从服务器上删除公钥的方法。
|
||||
|
||||
在你的情况中,你可能决定你不想在自己经常登录的系统上使用口令;比如,这个系统可能是一个开发者一天登录多次的测试机器。这没有问题,但是你需要调整一点你的规则。你可以添加一条规则:不可以通过移动设备登录该机器。换句话说,你需要根据自己的状况构建你的准则,不要假设某个方案放之四海而皆准。
|
||||
|
||||
### 软件
|
||||
|
||||
至于软件,令人吃惊的是,现实世界中并没有很多好的、可靠的存储和管理私钥的软件解决方案。但是应该有吗?考虑下这个,如果你有一个程序存储你所有服务器的全部密钥,并且这个程序被一个快捷的密钥锁住,那么你的密钥就真的安全了吗?或者类似的,如果你的密钥被放置在你的硬盘上,用于 SSH 程序快速访问,密钥管理软件是否真正提供了任何保护吗?
|
||||
|
||||
但是对于整体基础设施和创建/管理公钥来说,有许多的解决方案。我已经提到了 Puppet,在 Puppet 的世界中,你可以创建模块以不同的方式管理你的服务器。这个想法是服务器是动态的,而且不需要精确地复制彼此。[这里有一个聪明的方法](http://manuel.kiessling.net/2014/03/26/building-manageable-server-infrastructures-with-puppet-part-4/),在不同的服务器上使用相同的密钥,但是对于每一个用户使用不同的 Puppet 模块。这个方案可能适合你,也可能不适合你。
|
||||
|
||||
或者,另一个选择就是完全换个不同的档位。在 Docker 的世界中,你可以采取一个不同的方式,正如[关于 SSH 和 Docker 博客](http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/)所描述的那样。
|
||||
|
||||
但是怎么样管理私钥?如果你搜索过的话,你无法找到很多可以选择的软件,原因我之前提到过;私钥存放在你的硬盘上,一个管理软件可能无法提到更多额外的安全。但是我使用这种方法来管理我的密钥:
|
||||
|
||||
首先,我的 `.ssh/config` 文件中有很多的主机项。我要登录的都有一个主机项,但是有时我对于一个单独的主机有不止一项。如果我有很多登录方式,就会出现这种情况。对于放置我的 git 库的服务器来说,我有两个不同的登录项;一个限制于 git,另一个用于一般用途的 bash 访问。这个为 git 设置的登录选项在机器上有极大的限制。还记得我之前说的我存储在远程开发机器上的 git 密钥吗?好了。虽然这些密钥可以登录到我其中一个服务器,但是使用的账号是被严格限制的。
|
||||
|
||||
其次,大部分的私钥都包含口令。(对于需要多次输入口令的情况,考虑使用 [ssh-agent](http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/)。)
|
||||
|
||||
再次,我有一些我想要更加小心地保护的服务器,我不会把这些主机项放在我的 host 文件中。这更加接近于社会工程方面,密钥文件还在,但是可能需要攻击者花费更长的时间去找到这个密钥文件,分析出来它们对应的机器。在这种情况下,我就需要手动打出来一条长长的 SSH 命令。(没那么可怕。)
|
||||
|
||||
同时你可以看出来我没有使用任何特别的软件去管理这些私钥。
|
||||
|
||||
## 无放之四海而皆准的方案
|
||||
|
||||
我们偶尔会在 linux.com 收到一些问题,询问管理密钥的好软件的建议。但是退一步看,这个问题事实上需要重新思考,因为没有一个普适的解决方案。你问的问题应该基于你自己的状况。你是否简单地尝试找到一个位置去存储你的密钥文件?你是否寻找一个方法去管理多用户问题,其中每个人都需要将他们自己的公钥插入到 `authorized_keys` 文件中?
|
||||
|
||||
通过这篇文章,我已经囊括了这方面的基础知识,希望到此你明白如何管理你的密钥,并且,只有当你问出了正确的问题,无论你寻找任何软件(甚至你需要另外的软件),它都会出现。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linux.com/learn/tutorials/838235-how-to-best-manage-encryption-keys-on-linux
|
||||
|
||||
作者:[Jeff Cogswell][a]
|
||||
译者:[mudongliang](https://github.com/mudongliang)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linux.com/community/forums/person/62256
|
@ -0,0 +1,110 @@
|
||||
Linux 开发者如何看待 Git 和 Github?
|
||||
=====================================================
|
||||
|
||||
### Linux 开发者如何看待 Git 和 Github?
|
||||
|
||||
Git 和 Github 在 Linux 开发者中有很高的知名度。但是开发者如何看待它们呢?另外,Github 是不是真的和 Git 是一个意思?一个 Linux reddit 用户最近问到了这个问题,并且得到了很有意思的答案。
|
||||
|
||||
Dontwakemeup46 提问:
|
||||
|
||||
> 我正在学习 Git 和 Github。我感兴趣社区如何看待两者?据我所知,Git 和 Github 应用十分广泛。但是 Git 或 Github 有没有严重的不足?社区喜欢去改变些什么呢?
|
||||
|
||||
[更多见 Reddit](https://www.reddit.com/r/linux/comments/45jy59/the_popularity_of_git_and_github/)
|
||||
|
||||
与他志同道合的 Linux reddit 用户回答了他们对于 Git 和 Github的观点:
|
||||
|
||||
>**Derenir**: “Github 并不附属于 Git。
|
||||
|
||||
> Git 是由 Linus Torvalds 开发的。
|
||||
|
||||
> Github 几乎不支持 Linux。
|
||||
|
||||
> Github 是一家企图借助 Git 赚钱的公司。
|
||||
|
||||
> https://desktop.github.com/ 并没有支持 Linux。”
|
||||
|
||||
---
|
||||
>**Bilog78**: “一个小的补充: Linus Torvalds 已经不再维护 Git了。维护者是 Junio C Hamano,以及 在他之后的主要贡献者是 Jeff King 和 Shawn O. Pearce。”
|
||||
|
||||
---
|
||||
|
||||
>**Fearthefuture**: “我喜欢 Git,但是不明白人们为什么还要使用 Github。从我的角度,Github 比 Bitbucket 好的一点是用户统计和更大的用户基础。Bitbucket 有无限的免费私有库,更好的 UI,以及更好地集成了其他服务,比如说 Jenkins。”
|
||||
|
||||
---
|
||||
|
||||
>**Thunger**: “Gitlab.com 也很不错,特别是你可以在自己的服务器上架设自己的实例。”
|
||||
|
||||
---
|
||||
|
||||
>**Takluyver**: “很多人熟悉 Github 的 UI 以及相关联的服务,比如说 Travis 。并且很多人都有 Github 账号,所以它是存储项目的一个很好的地方。人们也使用他们的 Github 个人信息页作为一种求职用的作品选辑,所以他们很积极地将更多的项目放在这里。Github 是一个存放开源项目的事实标准。”
|
||||
|
||||
---
|
||||
|
||||
>**Tdammers**: “Git 严重问题在于 UI,它有些违反直觉,以至于很多用户只能达到使用一些容易记住的咒语的程度。”
|
||||
|
||||
> Github:最严重的问题在于它是商业托管的解决方案;你买了方便,但是代价是你的代码在别人的服务器上面,已经不在你的掌控范围之内了。另一个对于 Github 的普遍批判是它的工作流和 Git 本身的精神不符,特别是 pull requests 工作的方式。最后, Github 垄断了代码的托管环境,同时对于多样性是很不好的,这反过来对于旺盛的免费软件社区很重要。”
|
||||
|
||||
---
|
||||
|
||||
>**Dies**: “更重要的是,如果一旦是这样,按照现状来说,我猜我们会被 Github 所困,因为它们控制如此多的项目。”
|
||||
|
||||
---
|
||||
|
||||
>**Tdammers**: “代码托管在别人的服务器上,这里"别人"指的是 Github。这对于开源项目来说,并不是什么太大的问题,但是尽管如此,你无法控制它。如果你在 Github 上有私有项目,“它将保持私有”的唯一的保险只是 Github 的承诺而已。如果你决定删除东西,你不能确定东西是否被删除了,或者只是隐藏了。
|
||||
|
||||
Github 并不自己控制这些项目(你总是可以拿走你的代码,然后托管到别的地方,声明新位置是“官方”的),它只是有比开发者本身有更深的使用权。”
|
||||
|
||||
---
|
||||
|
||||
>**Drelos**: “我已经读了大量的关于 Github 的赞美与批评。(这里有一个[例子](http://www.wired.com/2015/06/problem-putting-worlds-code-github/)),但是我的幼稚问题是为什么不向一个免费开源的版本努力呢?”
|
||||
|
||||
---
|
||||
|
||||
>**Twizmwazin**: “Gitlab 的源码就存在这里”
|
||||
|
||||
---
|
||||
|
||||
[更多见 Reddit](https://www.reddit.com/r/linux/comments/45jy59/the_popularity_of_git_and_github/)
|
||||
|
||||
### DistroWatch 评估 XStream 桌面 153 版本
|
||||
|
||||
XStreamOS 是一个由 Sonicle 创建的 Solaris 的一个版本。XStream 桌面将 Solaris 的强大带给了桌面用户,同时新手用户很可能有兴趣体验一下。DistroWatch 对于 XStream 桌面 153 版本做了一个很全面的评估,并且发现它运行相当好。
|
||||
|
||||
Jesse Smith 为 DistroWatch 报道:
|
||||
|
||||
> 我认为 XStream 桌面做好了很多事情。诚然,当操作系统无法在我的硬件上启动,同时当运行在 VirtualBox 中时我无法使得桌面使用我显示器的完整分辨率,我的开端并不很成功。不过,除此之外,XStream 表现的很好。安装器工作的很好,该系统自动设置和使用了引导环境(boot environments),这让我们可以在发生错误时恢复该系统。包管理器有工作的不错, XStream 带了一套有用的软件。
|
||||
|
||||
> 我确实在播放多媒体文件时遇见一些问题,特别是使声卡工作。我不确定这是不是又一个硬件兼容问题,或者是该操作系统自带的多媒体软件的问题。另一方面,像 Web 浏览器,电子邮件,生产工具套件以及配置工具这样的工作的很好。
|
||||
|
||||
> 我最欣赏 XStream 的地方是这个操作系统是 OpenSolaris 家族的一个使用保持最新的分支。OpenSolaris 的其他衍生系统有落后的倾向,但是至少在桌面软件上,XStream 搭载最新版本的火狐和 LibreOffice。
|
||||
|
||||
> 对我个人来说,XStream 缺少一些组件,比如打印机管理器,多媒体支持和我的特定硬件的驱动。这个操作系统的其他方面也是相当吸引人的。我喜欢开发者搭配了 LXDE,也喜欢它的默认软件集,以及我最喜欢文件系统快照和启动环境开箱即用的方式。大多数的 Linux 发行版,openSUSE 除外,并没有利用好引导环境(boot environments)的用途。我希望它是一个被更多项目采用的技术。
|
||||
|
||||
[更多见 DistroWatch](http://distrowatch.com/weekly.php?issue=20160215#xstreamos)
|
||||
|
||||
### 街头霸王 V 和 SteamOS
|
||||
|
||||
街头霸王是最出名的游戏之一,并且 [Capcom 已经宣布](http://steamcommunity.com/games/310950/announcements/detail/857177755595160250) 街头霸王 V 将会在这个春天进入 Linux 和 StreamOS。这对于 Linux 游戏者是非常好的消息。
|
||||
|
||||
Joe Parlock 为 Destructoid 报道:
|
||||
|
||||
> 你是不足 1% 的那些在 Linux 系统上玩游戏的 Stream 用户吗?你是更少数的那些在 Linux 平台上玩游戏,同时也很喜欢街头霸王 V 的人之一吗?是的话,我有一些好消息要告诉你。
|
||||
|
||||
> Capcom 已经宣布,这个春天街头霸王 V 通过 Stream 进入 StreamOS 以及其他 Linux 发行版。它无需任何额外的花费,所以那些已经在自己的个人电脑上安装了该游戏的人可以很容易在 Linux 上安装它并玩了。
|
||||
|
||||
[更多 Destructoid](https://www.destructoid.com/street-fighter-v-is-coming-to-linux-and-steamos-this-spring-341531.phtml)
|
||||
|
||||
你是否错过了摘要?检查 [开源之眼的主页](http://www.infoworld.com/blog/eye-on-open/) 来获得关于 Linux 和开源的最新的新闻。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.infoworld.com/article/3033059/linux/what-do-linux-developers-think-of-git-and-github.html
|
||||
|
||||
作者:[Jim Lynch][a]
|
||||
译者:[mudongliang](https://github.com/mudongliang)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.infoworld.com/author/Jim-Lynch/
|
||||
|
@ -0,0 +1,213 @@
|
||||
如何在 Ubuntu 15.04/CentOS 7 中安装 Lighttpd Web 服务器
|
||||
=================================================================================
|
||||
|
||||
Lighttpd 是一款开源 Web 服务器软件。Lighttpd 安全快速,符合行业标准,适配性强并且针对高配置环境进行了优化。相对于其它的 Web 服务器而言,Lighttpd 占用内存更少;因其对 CPU 占用小和对处理速度的优化而在效率和速度方面从众多 Web 服务器中脱颖而出。而 Lighttpd 诸如 FastCGI、CGI、认证、输出压缩、URL 重写等高级功能更是那些面临性能压力的服务器的福音。
|
||||
|
||||
以下便是我们在运行 Ubuntu 15.04 或 CentOS 7 Linux 发行版的机器上安装 Lighttpd Web 服务器的简要流程。
|
||||
|
||||
### 安装Lighttpd
|
||||
|
||||
#### 使用包管理器安装
|
||||
|
||||
这里我们通过使用包管理器这种最简单的方法来安装 Lighttpd。只需以 sudo 模式在终端或控制台中输入下面的指令即可。
|
||||
|
||||
**CentOS 7**
|
||||
|
||||
由于 CentOS 7.0 官方仓库中并没有提供 Lighttpd,所以我们需要在系统中安装额外的软件源 epel 仓库。使用下面的 yum 指令来安装 epel。
|
||||
|
||||
# yum install epel-release
|
||||
|
||||
然后,我们需要更新系统及为 Lighttpd 的安装做前置准备。
|
||||
|
||||
# yum update
|
||||
# yum install lighttpd
|
||||
|
||||
![Install Lighttpd Centos](http://blog.linoxide.com/wp-content/uploads/2016/02/install-lighttpd-centos.png)
|
||||
|
||||
**Ubuntu 15.04**
|
||||
|
||||
Ubuntu 15.04 官方仓库中包含了 Lighttpd,所以只需更新本地仓库索引并使用 apt-get 指令即可安装 Lighttpd。
|
||||
|
||||
# apt-get update
|
||||
# apt-get install lighttpd
|
||||
|
||||
![Install lighttpd ubuntu](http://blog.linoxide.com/wp-content/uploads/2016/02/install-lighttpd-ubuntu.png)
|
||||
|
||||
#### 从源代码安装 Lighttpd
|
||||
|
||||
如果想从 Lighttpd 源码安装最新版本(例如 1.4.39),我们需要在本地编译源码并进行安装。首先我们要安装编译源码所需的依赖包。
|
||||
|
||||
# cd /tmp/
|
||||
# wget http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-1.4.39.tar.gz
|
||||
|
||||
下载完成后,执行下面的指令解压缩。
|
||||
|
||||
# tar -zxvf lighttpd-1.4.39.tar.gz
|
||||
|
||||
然后使用下面的指令进行编译。
|
||||
|
||||
# cd lighttpd-1.4.39
|
||||
# ./configure
|
||||
# make
|
||||
|
||||
**注:**在这份教程中,我们安装的是默认配置的 Lighttpd。其他拓展功能,如对 SSL 的支持,mod_rewrite,mod_redirect 等,需自行配置。
|
||||
|
||||
当编译完成后,我们就可以把它安装到系统中了。
|
||||
|
||||
# make install
|
||||
|
||||
### 设置 Lighttpd
|
||||
|
||||
如果有更高的需求,我们可以通过修改默认设置文件,如`/etc/lighttpd/lighttpd.conf`,来对 Lighttpd 进行进一步设置。 而在这份教程中我们将使用默认设置,不对设置文件进行修改。如果你曾做过修改并想检查设置文件是否出错,可以执行下面的指令。
|
||||
|
||||
# lighttpd -t -f /etc/lighttpd/lighttpd.conf
|
||||
|
||||
#### 使用 CentOS 7
|
||||
|
||||
在 CentOS 7 中,我们需创建一个在 Lighttpd 默认配置文件中设置的 webroot 文件夹,例如`/src/www/htdocs`。
|
||||
|
||||
# mkdir -p /srv/www/htdocs/
|
||||
|
||||
而后将默认欢迎页面从`/var/www/lighttpd`复制至刚刚新建的目录中:
|
||||
|
||||
# cp -r /var/www/lighttpd/* /srv/www/htdocs/
|
||||
|
||||
### 开启服务
|
||||
|
||||
现在,通过执行 systemctl 指令来重启 Web 服务。
|
||||
|
||||
# systemctl start lighttpd
|
||||
|
||||
然后我们将它设置为伴随系统启动自动运行。
|
||||
|
||||
# systemctl enable lighttpd
|
||||
|
||||
### 设置防火墙
|
||||
|
||||
如要让我们运行在 Lighttpd 上的网页或网站能在 Internet 或同一个网络内被访问,我们需要在防火墙程序中设置打开 80 端口。由于 CentOS 7 和 Ubuntu15.04 都附带 Systemd 作为默认初始化系统,所以我们默认用的都是 firewalld。如果要打开 80 端口或 http 服务,我们只需执行下面的命令:
|
||||
|
||||
# firewall-cmd --permanent --add-service=http
|
||||
success
|
||||
# firewall-cmd --reload
|
||||
success
|
||||
|
||||
### 连接至 Web 服务器
|
||||
|
||||
在将 80 端口设置为默认端口后,我们就可以直接访问 Lighttpd 的默认欢迎页了。我们需要根据运行 Lighttpd 的设备来设置浏览器的 IP 地址和域名。在本教程中,我们令浏览器访问 [http://lighttpd.linoxide.com/](http://lighttpd.linoxide.com/) ,同时将该子域名指向上述 IP 地址。如此一来,我们就可以在浏览器中看到如下的欢迎页面了。
|
||||
|
||||
![Lighttpd Welcome Page](http://blog.linoxide.com/wp-content/uploads/2016/02/lighttpd-welcome-page.png)
|
||||
|
||||
此外,我们可以将网站的文件添加到 webroot 目录下,并删除 Lighttpd 的默认索引文件,使我们的静态网站可以在互联网上访问。
|
||||
|
||||
如果想在 Lighttpd Web 服务器中运行 PHP 应用,请参考下面的步骤:
|
||||
|
||||
### 安装 PHP5 模块
|
||||
|
||||
在 Lighttpd 成功安装后,我们需要安装 PHP 及相关模块,以在 Lighttpd 中运行 PHP5 脚本。
|
||||
|
||||
#### 使用 Ubuntu 15.04
|
||||
|
||||
# apt-get install php5 php5-cgi php5-fpm php5-mysql php5-curl php5-gd php5-intl php5-imagick php5-mcrypt php5-memcache php-pear
|
||||
|
||||
#### 使用 CentOS 7
|
||||
|
||||
# yum install php php-cgi php-fpm php-mysql php-curl php-gd php-intl php-pecl-imagick php-mcrypt php-memcache php-pear lighttpd-fastcgi
|
||||
|
||||
### 设置 Lighttpd 的 PHP 服务
|
||||
|
||||
如要让 PHP 与 Lighttpd 协同工作,我们只要根据所使用的发行版执行如下对应的指令即可。
|
||||
|
||||
#### 使用 CentOS 7
|
||||
|
||||
首先要做的便是使用文件编辑器编辑 php 设置文件(例如`/etc/php.ini`)并取消掉对**cgi.fix_pathinfo=1**这一行的注释。
|
||||
|
||||
# nano /etc/php.ini
|
||||
|
||||
完成上面的步骤之后,我们需要把 PHP-FPM 进程的所有权从 Apache 转移至 Lighttpd。要完成这些,首先用文件编辑器打开`/etc/php-fpm.d/www.conf`文件。
|
||||
|
||||
# nano /etc/php-fpm.d/www.conf
|
||||
|
||||
然后在文件中增加下面的语句:
|
||||
|
||||
user = lighttpd
|
||||
group = lighttpd
|
||||
|
||||
做完这些,我们保存并退出文本编辑器。然后从`/etc/lighttpd/modules.conf`设置文件中添加 FastCGI 模块。
|
||||
|
||||
# nano /etc/lighttpd/modules.conf
|
||||
|
||||
然后,去掉下面语句前面的`#`来取消对它的注释。
|
||||
|
||||
include "conf.d/fastcgi.conf"
|
||||
|
||||
最后我们还需在文本编辑器设置 FastCGI 的设置文件。
|
||||
|
||||
# nano /etc/lighttpd/conf.d/fastcgi.conf
|
||||
|
||||
在文件尾部添加以下代码:
|
||||
|
||||
fastcgi.server += ( ".php" =>
|
||||
((
|
||||
"host" => "127.0.0.1",
|
||||
"port" => "9000",
|
||||
"broken-scriptfilename" => "enable"
|
||||
))
|
||||
)
|
||||
|
||||
在编辑完成后保存并退出文本编辑器即可。
|
||||
|
||||
#### 使用 Ubuntu 15.04
|
||||
|
||||
如需启用 Lighttpd 的 FastCGI,只需执行下列代码:
|
||||
|
||||
# lighttpd-enable-mod fastcgi
|
||||
|
||||
Enabling fastcgi: ok
|
||||
Run /etc/init.d/lighttpd force-reload to enable changes
|
||||
|
||||
# lighttpd-enable-mod fastcgi-php
|
||||
|
||||
Enabling fastcgi-php: ok
|
||||
Run `/etc/init.d/lighttpd` force-reload to enable changes
|
||||
|
||||
然后,执行下列命令来重启 Lighttpd。
|
||||
|
||||
# systemctl force-reload lighttpd
|
||||
|
||||
### 检测 PHP 工作状态
|
||||
|
||||
如需检测 PHP 是否按预期工作,我们需在 Lighttpd 的 webroot 目录下新建一个 php 文件。本教程中,在 Ubuntu 下 /var/www/html 目录,CentOS 下 /src/www/htdocs 目录下使用文本编辑器创建并打开 info.php。
|
||||
|
||||
**使用 CentOS 7**
|
||||
|
||||
# nano /var/www/info.php
|
||||
|
||||
**使用 Ubuntu 15.04**
|
||||
|
||||
# nano /srv/www/htdocs/info.php
|
||||
|
||||
然后只需将下面的语句添加到文件里即可。
|
||||
|
||||
<?php phpinfo(); ?>
|
||||
|
||||
在编辑完成后保存并推出文本编辑器即可。
|
||||
|
||||
现在,我们需根据路径 [http://lighttpd.linoxide.com/info.php](http://lighttpd.linoxide.com/info.php) 下的 info.php 文件的 IP 地址或域名,来让我们的网页浏览器指向系统上运行的 Lighttpd。如果一切都按照以上说明进行,我们将看到如下图所示的 PHP 页面信息。
|
||||
|
||||
![phpinfo lighttpd](http://blog.linoxide.com/wp-content/uploads/2016/02/phpinfo-lighttpd.png)
|
||||
|
||||
### 总结
|
||||
|
||||
至此,我们已经在 CentOS 7 和 Ubuntu 15.04 Linux 发行版上成功安装了轻巧快捷并且安全的 Lighttpd Web 服务器。现在,我们已经可以上传网站文件到网站根目录、配置虚拟主机、启用 SSL、连接数据库,在我们的 Lighttpd Web 服务器上运行 Web 应用等功能了。 如果你有任何疑问,建议或反馈请在下面的评论区中写下来以让我们更好的改良 Lighttpd。谢谢!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linoxide.com/linux-how-to/setup-lighttpd-web-server-ubuntu-15-04-centos-7/
|
||||
|
||||
作者:[Arun Pyasi][a]
|
||||
译者:[HaohongWANG](https://github.com/HaohongWANG)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linoxide.com/author/arunp/
|
@ -3,9 +3,9 @@
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/02/Linux-cloud-services.jpg)
|
||||
|
||||
云存储服务 Copy 即将关闭,我们 Linux 用户是时候该寻找其他优秀的** Copy 之外的 Linux 云存储服务**。
|
||||
云存储服务 Copy 已经关闭,我们 Linux 用户是时候该寻找其他优秀的** Copy 之外的 Linux 云存储服务**。
|
||||
|
||||
全部文件将会在 2016年5月1号 被删除。如果你是 Copy 的用户,你应该保存你的文件并将它们移至其他地方。
|
||||
全部文件会在 2016年5月1号 被删除。如果你是 Copy 的用户,你应该保存你的文件并将它们移至其他地方。
|
||||
|
||||
在过去的两年里,Copy 已经成为了我最喜爱的云存储。它为我提供了大量的免费空间并且带有桌面平台的原生应用程序,包括 Linux 和移动平台如 iOS 和 Android。
|
||||
|
||||
@ -13,16 +13,16 @@
|
||||
|
||||
当我从 Copy.com 看到它即将关闭的消息,我的担忧成真了。事实上,Copy 并不孤独。它的母公司 [Barracuda Networks](https://www.barracuda.com/)正经历一段困难时期并且已经[雇佣 Morgan Stanely 寻找 合适的卖家](http://www.bloomberg.com/news/articles/2016-02-01/barracuda-networks-said-to-work-with-morgan-stanley-to-seek-sale)(s)
|
||||
|
||||
无论什么理由,我们所知道的是 Copy 将会成为历史,我们需要寻找相似的**优秀的 Linux 云服务**。我之所以强调 Linux 是因为其他流行的云存储服务,如[微软的OneDrive](https://onedrive.live.com/about/en-us/) 和 [Google Drive](https://www.google.com/drive/) 都没有提供本地 Linux 客户端。这是微软预计的事情,但是谷歌对 Linux 的冷漠令人震惊。
|
||||
无论什么理由,我们所知道的是 Copy 将会成为历史,我们需要寻找相似的**优秀的 Linux 云服务**。我之所以强调 Linux 是因为其他流行的云存储服务,如[微软的 OneDrive](https://onedrive.live.com/about/en-us/) 和 [Google Drive](https://www.google.com/drive/) 都没有提供本地 Linux 客户端。微软并没有出乎我们的预料,但是[谷歌对 Linux 的冷漠][1]令人震惊。
|
||||
|
||||
## Linux 下 Copy 的最佳替代者
|
||||
|
||||
现在,作为一个 Linux 存储,在云存储中你需要什么?让我们猜猜:
|
||||
什么样的云服务才适合作为 Linux 下的存储服务?让我们猜猜:
|
||||
|
||||
- 大量的免费空间。毕竟,个人用户无法每月支付巨额款项。
|
||||
- 原生的 Linux 客户端。因此你能够使用提供的服务,方便地同步文件,而不用做一些特殊的调整或者定时执行脚本。
|
||||
- 其他桌面系统的客户端,比如 Windows 和 OS X。便携性是必要的,并且同步设备间的文件是一种很好的缓解。
|
||||
- Android 和 iOS 的移动应用程序。在今天的现代世界里,你需要连接所有设备。
|
||||
- 大量的免费空间。毕竟,个人用户无法支付每月的巨额款项。
|
||||
- 原生的 Linux 客户端。以便你能够方便的在服务器之间同步文件,而不用做一些特殊的调整或者定时执行脚本。
|
||||
- 其他桌面系统的客户端,比如 Windows 和 OS X。移动性是必要的,并且同步设备间的文件也很有必要。
|
||||
- 基于 Android 和 iOS 的移动应用程序。在今天的现代世界里,你需要连接所有设备。
|
||||
|
||||
我不将自托管的云服务计算在内,比如 OwnCloud 或 [Seafile](https://www.seafile.com/en/home/) ,因为它们需要自己建立和运行一个服务器。这不适合所有想要类似 Copy 的云服务的家庭用户。
|
||||
|
||||
@ -74,7 +74,7 @@ Hubic 拥有一些不错的功能。除了简单的用户界面、文件共享
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/02/pCloud-Linux.jpeg)
|
||||
|
||||
pCloud 是另一款欧洲的发行软件,但这一次从瑞士横跨法国边境。专注于加密和安全,pCloud 为每一个注册者提供 10 GB 的免费存储空间。你可以通过邀请好友、在社交媒体上分享链接等方式将空间增加至 20 GB。
|
||||
pCloud 是另一款欧洲的发行软件,但这一次跨过了法国边境,它来自瑞士。专注于加密和安全,pCloud 为每一个注册者提供 10 GB 的免费存储空间。你可以通过邀请好友、在社交媒体上分享链接等方式将空间增加至 20 GB。
|
||||
|
||||
它拥有云服务的所有标准特性,例如文件共享、同步、选择性同步等等。pCloud 也有跨平台原生客户端,当然包括 Linux。
|
||||
|
||||
@ -128,8 +128,9 @@ via: http://itsfoss.com/cloud-services-linux/
|
||||
|
||||
作者:[ABHISHEK][a]
|
||||
译者:[cposture](https://github.com/cposture)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://itsfoss.com/author/abhishek/
|
||||
[1]:https://itsfoss.com/google-hates-desktop-linux/
|
@ -0,0 +1,37 @@
|
||||
构建在开源之上的商业软件市场持续成长
|
||||
=====================================================================
|
||||
|
||||
![](https://www.linux.com/images/stories/41373/Structure-event-photo.jpg)
|
||||
|
||||
*与会者在 Structure 上听取演讲,Structure Data 2016 也将在 UCSF Mission Bay 会议中心举办。图片来源:Structure Events。*
|
||||
|
||||
如今真的很难低估开源项目对于企业软件市场的影响;开源软件的集成如此快速地形成了业界常态,我们没能捕捉到转折点也情有可原。
|
||||
|
||||
举个例子,Hadoop,改变的不止是数据分析界,它引领了新一代数据公司,它们围绕开源项目创造自己的软件,按需调整和支持那些代码,更像红帽在上世纪 90 年代和本世纪早期拥抱 Linux 那样。软件越来越多地通过公有云交付,而不是运行在购买者自己的服务器,拥有了令人惊奇的操作灵活性,但同时也带来了一些关于授权、支持以及价格之类的新问题。
|
||||
|
||||
我们多年来持续追踪这个趋势,这些话题充斥了我们的 Structure Data 会议,而今年的 Structure Data 2016 也不例外。三家围绕 Hadoop 最重要的大数据公司——Hortonworks、Cloudera 和 MapR ——的 CEO 们将会共同讨论它们是如何销售他们围绕开源项目的企业软件和服务,获利的同时回报社区项目。
|
||||
|
||||
以前在企业软件上获利是很容易的事情。一个客户购买了之后,企业供应商的一系列软件就变成了收银机,从维护合同和阶段性升级中获得近乎终生的收入,软件也越来越难以被替代,因为它已经成为了客户的业务核心。客户抱怨这种绑定,但如果它们想提高工作队伍的生产力也确实没有多少选择。
|
||||
|
||||
而现在的情况不再是这样了。尽管无数的公司还陷于在他们的基础设施上运行至关重要的巨型软件包,新的项目被部署到使用开源技术的云服务器上。这让升级功能不再需要去掉大量软件包再重新安装别的,同时也让公司按需付费,而不是为一堆永远用不到的特性买单。
|
||||
|
||||
有很多客户想要利用开源项目的优势,而又不想建立和支持一支工程师队伍来调整那些开源项目以满足自己的需求。这些客户愿意为开源项目和在这之上的专有特性之间的差异付费。
|
||||
|
||||
这对于基础设施相关的软件来说格外正确。当然,你的客户们可以自己对项目进行调整,比如 Hadoop,Spark 或 Node.js,但付费可以帮助他们自定义地打包部署如今这些重要的开源技术,而不用自己干这些活儿。只需看看 Structure Data 2016 的发言者就明白了,比如 Confluent(Kafka),Databricks(Spark),以及 Cloudera-Hortonworks-MapR(Hadoop)三人组。
|
||||
|
||||
当然还有一个值得提到的是在出错的时候有个供应商给你背锅。如果你的工程师弄糟了开源项目的实现,那你只能怪你自己了。但是如果你和一个愿意提供服务级品质、能确保性能和正常运行时间指标的公司签订了合同,你实际上就是为得到支持、指导,以及有人背锅而买单。
|
||||
|
||||
构建在开源之上的商业软件市场的持续成长是我们在 Structure Data 上追踪多年的内容,如果这个话题正合你意,我们鼓励你加入我们,在旧金山,3 月 9 日和 10 日。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/enterprise/cloud-computing/889564-the-evolving-market-for-commercial-software-built-on-open-source-
|
||||
|
||||
作者:[Tom Krazit][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/community/forums/person/70513
|
@ -0,0 +1,86 @@
|
||||
Linux 下五个顶级的开源命令行 Shell
|
||||
===============================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/terminal_blue_smoke_command_line_0.jpg?itok=u2mRRqOa)
|
||||
|
||||
这个世界上有两种 Linux 用户:敢于冒险的和态度谨慎的。
|
||||
|
||||
其中一类用户总是本能的去尝试任何能够戳中其痛点的新选择。他们尝试过不计其数的窗口管理器、系统发行版和几乎所有能找到的桌面插件。
|
||||
|
||||
另一类用户找到他们喜欢的东西后,会一直使用下去。他们往往喜欢所使用的系统发行版的默认配置。最先熟练掌握的文本编辑器会成为他们最钟爱的那一个。
|
||||
|
||||
作为一个使用桌面版和服务器版十五年之久的 Linux 用户,比起第一类来,我无疑属于第二类用户。我更倾向于使用现成的东西,如此一来,很多时候我就可以通过文档和示例方便地找到我所需要的使用案例。如果我决定选择使用非费标准的东西,这个切换过程一定会基于细致的研究,并且前提是来自好基友的大力推荐。
|
||||
|
||||
但这并不意味着我不喜欢尝试新事物并且查漏补失。所以最近一段时间,在我不假思索的使用了 bash shell 多年之后,决定尝试一下另外四个 shell 工具:ksh、tcsh、zsh 和 fish。这四个 shell 都可以通过我所用的 Fedora 系统的默认库轻松安装,并且他们可能已经内置在你所使用的系统发行版当中了。
|
||||
|
||||
这里对它们每个选择都稍作介绍,并且阐述下它适合做为你的下一个 Linux 命令行解释器的原因所在。
|
||||
|
||||
### bash
|
||||
|
||||
首先,我们回顾一下最为熟悉的一个。 [GNU Bash][1],又名 Bourne Again Shell,它是我这些年使用过的众多 Linux 发行版的默认选择。它最初发布于 1989 年,并且轻松成长为 Linux 世界中使用最广泛的 shell,甚至常见于其他一些类 Unix 系统当中。
|
||||
|
||||
Bash 是一个广受赞誉的 shell,当你通过互联网寻找各种事情解决方法所需的文档时,总能够无一例外的发现这些文档都默认你使用的是 bash shell。但 bash 也有一些缺点存在,如果你写过 Bash 脚本就会发现我们写的代码总是得比真正所需要的多那么几行。这并不是说有什么事情是它做不到的,而是说它读写起来并不总是那么直观,至少是不够优雅。
|
||||
|
||||
如上所述,基于其巨大的安装量,并且考虑到各类专业和非专业系统管理员已经适应了它的使用方式和独特之处,至少在将来一段时间内,bash 或许会一直存在。
|
||||
|
||||
### ksh
|
||||
|
||||
[KornShell][4],或许你对这个名字并不熟悉,但是你一定知道它的调用命令 ksh。这个替代性的 shell 于 80 年代起源于贝尔实验室,由 David Korn 所写。虽然最初是一个专有软件,但是后期版本是在 [Eclipse Public 许可][5]下发布的。
|
||||
|
||||
ksh 的拥趸们列出了他们觉得其优越的诸多理由,包括更好的循环语法,清晰的管道退出代码,处理重复命令和关联数组的更简单的方式。它能够模拟 vi 和 emacs 的许多行为,所以如果你是一个重度文本编辑器患者,它值得你一试。最后,我发现它虽然在高级脚本方面拥有不同的体验,但在基本输入方面与 bash 如出一辙。
|
||||
|
||||
### tcsh
|
||||
|
||||
[tcsh][6] 衍生于 csh(Berkely Unix C shell),并且可以追溯到早期的 Unix 和计算机时代开始。
|
||||
|
||||
tcsh 最大的卖点在于它的脚本语言,对于熟悉 C 语言编程的人来说,看起来会非常亲切。tcsh 的脚本编写有人喜欢,有人憎恶。但是它也有其他的技术特色,包括可以为 aliases 添加参数,各种可能迎合你偏好的默认行为,包括 tab 自动完成和将 tab 完成的工作记录下来以备后查。
|
||||
|
||||
tcsh 以 [BSD 许可][7]发布。
|
||||
|
||||
### zsh
|
||||
|
||||
[zsh][8] 是另外一个与 bash 和 ksh 有着相似之处的 shell。诞生于 90 年代初,zsh 支持众多有用的新技术,包括拼写纠正、主题化、可命名的目录快捷键,在多个终端中共享同一个命令历史信息和各种相对于原来的 bash 的轻微调整。
|
||||
|
||||
虽然部分需要遵照 GPL 许可,但 zsh 的代码和二进制文件可以在一个类似 MIT 许可证的许可下进行分发; 你可以在 [actual license][9] 中查看细节。
|
||||
|
||||
### fish
|
||||
|
||||
之前我访问了 [fish][10] 的主页,当看到 “好了,这是一个为 90 后而生的命令行 shell” 这条略带调侃的介绍时(fish 完成于 2005 年),我就意识到我会爱上这个交互友好的 shell 的。
|
||||
|
||||
fish 的作者提供了若干切换过来的理由,这些理由有点小幽默并且能戳中笑点,不过还真是那么回事。这些特性包括自动建议(“注意, Netscape Navigator 4.0 来了”,LCTT 译注:NN4 是一个重要版本。),支持“惊人”的 256 色 VGA 调色,不过也有真正有用的特性,包括根据你机器上的 man 页面自动补全命令,清除脚本和基于 web 界面的配置方式。
|
||||
|
||||
fish 的许可主要基于 GPLv2,但有些部分是在其他许可下的。你可以查看资源库来了解[完整信息][11]。
|
||||
|
||||
***
|
||||
|
||||
如果你想要寻找关于每个选择确切不同之处的详尽纲要,[这个网站][12]应该可以帮到你。
|
||||
|
||||
我的立场到底是怎样的呢?好吧,最终我应该还是会重新投入 bash 的怀抱,因为对于大多数时间都在使用命令行交互的人来说,切换过程对于编写高级的脚本能带来的好处微乎其微,并且我已经习惯于使用 bash 了。
|
||||
|
||||
但是我很庆幸做出了敞开大门并且尝试新选择的决定。我知道门外还有许许多多其他的东西。你尝试过哪些 shell,更中意哪一个?请在评论里告诉我们。
|
||||
|
||||
---
|
||||
|
||||
via: https://opensource.com/business/16/3/top-linux-shells
|
||||
|
||||
作者:[Jason Baker][a]
|
||||
译者:[mr-ping](https://github.com/mr-ping)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/jason-baker
|
||||
|
||||
[1]: https://www.gnu.org/software/bash/
|
||||
[2]: http://mywiki.wooledge.org/BashPitfalls
|
||||
[3]: http://www.gnu.org/licenses/gpl.html
|
||||
[4]: http://www.kornshell.org/
|
||||
[5]: https://www.eclipse.org/legal/epl-v10.html
|
||||
[6]: http://www.tcsh.org/Welcome
|
||||
[7]: https://en.wikipedia.org/wiki/BSD_licenses
|
||||
[8]: http://www.zsh.org/
|
||||
[9]: https://sourceforge.net/p/zsh/code/ci/master/tree/LICENCE
|
||||
[10]: https://fishshell.com/
|
||||
[11]: https://github.com/fish-shell/fish-shell/blob/master/COPYING
|
||||
[12]: http://hyperpolyglot.org/unix-shells
|
||||
|
@ -0,0 +1,284 @@
|
||||
用 Python、 RabbitMQ 和 Nameko 实现微服务
|
||||
==============================================
|
||||
|
||||
>"微服务是一股新浪潮" - 现如今,将项目拆分成多个独立的、可扩展的服务是保障代码演变的最好选择。在 Python 的世界里,有个叫做 “Nameko” 的框架,它将微服务的实现变得简单并且强大。
|
||||
|
||||
|
||||
### 微服务
|
||||
|
||||
> 在最近的几年里,“微服务架构”如雨后春笋般涌现。它用于描述一种特定的软件应用设计方式,这种方式使得应用可以由多个独立部署的服务以服务套件的形式组成。 - M. Fowler
|
||||
|
||||
推荐各位读一下 [Fowler 的文章][1] 以理解它背后的原理。
|
||||
|
||||
#### 好吧,那它究竟意味着什么呢?
|
||||
|
||||
简单来说,**微服务架构**可以将你的系统拆分成多个负责不同任务的小的(单一上下文内)功能块(responsibilities blocks),它们彼此互无感知,各自只提供用于通讯的通用指向(common point)。这个指向通常是已经将通讯协议和接口定义好的消息队列。
|
||||
|
||||
#### 这里给大家提供一个真实案例
|
||||
|
||||
> 案例的代码可以通过 github: <http://github.com/rochacbruno/nameko-example> 访问,查看 service 和 api 文件夹可以获取更多信息。
|
||||
|
||||
想象一下,你有一个 REST API ,这个 API 有一个端点(LCTT 译注:REST 风格的 API 可以有多个端点用于处理对同一资源的不同类型的请求)用来接受数据,并且你需要将接收到的数据进行一些运算工作。那么相比阻塞接口调用者的请求来说,异步实现此接口是一个更好的选择。你可以先给用户返回一个 "OK - 你的请求稍后会处理" 的状态,然后在后台任务中完成运算。
|
||||
|
||||
同样,如果你想要在不阻塞主进程的前提下,在计算完成后发送一封提醒邮件,那么将“邮件发送”委托给其他服务去做会更好一些。
|
||||
|
||||
|
||||
#### 场景描述
|
||||
|
||||
![](http://brunorocha.org/static/media/microservices/micro_services.png)
|
||||
|
||||
|
||||
### 用代码说话
|
||||
|
||||
让我们将系统创建起来,在实践中理解它:
|
||||
|
||||
#### 环境
|
||||
|
||||
我们需要的环境:
|
||||
|
||||
- 运行良好的 RabbitMQ(LCTT 译注:[RabbitMQ][2] 是一个流行的消息队列实现)
|
||||
- 由 VirtualEnv 提供的 Services 虚拟环境
|
||||
- 由 VirtualEnv 提供的 API 虚拟环境
|
||||
|
||||
#### Rabbit
|
||||
|
||||
在开发环境中使用 RabbitMQ 最简单的方式就是运行其官方的 docker 容器。在你已经拥有 Docker 的情况下,运行:
|
||||
|
||||
```
|
||||
docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
|
||||
```
|
||||
|
||||
在浏览器中访问 <http://localhost:15672> ,如果能够使用 guest:guest 验证信息登录 RabbitMQ 的控制面板,说明它已经在你的开发环境中运行起来了。
|
||||
|
||||
![](http://brunorocha.org/static/media/microservices/RabbitMQManagement.png)
|
||||
|
||||
#### 服务环境
|
||||
|
||||
现在让我们创建微服务来满足我们的任务需要。其中一个服务用来执行计算任务,另一个用来发送邮件。按以下步骤执行:
|
||||
|
||||
在 Shell 中创建项目的根目录
|
||||
|
||||
```
|
||||
$ mkdir myproject
|
||||
$ cd myproject
|
||||
```
|
||||
|
||||
用 virtualenv 工具创建并且激活一个虚拟环境(你也可以使用virtualenv-wrapper)
|
||||
|
||||
```
|
||||
$ virtualenv service_env
|
||||
$ source service_env/bin/activate
|
||||
```
|
||||
|
||||
安装 nameko 框架和 yagmail
|
||||
|
||||
```
|
||||
(service_env)$ pip install nameko
|
||||
(service_env)$ pip install yagmail
|
||||
```
|
||||
|
||||
#### 服务的代码
|
||||
|
||||
现在我们已经准备好了 virtualenv 所提供的虚拟环境(可以想象成我们的服务是运行在一个独立服务器上的,而我们的 API 运行在另一个服务器上),接下来让我们编码,实现 nameko 的 RPC 服务。
|
||||
|
||||
我们会将这两个服务放在同一个 python 模块中,当然如果你乐意,也可以把它们放在单独的模块里并且当成不同的服务运行:
|
||||
|
||||
在名为 `service.py` 的文件中
|
||||
|
||||
```python
|
||||
import yagmail
|
||||
from nameko.rpc import rpc, RpcProxy
|
||||
|
||||
|
||||
class Mail(object):
|
||||
name = "mail"
|
||||
|
||||
@rpc
|
||||
def send(self, to, subject, contents):
|
||||
yag = yagmail.SMTP('myname@gmail.com', 'mypassword')
|
||||
# 以上的验证信息请从安全的地方进行读取
|
||||
# 贴士: 可以去看看 Dynaconf 设置模块
|
||||
yag.send(to=to.encode('utf-8),
|
||||
subject=subject.encode('utf-8),
|
||||
contents=[contents.encode('utf-8)])
|
||||
|
||||
|
||||
class Compute(object):
|
||||
name = "compute"
|
||||
mail = RpcProxy('mail')
|
||||
|
||||
@rpc
|
||||
def compute(self, operation, value, other, email):
|
||||
operations = {'sum': lambda x, y: int(x) + int(y),
|
||||
'mul': lambda x, y: int(x) * int(y),
|
||||
'div': lambda x, y: int(x) / int(y),
|
||||
'sub': lambda x, y: int(x) - int(y)}
|
||||
try:
|
||||
result = operations[operation](value, other)
|
||||
except Exception as e:
|
||||
self.mail.send.async(email, "An error occurred", str(e))
|
||||
raise
|
||||
else:
|
||||
self.mail.send.async(
|
||||
email,
|
||||
"Your operation is complete!",
|
||||
"The result is: %s" % result
|
||||
)
|
||||
return result
|
||||
```
|
||||
|
||||
现在我们已经用以上代码定义好了两个服务,下面让我们将 Nameko RPC service 运行起来。
|
||||
|
||||
> 注意:我们会在控制台中启动并运行它。但在生产环境中,建议大家使用 supervisord 替代控制台命令。
|
||||
|
||||
在 Shell 中启动并运行服务
|
||||
|
||||
```
|
||||
(service_env)$ nameko run service --broker amqp://guest:guest@localhost
|
||||
starting services: mail, compute
|
||||
Connected to amqp://guest:**@127.0.0.1:5672//
|
||||
Connected to amqp://guest:**@127.0.0.1:5672//
|
||||
```
|
||||
|
||||
|
||||
#### 测试
|
||||
|
||||
在另外一个 Shell 中(使用相同的虚拟环境),用 nameko shell 进行测试:
|
||||
|
||||
```
|
||||
(service_env)$ nameko shell --broker amqp://guest:guest@localhost
|
||||
Nameko Python 2.7.9 (default, Apr 2 2015, 15:33:21)
|
||||
[GCC 4.9.2] shell on linux2
|
||||
Broker: amqp://guest:guest@localhost
|
||||
>>>
|
||||
```
|
||||
|
||||
现在你已经处在 RPC 客户端中了,Shell 的测试工作是通过 n.rpc 对象来进行的,它的使用方法如下:
|
||||
|
||||
```
|
||||
>>> n.rpc.mail.send("name@email.com", "testing", "Just testing")
|
||||
```
|
||||
|
||||
上边的代码会发送一封邮件,我们同样可以调用计算服务对其进行测试。需要注意的是,此测试还会附带进行异步的邮件发送。
|
||||
|
||||
```
|
||||
>>> n.rpc.compute.compute('sum', 30, 10, "name@email.com")
|
||||
40
|
||||
>>> n.rpc.compute.compute('sub', 30, 10, "name@email.com")
|
||||
20
|
||||
>>> n.rpc.compute.compute('mul', 30, 10, "name@email.com")
|
||||
300
|
||||
>>> n.rpc.compute.compute('div', 30, 10, "name@email.com")
|
||||
3
|
||||
```
|
||||
|
||||
### 在 API 中调用微服务
|
||||
|
||||
在另外一个 Shell 中(甚至可以是另外一台服务器上),准备好 API 环境。
|
||||
|
||||
用 virtualenv 工具创建并且激活一个虚拟环境(你也可以使用 virtualenv-wrapper)
|
||||
|
||||
```
|
||||
$ virtualenv api_env
|
||||
$ source api_env/bin/activate
|
||||
```
|
||||
|
||||
安装 Nameko、 Flask 和 Flasgger
|
||||
|
||||
```
|
||||
(api_env)$ pip install nameko
|
||||
(api_env)$ pip install flask
|
||||
(api_env)$ pip install flasgger
|
||||
```
|
||||
|
||||
>注意: 在 API 中并不需要 yagmail ,因为在这里,处理邮件是服务的职责
|
||||
|
||||
创建含有以下内容的 `api.py` 文件:
|
||||
|
||||
```python
|
||||
from flask import Flask, request
|
||||
from flasgger import Swagger
|
||||
from nameko.standalone.rpc import ClusterRpcProxy
|
||||
|
||||
app = Flask(__name__)
|
||||
Swagger(app)
|
||||
CONFIG = {'AMQP_URI': "amqp://guest:guest@localhost"}
|
||||
|
||||
|
||||
@app.route('/compute', methods=['POST'])
|
||||
def compute():
|
||||
"""
|
||||
Micro Service Based Compute and Mail API
|
||||
This API is made with Flask, Flasgger and Nameko
|
||||
---
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
id: data
|
||||
properties:
|
||||
operation:
|
||||
type: string
|
||||
enum:
|
||||
- sum
|
||||
- mul
|
||||
- sub
|
||||
- div
|
||||
email:
|
||||
type: string
|
||||
value:
|
||||
type: integer
|
||||
other:
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: Please wait the calculation, you'll receive an email with results
|
||||
"""
|
||||
operation = request.json.get('operation')
|
||||
value = request.json.get('value')
|
||||
other = request.json.get('other')
|
||||
email = request.json.get('email')
|
||||
msg = "Please wait the calculation, you'll receive an email with results"
|
||||
subject = "API Notification"
|
||||
with ClusterRpcProxy(CONFIG) as rpc:
|
||||
# asynchronously spawning and email notification
|
||||
rpc.mail.send.async(email, subject, msg)
|
||||
# asynchronously spawning the compute task
|
||||
result = rpc.compute.compute.async(operation, value, other, email)
|
||||
return msg, 200
|
||||
|
||||
app.run(debug=True)
|
||||
```
|
||||
|
||||
在其他的 shell 或者服务器上运行此文件
|
||||
|
||||
```
|
||||
(api_env) $ python api.py
|
||||
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
然后访问 <http://localhost:5000/apidocs/index.html> 这个 url,就可以看到 Flasgger 的界面了,利用它可以进行 API 的交互并可以发布任务到队列以供服务进行消费。
|
||||
|
||||
![](http://brunorocha.org/static/media/microservices/Flasgger_API_documentation.png)
|
||||
|
||||
> 注意: 你可以在 shell 中查看到服务的运行日志,打印信息和错误信息。也可以访问 RabbitMQ 控制面板来查看消息在队列中的处理情况。
|
||||
|
||||
Nameko 框架还为我们提供了很多高级特性,你可以从 <https://nameko.readthedocs.org/en/stable/> 获取更多的信息。
|
||||
|
||||
别光看了,撸起袖子来,实现微服务!
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://brunorocha.org/python/microservices-with-python-rabbitmq-and-nameko.html
|
||||
|
||||
作者: [Bruno Rocha][a]
|
||||
译者: [mr-ping](http://www.mr-ping.com)
|
||||
校对: [wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://facebook.com/rochacbruno
|
||||
[1]:http://martinfowler.com/articles/microservices.html
|
||||
[2]:http://rabbitmq.mr-ping.com/description.html
|
@ -0,0 +1,107 @@
|
||||
如何使用 Awk 打印文件中的字段和列
|
||||
===================================================
|
||||
|
||||
在 [Linux Awk 命令系列介绍][1] 的这部分,我们来看一下 awk 最重要的功能之一,字段编辑。
|
||||
|
||||
首先我们要知道 Awk 会自动把输入的行切分为字段,字段可以定义为是一些字符集,这些字符集和其它字段被内部字段分隔符分离。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/04/Awk-Print-Fields-and-Columns.png)
|
||||
>Awk 输出字段和列
|
||||
|
||||
如果你熟悉 Unix/Linux 或者懂得 [bash shell 编程][2],那么你也应该知道内部字段分隔符(IFS)变量。Awk 默认的 IFS 是 tab 和空格。
|
||||
|
||||
Awk 字段切分的工作原理如下:当获得一行输入时,根据定义的 IFS,第一个字符集是字段一,用 $1 表示,第二个字符集是字段二,用 $2 表示,第三个字符集是字段三,用 $3 表示,以此类推直到最后一个字符集。
|
||||
|
||||
为了更好的理解 Awk 的字段编辑,让我们来看看下面的例子:
|
||||
|
||||
**事例 1:**: 我创建了一个名为 tecmintinfo.txt 的文件。
|
||||
|
||||
```
|
||||
# vi tecmintinfo.txt
|
||||
# cat tecmintinfo.txt
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/04/Create-File-in-Linux.png)
|
||||
>在 Linux 中创建文件
|
||||
|
||||
然后在命令行中使用以下命令打印 tecmintinfo.txt 文件中的第一、第二和第三个字段。
|
||||
|
||||
```
|
||||
$ awk '//{print $1 $2 $3 }' tecmintinfo.txt
|
||||
TecMint.comisthe
|
||||
```
|
||||
从上面的输出中你可以看到,三个字段中的第一个是按照定义的 IFS,也就是空格,打印的。
|
||||
|
||||
- 字段一 “TecMint.com” 使用 $1 访问。
|
||||
- 字段二 “is” 通过 $2 访问。
|
||||
- 字段三 “the” 通过 $3 访问。
|
||||
|
||||
如果你注意打印的输出,可以看到字段值之间并没有分隔开,这是 print 默认的方式。
|
||||
|
||||
为了在字段值之间加入空格,你需要像下面这样添加(,)分隔符:
|
||||
|
||||
```
|
||||
$ awk '//{print $1, $2, $3; }' tecmintinfo.txt
|
||||
|
||||
TecMint.com is the
|
||||
```
|
||||
|
||||
很重要而且必须牢记的一点是,Awk 中 ($) 的使用和在 shell 脚本中不一样。
|
||||
|
||||
在 shell 脚本中 ($) 用于获取变量的值,而在 Awk 中 ($) 只用于获取一个字段的内容,而不能用于获取变量的值。
|
||||
|
||||
**事例2**: 让我们再看一个使用多行文件 my_shoping.list 的例子。
|
||||
|
||||
```
|
||||
No Item_Name Unit_Price Quantity Price
|
||||
1 Mouse #20,000 1 #20,000
|
||||
2 Monitor #500,000 1 #500,000
|
||||
3 RAM_Chips #150,000 2 #300,000
|
||||
4 Ethernet_Cables #30,000 4 #120,000
|
||||
```
|
||||
|
||||
假设你只想打印购物清单中每个物品的 Unit_Price,你需要允许下面的命令:
|
||||
|
||||
```
|
||||
$ awk '//{print $2, $3 }' my_shopping.txt
|
||||
|
||||
Item_Name Unit_Price
|
||||
Mouse #20,000
|
||||
Monitor #500,000
|
||||
RAM_Chips #150,000
|
||||
Ethernet_Cables #30,000
|
||||
```
|
||||
|
||||
Awk 也有一个 printf 命令,它能帮助你用更好的方式格式化输出,正如你可以看到上面的输出并不清晰。
|
||||
|
||||
使用 printf 格式化输出 Item_Name 和 Unit_Price:
|
||||
|
||||
```
|
||||
$ awk '//{printf "%-10s %s\n",$2, $3 }' my_shopping.txt
|
||||
|
||||
Item_Name Unit_Price
|
||||
Mouse #20,000
|
||||
Monitor #500,000
|
||||
RAM_Chips #150,000
|
||||
Ethernet_Cables #30,000
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
使用 Awk 进行文本和字符串过滤时字段编辑功能非常重要,它能帮助你从列表中获取列的特定数据。同时需要记住 Awk 中 ($) 操作符和 shell 脚本中不一样。
|
||||
|
||||
我希望这篇文章能对你有所帮助,如果你需要获取其它信息或者有任何疑问,都可以在下面的评论框中告诉我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/awk-print-fields-columns-with-space-separator/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[ictlyh](https://github.com/ictlyh)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: http://www.tecmint.com/tag/awk-command/
|
||||
[2]: http://www.tecmint.com/category/bash-shell/
|
@ -0,0 +1,45 @@
|
||||
Cassandra 和 Spark 数据处理一窥
|
||||
==============================================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/osdc_520x292_opendata_0613mm.png?itok=mzC0Tb28)
|
||||
|
||||
Apache Cassandra 数据库近来引起了很多的兴趣,这主要源于现代云端软件对于可用性及性能方面的要求。
|
||||
|
||||
那么,Apache Cassandra 是什么?它是一种为高可用性及线性可扩展性优化的分布式的联机交易处理 (OLTP) 数据库。具体说到 Cassandra 的用途时,可以想想你希望贴近用户的系统,比如说让我们的用户进行交互的系统、需要保证实时可用的程序等等,如:产品目录,物联网,医疗系统,以及移动应用。对这些程序而言,下线时间意味着利润降低甚至导致其他更坏的结果。Netfilix 是这个在 2008 年开源的项目的早期使用者,他们对此项目的贡献以及带来的成功让这个项目名声大噪。
|
||||
|
||||
Cassandra 于2010年成为了 Apache 软件基金会的顶级项目,并从此之后就流行起来。现在,只要你有 Cassadra 的相关知识,找工作时就能轻松不少。想想看,NoSQL 语言和开源技术能达到企业级 SQL 技术的高度,真让人觉得十分疯狂而又不可思议的。这引出了一个问题。是什么让它如此的流行?
|
||||
|
||||
因为采用了[亚马逊发表的 Dynamo 论文][1]中率先提出的设计,Cassandra 有能力在大规模的硬件及网络故障时保持实时在线。由于采用了点对点模式,在没有单点故障的情况下,我们能幸免于机架故障甚至全网中断。我们能在不影响用户体验的前提下处理数据中心故障。一个能考虑到故障的分布式系统才是一个没有后顾之忧的分布式系统,因为老实说,故障是迟早会发生的。有了 Cassandra, 我们可以直面残酷的生活并将之融入数据库的结构和功能中。
|
||||
|
||||
我们能猜到你现在在想什么,“但我只有关系数据库相关背景,难道这样的转变不会很困难吗?”这问题的答案介于是和不是之间。使用 Cassandra 建立数据模型对有关系数据库背景的开发者而言是轻车熟路。我们使用表格来建立数据模型,并使用 CQL ( Cassandra 查询语言)来查询数据库。然而,与 SQL 不同的是,Cassandra 支持更加复杂的数据结构,例如嵌套和用户自定义类型。举个例子,当要储存对一个小猫照片的点赞数目时,我们可以将整个数据储存在一个包含照片本身的集合之中从而获得更快的顺序查找而不是建立一个独立的表。这样的表述在 CQL 中十分的自然。在我们照片表中,我们需要记录名字,URL以及给此照片点赞过的人。
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/screen_shot_2016-05-06_at_7.17.33_am-350x198.png)
|
||||
|
||||
在一个高性能系统中,毫秒级处理都能对用户体验和客户维系产生影响。昂贵的 JOIN 操作制约了我们通过增加不可预见的网络调用而扩容的能力。当我们将数据反范式化使其能通过尽可能少的请求就可获取时,我们即可从磁盘空间成本的降低中获益并获得可预期的、高性能应用。我们将反范式化同 Cassandra 一同介绍是因为它提供了很有吸引力的的折衷方案。
|
||||
|
||||
很明显,我们不会局限于对于小猫照片的点赞数量。Canssandra 是一款为高并发写入优化的方案。这使其成为需要时常吞吐数据的大数据应用的理想解决方案。实时应用和物联网方面的应用正在稳步增长,无论是需求还是市场表现,我们也会不断的利用我们收集到的数据来寻求改进技术应用的方式。
|
||||
|
||||
这就引出了我们的下一步,我们已经提到了如何以一种现代的、性价比高的方式储存数据,但我们应该如何获得更多的动力呢?具体而言,当我们收集到了所需的数据,我们应该怎样处理呢?如何才能有效的分析几百 TB 的数据呢?如何才能实时的对我们所收集到的信息进行反馈,并在几秒而不是几小时的时间利作出决策呢?Apache Spark 将给我们答案。
|
||||
|
||||
Spark 是大数据变革中的下一步。 Hadoop 和 MapReduce 都是革命性的产品,它们让大数据界获得了分析所有我们所取得的数据的机会。Spark 对性能的大幅提升及对代码复杂度的大幅降低则将大数据分析提升到了另一个高度。通过 Spark,我们能大批量的处理计算,对流处理进行快速反应,通过机器学习作出决策,并通过图遍历来理解复杂的递归关系。这并非只是为你的客户提供与快捷可靠的应用程序连接(Cassandra 已经提供了这样的功能),这更是能洞悉 Canssandra 所储存的数据,作出更加合理的商业决策并同时更好地满足客户需求。
|
||||
|
||||
你可以看看 [Spark-Cassandra Connector][2] (开源) 并动手试试。若想了解更多关于这两种技术的信息,我们强烈推荐名为 [DataStax Academy][3] 的自学课程
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/life/16/5/basics-cassandra-and-spark-data-processing
|
||||
|
||||
作者:[Jon Haddad][a],[Dani Traphagen][b]
|
||||
译者:[KevinSJ](https://github.com/KevinSJ)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://twitter.com/rustyrazorblade
|
||||
[b]: https://opensource.com/users/dtrapezoid
|
||||
[1]: http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
|
||||
[2]: https://github.com/datastax/spark-cassandra-connector
|
||||
[3]: https://academy.datastax.com/
|
||||
[4]: http://conferences.oreilly.com/oscon/open-source-us/public/schedule/detail/49162
|
||||
[5]: https://twitter.com/dtrapezoid
|
||||
[6]: https://twitter.com/rustyrazorblade
|
@ -0,0 +1,65 @@
|
||||
共享的未来:Pydio 与 ownCloud 的联合
|
||||
=========================================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/BIZ_darwincloud_520x292_0311LL.png?itok=5yWIaEDe)
|
||||
|
||||
*图片来源 : opensource.com*
|
||||
|
||||
开源共享生态圈内容纳了许多各异的项目,它们每一个都给出了自己的解决方案,且每一个都不按套路来。有很多原因导致你选择开源的解决方案,而非 Dropbox、Google Drive、iCloud 或 OneDrive 这些商业的解决方案。这些商业的解决方案虽然能让你不必为如何管理数据担心,但也理所应当的带着种种限制,其中就包括对于原有基础结构的控制和整合不足。
|
||||
|
||||
对于用户而言仍有相当一部分可供选择的文件分享和同步的替代品,其中就包括了 Pydio 和 ownCloud。
|
||||
|
||||
### Pydio
|
||||
|
||||
Pydio (Put your data in orbit 把你的数据放上轨道) 项目由一位作曲家 Charles du Jeu 发起,起初他只是需要一种与乐队成员分享大型音频文件的方法。[Pydio][1] 是一种文件分享与同步的解决方案,综合了多存储后端,设计时还同时考虑了开发者和系统管理员两方面。在世界各地有逾百万的下载量,已被翻译成 27 种语言。
|
||||
|
||||
项目在刚开始的时候便开源了,先是在 [SourceForge][2] 上茁壮的成长,现在已在 [GitHub][3] 上安了家。
|
||||
|
||||
用户界面基于 Google 的 [Material 设计风格][4]。用户可以使用现有的传统文件基础结构或是根据预估的需求部署 Pydio,并通过 web、桌面和移动端应用随时随地地管理自己的东西。对于管理员来说,细粒度的访问权限绝对是配置访问时的利器。
|
||||
|
||||
在 [Pydio 社区][5],你可以找到许多让你增速的资源。Pydio 网站 [对于如何为 Pydio GitHub 仓库贡献][6] 给出了明确的指导方案。[论坛][7]中也包含了开发者板块和社区。
|
||||
|
||||
### ownCloud
|
||||
|
||||
[ownCloud][8] 在世界各地拥有逾 8 百万的用户,它是一个开源、自行管理的文件同步共享技术。同步客户端支持所有主流平台并支持 WebDAV 通过 web 界面实现。ownCloud 拥有简单的使用界面,强大的管理工具,和大规模的共享及协作功能——以满足用户管理数据时的需求。
|
||||
|
||||
ownCloud 的开放式架构是通过 API 和为应用提供平台来实现可扩展性的。迄今已有逾 300 款应用,功能包括处理像日历、联系人、邮件、音乐、密码、笔记等诸多数据类型。ownCloud 由一个数百位贡献者的国际化的社区开发,安全,并且能做到为小到一个树莓派大到好几百万用户的 PB 级存储集群量身定制。
|
||||
|
||||
### 联合共享 (Federated sharing)
|
||||
|
||||
文件共享开始转向团队合作时代,而标准化为合作提供了坚实的土壤。
|
||||
|
||||
联合共享(Federated sharing)——一个由 [OpenCloudMesh][9] 项目提供的新的开放标准,就是在这个方向迈出的一步。先不说别的,在支持该标准的服务器之间分享文件和文件夹,比如说 Pydio 和 ownCloud。
|
||||
|
||||
ownCloud 7 率先引入该标准,这种服务器到服务器的分享方式可以让你挂载远程服务器上共享的文件,实际上就是创建你自己的云上之云。你可以直接为其它支持联合共享的服务器上的用户创建共享链接。
|
||||
|
||||
实现这个新的 API 允许存储解决方案之间更深层次的集成,同时保留了原有平台的安全,控制和特性。
|
||||
|
||||
“交换和共享文件是当下和未来不可或缺的东西。”ownCloud 的创始人 Frank Karlitschek 说道:“正因如此,采用联合和分布的方式而非集中的数据孤岛就显得至关重要。联合共享的设计初衷便是在保证安全和用户隐私的同时追求分享的无缝、至简之道。”
|
||||
|
||||
### 下一步是什么呢?
|
||||
|
||||
正如 OpenCloudMesh 做的那样,将会通过像 Pydio 和 ownCloud 这样的机构和公司,合作推广这一文件共享的新开放标准。ownCloud 9 已经引入联合的服务器之间交换用户列表的功能,让你的用户们在你的服务器上享有和你同样的无缝体验。将来,一个中央地址簿服务(联合的)集合,用以检索其他联合云 ID 的构想可能会把云间合作推向一个新的高度。
|
||||
|
||||
这一举措无疑有助于日益开放的技术社区中的那些成员方便地讨论,开发,并推动“OCM 分享 API”作为一个厂商中立协议。所有领导 OCM 项目的合作伙伴都全心致力于开放 API 的设计原则,并欢迎其他开源的文件分享和同步社区参与并加入其中。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/16/5/sharing-files-pydio-owncloud
|
||||
|
||||
作者:[ben van 't ende][a]
|
||||
译者:[martin2011qi](https://github.com/martin2011qi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/benvantende
|
||||
[1]: https://pydio.com/
|
||||
[2]: https://sourceforge.net/projects/ajaxplorer/
|
||||
[3]: https://github.com/pydio/
|
||||
[4]: https://www.google.com/design/spec/material-design/introduction.html
|
||||
[5]: https://pydio.com/en/community
|
||||
[6]: https://pydio.com/en/community/contribute
|
||||
[7]: https://pydio.com/forum/f
|
||||
[8]: https://owncloud.org/
|
||||
[9]: https://wiki.geant.org/display/OCM/Open+Cloud+Mesh
|
@ -2,7 +2,8 @@
|
||||
========================================
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cloud-ready-main.jpg?itok=gtzJVSq0)
|
||||
>学习如何用 CloudReady 在你的旧电脑上安装 Chrome OS
|
||||
|
||||
*学习如何用 CloudReady 在你的旧电脑上安装 Chrome OS*
|
||||
|
||||
Linux 之年就在眼前。根据[报道][1],Google 在 2016 年第一季度卖出了比苹果卖出的 Macbook 更多的 Chromebook。并且,Chromebook 即将变得更加激动人心。在 Google I/O 大会上,Google 宣布安卓 Google Play 商店将在 6 月中旬来到 Chromebook,这让用户能够在他们的 Chrome OS 设备上运行安卓应用。
|
||||
|
||||
@ -16,33 +17,35 @@ Linux 之年就在眼前。根据[报道][1],Google 在 2016 年第一季度
|
||||
|
||||
在你开始在笔记本上安装 CloudReady 之前,你需要一些准备:
|
||||
|
||||
- 一个容量大于等于 4GB 的 USB 存储设备
|
||||
|
||||
- 一个容量不小于 4GB 的 USB 存储设备
|
||||
- 打开 Chrome 浏览器,到 Google Chrome Store 去安装 [Chromebook Recovery Utility(Chrome 恢复工具)][3]
|
||||
|
||||
- 更改目标机器的 BIOS 设置以便能从 USB 启动
|
||||
|
||||
### 开始
|
||||
|
||||
Neverware 提供两个版本的 CloudReady 镜像:32 位和 64 位。从下载页面[下载][4]合适你硬件的系统版本。
|
||||
|
||||
解压下载的 zip 文件,你会得到一个 chromiumos_image.bin 文件。现在插入 U 盘并打开 Chromebook recovery utility。点击工具右上角的齿轮,选择 erase recovery media(擦除恢复媒介,如图 1)。
|
||||
解压下载的 zip 文件,你会得到一个 chromiumos_image.bin 文件。现在插入 U 盘并打开 Chromebook Recovery Utility。点击工具右上角的齿轮,选择 erase recovery media(擦除恢复媒介,如图 1)。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cloudready-erase.png?itok=1si1QrCL)
|
||||
>图 1:选择 erase recovery media。[image:cloudready-erase]
|
||||
|
||||
*图 1:选择 erase recovery media。[image:cloudready-erase]*
|
||||
|
||||
接下来,选择目标 USB 驱动器并把它格式化。格式化完成后,再次打开右上齿轮,这次选择 use local image(使用本地镜像)。浏览解压的 bin 文件并选中,选好 USB 驱动器,点击继续,然后点击创建按钮(图 2)。它会开始将镜像写入驱动器。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cloudready-create.png?itok=S1FGzRp-)
|
||||
>图 2:创建 CloudReady 镜像。[Image:cloudready-create]
|
||||
|
||||
*图 2:创建 CloudReady 镜像。[Image:cloudready-create]*
|
||||
|
||||
驱动器写好可启动的 CloudReady 之后,插到目标 PC 上并启动。系统启动进 Chromium OS 需要一小段时间。启动之后,你会看到图 3 中的界面。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cloud-ready-install-1.jpg?itok=D6SjlIQ4)
|
||||
>图 3:准备好安装 CloudReady。
|
||||
|
||||
*图 3:准备好安装 CloudReady。*
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/cloud-ready-install-single_crop.jpg?itok=My2rUjYC)
|
||||
>图 4:单系统选项。
|
||||
|
||||
*图 4:单系统选项。*
|
||||
|
||||
到任务栏选择 Install CloudReady(安装 CloudReady)。
|
||||
|
||||
@ -53,7 +56,8 @@ Neverware 提供两个版本的 CloudReady 镜像:32 位和 64 位。从下载
|
||||
按照下一步按钮说明选择安装。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/cloud-ready-install-dual_crop.jpg?itok=Daywck_s)
|
||||
>图 5:双系统选项。
|
||||
|
||||
*图 5:双系统选项。*
|
||||
|
||||
整个过程最多 20 分钟左右,这取决于存储媒介和处理能力。安装完成后,电脑会关闭并重启。
|
||||
|
||||
@ -62,17 +66,20 @@ Neverware 提供两个版本的 CloudReady 镜像:32 位和 64 位。从下载
|
||||
你连上无线网络之后,系统会自动查找更新并提供 Adobe Flash 安装。安装完成后,你会看到 Chromium OS 登录界面。现在你只需登录你的 Gmail 账户,开始使用你的“Chromebook”即可。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cloud-ready-post-install-network.jpg?itok=gSX2fQZS)
|
||||
>图 6:网络设置。
|
||||
|
||||
*图 6:网络设置。*
|
||||
|
||||
### 让 Netflix 正常工作
|
||||
|
||||
如果你想要播放 Netflix 或其它 DRM 保护流媒体站点,你需要做一些额外的工作。转到设置并点击安装 Widevine 插件(图 7)。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/install_widevine.png?itok=bUJaRmyx0)
|
||||
>图 7:安装 Widevine。
|
||||
|
||||
*图 7:安装 Widevine。*
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/user-agent-changer.jpg?itok=5QDCLrZk)
|
||||
>图 8:安装 User Agent Switcher.
|
||||
|
||||
*图 8:安装 User Agent Switcher。*
|
||||
|
||||
现在你需要使用 user agent switcher 这个伎俩(图 8)。
|
||||
|
||||
@ -96,20 +103,20 @@ Indicator Flag: "IE"
|
||||
点击“添加(Add)”。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/spoof-netflix.png?itok=8DEZK4Pl)
|
||||
>图 9:为 CloudReady 创建条目。
|
||||
|
||||
*图 9:为 CloudReady 创建条目。*
|
||||
|
||||
然后,到“permanent spoof list(永久欺骗列表)”选项中将 CloudReady Widevine 添加为 [www.netflix.com](http://www.netflix.com) 的永久 UA 串。
|
||||
|
||||
现在,重启机器,你就可以观看 Netflix 和其它一些服务了。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/turn-your-old-laptop-chromebook
|
||||
|
||||
作者:[SWAPNIL BHARTIYA][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,322 @@
|
||||
在 Ubuntu 16.04 为 Nginx 服务器安装 LEMP 环境(MariaDB,PHP 7 并支持 HTTP 2.0)
|
||||
=====================
|
||||
|
||||
LEMP 是个缩写,代表一组软件包(L:Linux OS,E:Nginx 网络服务器,M:MySQL/MariaDB 数据库和 P:PHP 服务端动态编程语言),它被用来搭建动态的网络应用和网页。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Install-Nginx-with-FastCGI-on-Ubuntu-16.04.png)
|
||||
|
||||
*在 Ubuntu 16.04 安装 Nginx 以及 MariaDB,PHP7 并且支持 HTTP 2.0*
|
||||
|
||||
这篇教程会教你怎么在 Ubuntu 16.04 的服务器上安装 LEMP (Nginx 和 MariaDB 以及 PHP7)。
|
||||
|
||||
**前置准备**
|
||||
|
||||
- [安装 Ubuntu 16.04 服务器版本][1]
|
||||
|
||||
### 步骤 1:安装 Nginx 服务器
|
||||
|
||||
1、Nginx 是一个先进的、资源优化的 Web 服务器程序,用来向因特网上的访客展示网页。我们从 Nginx 服务器的安装开始介绍,使用 [apt 命令][2] 从 Ubuntu 的官方软件仓库中获取 Nginx 程序。
|
||||
|
||||
```
|
||||
$ sudo apt-get install nginx
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Install-Nginx-on-Ubuntu-16.04.png)
|
||||
|
||||
*在 Ubuntu 16.04 安装 Nginx*
|
||||
|
||||
2、 然后输入 [netstat][3] 和 [systemctl][4] 命令,确认 Nginx 进程已经启动并且绑定在 80 端口。
|
||||
|
||||
```
|
||||
$ netstat -tlpn
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-Nginx-Network-Port-Connection.png)
|
||||
|
||||
*检查 Nginx 网络端口连接*
|
||||
|
||||
```
|
||||
$ sudo systemctl status nginx.service
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-Nginx-Service-Status.png)
|
||||
|
||||
*检查 Nginx 服务状态*
|
||||
|
||||
当你确认服务进程已经启动了,你可以打开一个浏览器,使用 HTTP 协议访问你的服务器 IP 地址或者域名,浏览 Nginx 的默认网页。
|
||||
|
||||
```
|
||||
http://IP-Address
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Verify-Nginx-Webpage.png)
|
||||
|
||||
*验证 Nginx 网页*
|
||||
|
||||
### 步骤 2:启用 Nginx HTTP/2.0 协议
|
||||
|
||||
3、 对 HTTP/2.0 协议的支持默认包含在 Ubuntu 16.04 最新发行版的 Nginx 二进制文件中了,它只能通过 SSL 连接并且保证加载网页的速度有巨大提升。
|
||||
|
||||
要启用Nginx 的这个协议,首先找到 Nginx 提供的网站配置文件,输入下面这个命令备份配置文件。
|
||||
|
||||
```
|
||||
$ cd /etc/nginx/sites-available/
|
||||
$ sudo mv default default.backup
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Backup-Nginx-Sites-Configuration-File.png)
|
||||
|
||||
*备份 Nginx 的网站配置文件*
|
||||
|
||||
4、然后,用文本编辑器新建一个默认文件,输入以下内容:
|
||||
|
||||
```
|
||||
server {
|
||||
listen 443 ssl http2 default_server;
|
||||
listen [::]:443 ssl http2 default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
index index.html index.htm index.php;
|
||||
|
||||
server_name 192.168.1.13;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/nginx.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/nginx.key;
|
||||
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
|
||||
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
|
||||
ssl_session_cache shared:SSL:20m;
|
||||
ssl_session_timeout 180m;
|
||||
resolver 8.8.8.8 8.8.4.4;
|
||||
add_header Strict-Transport-Security "max-age=31536000;
|
||||
#includeSubDomains" always;
|
||||
|
||||
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name 192.168.1.13;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Enable-Nginx-HTTP-2-Protocol.png)
|
||||
|
||||
*启用 Nginx HTTP 2 协议*
|
||||
|
||||
上面的配置片段向所有的 SSL 监听指令中添加 http2 参数来启用 `HTTP/2.0`。
|
||||
|
||||
上述添加到服务器配置的最后一段,是用来将所有非 SSL 的流量重定向到 SSL/TLS 默认主机。然后用你主机的 IP 地址或者 DNS 记录(最好用 FQDN 名称)替换掉 `server_name` 选项的参数。
|
||||
|
||||
5、 当你按照以上步骤编辑完 Nginx 的默认配置文件之后,用下面这些命令来生成、查看 SSL 证书和密钥。
|
||||
|
||||
用你自定义的设置完成证书的制作,注意 Common Name 设置成和你的 DNS FQDN 记录或者服务器 IP 地址相匹配。
|
||||
|
||||
```
|
||||
$ sudo mkdir /etc/nginx/ssl
|
||||
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
|
||||
$ ls /etc/nginx/ssl/
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Generate-SSL-Certificate-and-Key.png)
|
||||
|
||||
*生成 Nginx 的 SSL 证书和密钥*
|
||||
|
||||
6、 通过输入以下命令使用一个强 DH 加密算法,这会修改之前的配置文件 `ssl_dhparam` 所配置的文件。
|
||||
|
||||
```
|
||||
$ sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Create-Diffie-Hellman-Key.png)
|
||||
|
||||
*创建 Diffie-Hellman 密钥*
|
||||
|
||||
7、 当 `Diffie-Hellman` 密钥生成之后,验证 Nginx 的配置文件是否正确、能否被 Nginx 网络服务程序应用。然后运行以下命令重启守护进程来观察有什么变化。
|
||||
|
||||
```
|
||||
$ sudo nginx -t
|
||||
$ sudo systemctl restart nginx.service
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-Nginx-Configuration.png)
|
||||
|
||||
*检查 Nginx 的配置*
|
||||
|
||||
8、 键入下面的命令来测试 Nginx 使用的是 HTTP/2.0 协议。看到协议中有 `h2` 的话,表明 Nginx 已经成功配置使用 HTTP/2.0 协议。所有最新的浏览器默认都能够支持这个协议。
|
||||
|
||||
```
|
||||
$ openssl s_client -connect localhost:443 -nextprotoneg ''
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Test-Nginx-HTTP-2-Protocol.png)
|
||||
|
||||
*测试 Nginx HTTP 2.0 协议*
|
||||
|
||||
### 第 3 步:安装 PHP 7 解释器
|
||||
|
||||
通过 FastCGI 进程管理程序的协助,Nginx 能够使用 PHP 动态语言解释器生成动态网络内容。FastCGI 能够从 Ubuntu 官方仓库中安装 php-fpm 二进制包来获取。
|
||||
|
||||
9、 在你的服务器控制台里输入下面的命令来获取 PHP7.0 和扩展包,这能够让 PHP 与 Nginx 网络服务进程通信。
|
||||
|
||||
```
|
||||
$ sudo apt install php7.0 php7.0-fpm
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Install-PHP-7-PHP-FPM-for-Ngin.png)
|
||||
|
||||
*安装 PHP 7 以及 PHP-FPM*
|
||||
|
||||
10、 当 PHP7.0 解释器安装成功后,输入以下命令启动或者检查 php7.0-fpm 守护进程:
|
||||
|
||||
```
|
||||
$ sudo systemctl start php7.0-fpm
|
||||
$ sudo systemctl status php7.0-fpm
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Start-Verify-php-fpm-Service.png)
|
||||
|
||||
*开启、验证 php-fpm 服务*
|
||||
|
||||
11、 当前的 Nginx 配置文件已经配置了使用 PHP FPM 来提供动态内容。
|
||||
|
||||
下面给出的这部分服务器配置让 Nginx 能够使用 PHP 解释器,所以不需要对 Nginx 配置文件作别的修改。
|
||||
|
||||
```
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
|
||||
}
|
||||
```
|
||||
|
||||
下面是的截图是 Nginx 默认配置文件的内容。你可能需要对其中的代码进行修改或者取消注释。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Enable-PHP-FastCGI-for-Nginx.png)
|
||||
|
||||
*启用 PHP FastCGI*
|
||||
|
||||
12、 要测试启用了 PHP-FPM 的 Nginx 服务器,用下面的命令创建一个 PHP 测试配置文件 `info.php`。接着用 `http://IP_or domain/info.php` 这个网址来查看配置。
|
||||
|
||||
```
|
||||
$ sudo su -c 'echo "<?php phpinfo(); ?>" |tee /var/www/html/info.php'
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Create-PHP-Info-File.png)
|
||||
|
||||
*创建 PHP Info 文件*
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Verify-PHP-FastCGI-Info.png)
|
||||
|
||||
*检查 PHP FastCGI 的信息*
|
||||
|
||||
检查服务器是否宣告支持 HTTP/2.0 协议,定位到 PHP 变量区域中的 `$_SERVER[‘SERVER_PROTOCOL’]` 就像下面这张截图一样。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-HTTP-2.0-Protocol-Info.png)
|
||||
|
||||
*检查 HTTP2.0 协议信息*
|
||||
|
||||
13、 为了安装其它的 PHP7.0 模块,使用 `apt search php7.0` 命令查找 php 的模块然后安装。
|
||||
|
||||
如果你想要 [安装 WordPress][5] 或者别的 CMS,需要安装以下的 PHP 模块,这些模块迟早有用。
|
||||
|
||||
```
|
||||
$ sudo apt install php7.0-mcrypt php7.0-mbstring
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Install-PHP-7-Modules.png)
|
||||
|
||||
*安装 PHP 7 模块*
|
||||
|
||||
14、 要注册这些额外的 PHP 模块,输入下面的命令重启 PHP-FPM 守护进程。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart php7.0-fpm.service
|
||||
```
|
||||
|
||||
### 第 4 步:安装 MariaDB 数据库
|
||||
|
||||
15、 最后,我们需要 MariaDB 数据库来存储、管理网站数据,才算完成 LEMP 的搭建。
|
||||
|
||||
运行下面的命令安装 MariaDB 数据库管理系统,重启 PHP-FPM 服务以便使用 MySQL 模块与数据库通信。
|
||||
|
||||
```
|
||||
$ sudo apt install mariadb-server mariadb-client php7.0-mysql
|
||||
$ sudo systemctl restart php7.0-fpm.service
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Install-MariaDB-for-Nginx.png)
|
||||
|
||||
*安装 MariaDB*
|
||||
|
||||
16、 为了安全加固 MariaDB,运行来自 Ubuntu 软件仓库中的二进制包提供的安全脚本,这会询问你设置一个 root 密码,移除匿名用户,禁用 root 用户远程登录,移除测试数据库。
|
||||
|
||||
输入下面的命令运行脚本,并且确认所有的选择。参照下面的截图。
|
||||
|
||||
```
|
||||
$ sudo mysql_secure_installation
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Secure-MariaDB-Installation-for-Nginx.png)
|
||||
|
||||
*MariaDB 的安全安装*
|
||||
|
||||
17、 配置 MariaDB 以便普通用户能够不使用系统的 sudo 权限来访问数据库。用 root 用户权限打开 MySQL 命令行界面,运行下面的命令:
|
||||
|
||||
```
|
||||
$ sudo mysql
|
||||
MariaDB> use mysql;
|
||||
MariaDB> update user set plugin=’‘ where User=’root’;
|
||||
MariaDB> flush privileges;
|
||||
MariaDB> exit
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/MariaDB-User-Permissions.png)
|
||||
|
||||
*MariaDB 的用户权限*
|
||||
|
||||
最后通过执行以下命令登录到 MariaDB 数据库,就可以不需要 root 权限而执行任意数据库内的命令:
|
||||
|
||||
```
|
||||
$ mysql -u root -p -e 'show databases'
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-MariaDB-Databases.png)
|
||||
|
||||
*查看 MariaDB 数据库*
|
||||
|
||||
好了!现在你拥有了配置在 **Ubuntu 16.04** 服务器上的 **LEMP** 环境,你能够部署能够与数据库交互的复杂动态网络应用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/install-nginx-mariadb-php7-http2-on-ubuntu-16-04/
|
||||
|
||||
作者:[Matei Cezar][a]
|
||||
译者:[GitFuture](https://github.com/GitFuture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/cezarmatei/
|
||||
[1]: http://www.tecmint.com/installation-of-ubuntu-16-04-server-edition/
|
||||
[2]: http://www.tecmint.com/apt-advanced-package-command-examples-in-ubuntu/
|
||||
[3]: http://www.tecmint.com/20-netstat-commands-for-linux-network-management/
|
||||
[4]: http://www.tecmint.com/manage-services-using-systemd-and-systemctl-in-linux/
|
||||
[5]: http://www.tecmint.com/install-wordpress-using-lamp-or-lemp-on-rhel-centos-fedora/
|
@ -1,14 +1,15 @@
|
||||
在 Ubuntu Linux 中使用 WEBP 图片
|
||||
在 Ubuntu Linux 中使用 WebP 图片
|
||||
=========================================
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/support-webp-ubuntu-linux.jpg)
|
||||
|
||||
> 简介:这篇指南会向你展示如何在 Linux 下查看 WebP 图片以及将 WebP 图片转换为 JPEG 或 PNG 格式。
|
||||
|
||||
### 什么是 WEBP?
|
||||
### 什么是 WebP?
|
||||
|
||||
Google 为图片推出 [WebP 文件格式][0]已经超过五年了。Google 说,WebP 提供有损和无损压缩,相比 JPEG 压缩,WebP 压缩文件大小能更小约 25%。
|
||||
自从 Google 推出 [WebP 图片格式][0],已经过去五年了。Google 说,WebP 提供有损和无损压缩,相比 JPEG 压缩,WebP 压缩文件大小,能更小约 25%。
|
||||
|
||||
Google 的目标是让 WebP 成为 web 图片的新标准,但是我没能看到这一切发生。已经五年过去了,除了谷歌的生态系统以外它仍未被接受成为一个标准。但正如我们所知的,Google 对它的技术很有进取心。几个月前 Google 将 Google Plus 的所有图片改为了 WebP 格式。
|
||||
Google 的目标是让 WebP 成为 web 图片的新标准,但是并没有成为现实。已经五年过去了,除了谷歌的生态系统以外它仍未被接受成为一个标准。但正如我们所知的,Google 对它的技术很有进取心。几个月前 Google 将 Google Plus 的所有图片改为了 WebP 格式。
|
||||
|
||||
如果你用 Google Chrome 从 Google Plus 上下载那些图片,你会得到 WebP 图片,不论你之前上传的是 PNG 还是 JPEG。这都不是重点。真正的问题在于当你尝试着在 Ubuntu 中使用默认的 GNOME 图片查看器打开它时你会看到如下错误:
|
||||
|
||||
@ -17,7 +18,8 @@ Google 的目标是让 WebP 成为 web 图片的新标准,但是我没能看
|
||||
> **Unrecognized image file format(未识别文件格式)**
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-1.png)
|
||||
>GNOME 图片查看器不支持 WebP 图片
|
||||
|
||||
*GNOME 图片查看器不支持 WebP 图片*
|
||||
|
||||
在这个教程里,我们会看到
|
||||
|
||||
@ -41,7 +43,8 @@ sudo apt-get install gthumb
|
||||
一旦安装完成,你就可以简单地右键点击 WebP 图片,选择 gThumb 来打开它。你现在应该可以看到如下画面:
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-2.jpeg)
|
||||
>gThumb 中显示的 WebP 图片
|
||||
|
||||
*gThumb 中显示的 WebP 图片*
|
||||
|
||||
### 让 gThumb 成为 Ubuntu 中 WebP 图片的默认应用
|
||||
|
||||
@ -50,28 +53,30 @@ sudo apt-get install gthumb
|
||||
#### 步骤 1:右键点击 WebP 文件选择属性。
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png)
|
||||
>从右键菜单中选择属性
|
||||
|
||||
*从右键菜单中选择属性*
|
||||
|
||||
#### 步骤 2:转到打开方式标签,选择 gThumb 并点击设置为默认。
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png)
|
||||
>让 gThumb 成为 Ubuntu 中 WebP 图片的默认应用
|
||||
|
||||
*让 gThumb 成为 Ubuntu 中 WebP 图片的默认应用*
|
||||
|
||||
### 让 gThumb 成为所有图片的默认应用
|
||||
|
||||
gThumb 的功能比图片查看器更多。举个例子,你可以做一些简单的编辑,给图片添加滤镜等。添加滤镜的效率没有 XnRetro(在[ Linux 下添加类似 Instagram 滤镜效果][5]的专用工具)那么高,但它还是有一些基础的滤镜可以用。
|
||||
gThumb 的功能比图片查看器更多。举个例子,你可以做一些简单的图片编辑,给图片添加滤镜等。添加滤镜的效率没有 XnRetro(在[ Linux 下添加类似 Instagram 滤镜效果][5]的专用工具)那么高,但它还是有一些基础的滤镜可以用。
|
||||
|
||||
我非常喜欢 gThumb 并且决定让它成为默认的图片查看器。如果你也想在 Ubuntu 中让 gThumb 成为所有图片的默认默认应用,遵照以下步骤操作:
|
||||
我非常喜欢 gThumb 并且决定让它成为默认的图片查看器。如果你也想在 Ubuntu 中让 gThumb 成为所有图片的默认应用,遵照以下步骤操作:
|
||||
|
||||
#### 步骤1:打开系统设置
|
||||
步骤1:打开系统设置
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2014/04/System_Settings_ubuntu_1404.jpeg)
|
||||
|
||||
#### 步骤2:转到详情(Details)
|
||||
步骤2:转到详情(Details)
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2013/11/System_settings_Ubuntu_1.jpeg)
|
||||
|
||||
#### 步骤3:在这里将 gThumb 设置为图片的默认应用
|
||||
步骤3:在这里将 gThumb 设置为图片的默认应用
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-5.png)
|
||||
|
||||
@ -100,7 +105,7 @@ sudo apt-get install webp
|
||||
|
||||
##### 将 JPEG/PNG 转换为 WebP
|
||||
|
||||
我们将使用 cwebp 命令(它代表压缩为 WebP 吗?)来将 JPEG 或 PNG 文件转换为 WebP。命令格式是这样的:
|
||||
我们将使用 cwebp 命令(它代表转换为 WebP 的意思吗?)来将 JPEG 或 PNG 文件转换为 WebP。命令格式是这样的:
|
||||
|
||||
```
|
||||
cwebp -q [图片质量] [JPEG/PNG_文件名] -o [WebP_文件名]
|
||||
@ -132,7 +137,7 @@ dwebp example.webp -o example.png
|
||||
|
||||
[下载 XnConvert][1]
|
||||
|
||||
XnConvert 是个强大的工具,你可以用它来批量修改图片尺寸。但在这个教程里,我们只能看到如何将单个 WebP 图片转换为 PNG/JPEG。
|
||||
XnConvert 是个强大的工具,你可以用它来批量修改图片尺寸。但在这个教程里,我们只介绍如何将单个 WebP 图片转换为 PNG/JPEG。
|
||||
|
||||
打开 XnConvert 并选择输入文件:
|
||||
|
||||
@ -148,24 +153,24 @@ XnConvert 是个强大的工具,你可以用它来批量修改图片尺寸。
|
||||
|
||||
也许你一点都不喜欢 WebP 图片格式,也不想在 Linux 仅仅为了查看 WebP 图片而安装一个新软件。如果你不得不将 WebP 文件转换以备将来使用,这会是件更痛苦的事情。
|
||||
|
||||
一个解决这个问题更简单,不那么痛苦的途径是安装一个 Chrome 扩展 Save Image as PNG。有了这个插件,你可以右键点击 WebP 图片并直接存储为 PNG 格式。
|
||||
解决这个问题的一个更简单、不那么痛苦的途径是安装一个 Chrome 扩展 Save Image as PNG。有了这个插件,你可以右键点击 WebP 图片并直接存储为 PNG 格式。
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-8.png)
|
||||
>在 Google Chrome 中将 WebP 图片保存为 PNG 格式
|
||||
|
||||
[获取 Save Image as PNG 扩展][2]
|
||||
*在 Google Chrome 中将 WebP 图片保存为 PNG 格式*
|
||||
|
||||
- [获取 Save Image as PNG 扩展][2]
|
||||
|
||||
### 你的选择是?
|
||||
|
||||
我希望这个详细的教程能够帮你在 Linux 上获取 WebP 支持并帮你转换 WebP 图片。你在 Linux 怎么处理 WebP 图片?你使用哪个工具?以上描述的方法中,你最喜欢哪一个?
|
||||
|
||||
我希望这个详细的教程能够帮你在 Linux 上支持 WebP 并帮你转换 WebP 图片。你在 Linux 怎么处理 WebP 图片?你使用哪个工具?以上描述的方法中,你最喜欢哪一个?
|
||||
|
||||
----------------------
|
||||
via: http://itsfoss.com/webp-ubuntu-linux/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29
|
||||
via: http://itsfoss.com/webp-ubuntu-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,63 @@
|
||||
为什么 Ubuntu 家族会占据 Linux 发行版的主导地位?
|
||||
=========================================
|
||||
|
||||
在过去的数年中,我体验了一些优秀的 Linux 发行版。给我印象最深刻的是那些由强大的社区维护的发行版,而流行的发行版比强大的社区给我的印象更深。流行的 Linux 发行版往往能吸引新用户,这通常是由于其流行而使得使用该发行版会更加容易。并非绝对如此,但一般来说是这样的。
|
||||
|
||||
说到这里,首先映入我脑海的一个发行版是 [Ubuntu][1]。其基于健壮的 [Debian][2] 发行版构建,它不仅成为了一个非常受欢迎的 Linux 发行版,而且它也衍生出了不可计数的其他分支,比如 Linux Mint 就是一个例子。在本文中,我会探讨为何我认为 Ubuntu 会赢得 Linux 发行版之战的原因,以及它是怎样影响到了整个 Linux 桌面领域。
|
||||
|
||||
### Ubuntu 易于使用
|
||||
|
||||
在我几年前首次尝试使用 Ubuntu 前,我更喜欢使用 KED 桌面。在那个时期,我接触的大多是这种 KDE 桌面环境。主要原因还是 KDE 是大多数新手容易入手的 Linux 发行版中最受欢迎的。这些新手友好的发行版有 Knoppix、Simply Mepis、Xandros、Linspire 以及其它的发行版等等,这些发行版都推荐他们的用户去使用广受欢迎的 KDE。
|
||||
|
||||
现在 KDE 能满足我的需求,我也没有什么理由去折腾其他的桌面环境。有一天我的 Debian 安装失败了(由于我个人的操作不当),我决定尝试开发代号为 Dapper Drake 的 Ubuntu 版本(LCTT 译注:Ubuntu 6.06 - Dapper Drake,发布日期:2006 年 6 月 1 日),每个人都对它赞不绝口。那个时候,我对于它的印象仅限于屏幕截图,但是我想试试也挺有趣的。
|
||||
|
||||
Ubuntu Dapper Drake 给我的最大的印象是它让我很清楚地知道每个东西都在哪儿。记住,我是来自于 KDE 世界的用户,在 KDE 上要想改变菜单的设置就有 15 种方法 !而 Ubuntu 上的 GNOME 实现极具极简主义的。
|
||||
|
||||
时间来到 2016 年,最新的版本号是 16.04:我们有了好几种 Ubuntu 特色版本,也有一大堆基于 Ubuntu 的发行版。所有的 Ubuntu 特色版和衍生发行版的共同具有的核心都是为易用而设计。发行版想要增大用户基数时,这就是最重要的原因。
|
||||
|
||||
### Ubuntu LTS
|
||||
|
||||
过去,我几乎一直坚持使用 LTS(Long Term Support)发行版作为我的主要桌面系统。10月份的发行版很适合我测试硬盘驱动器,甚至把它用在一个老旧的手提电脑上。我这样做的原因很简单——我没有兴趣在一个正式使用的电脑上折腾短期发行版。我是个很忙的家伙,我觉得这样会浪费我的时间。
|
||||
|
||||
对于我来说,我认为 Ubuntu 提供 LTS 发行版是 Ubuntu 能够变得流行的最大的原因。这样说吧———给普罗大众提供一个桌面 Linux 发行版,这个发行版能够得到长期的有效支持就是它的优势。事实上,不只 Ubuntu 是这样,其他的分支在这一点上也做的很好。长期支持策略以及对新手的友好环境,我认为这就为 Ubuntu 的普及带来了莫大的好处。
|
||||
|
||||
### Ubuntu Snap 软件包
|
||||
|
||||
以前,用户会夸赞可以在他们的系统上使用 PPA(personal package archive 个人软件包档案)获得新的软件。不好的是,这种技术也有缺点。当它用在各种软件名称时, PPA 经常会找不到,这种情况很常见。
|
||||
|
||||
现在有了 [Snap 软件包][3] 。当然这不是一个全新的概念,过去已经进行了类似的尝试。用户可以在一个长期支持版本上运行最新的软件,而不必去使用最新的 Ubuntu 发行版。虽然我认为目前还处于 Snap 软件包的早期,但是我很期待可以在一个稳定的发行版上运行的崭新的软件。
|
||||
|
||||
最明显的问题是,如果你要运行很多软件,那么 Snap 包实际会占用很多硬盘空间。不仅如此,大多数 Ubuntu 软件仍然需要由官方从 deb 包进行转换。第一个问题可以通过使用更大的硬盘空间得到解决,而后一个问题的解决则需要等待。
|
||||
|
||||
### Ubuntu 社区
|
||||
|
||||
首先,我承认大多数主要的 Linux 发行版都有强大的社区。然而,我坚信 Ubuntu 社区的成员是最多样化的,他们来自各行各业。例如,我们的论坛包括从苹果硬件支持到游戏等不同分类。特别是这些专业的讨论话题还非常广泛。
|
||||
|
||||
除过论坛,Ubuntu 也提供了一个很正式的社区组织。这个组织包括一个理事会、技术委员会、[本地社区团队][4]和开发者成员委员会。还有很多,但是这些都是我知道的社区组织部分。
|
||||
|
||||
我们还有一个 [Ubuntu 问答][5]版块。我认为,这种功能可以代替人们从论坛寻求帮助的方式,我发现在这个网站你得到有用信息的可能性更大。不仅如此,那些提供的解决方案中被选出的最精准的答案也会被写入到官方文档中。
|
||||
|
||||
### Ubuntu 的未来
|
||||
|
||||
我认为 Ubuntu 的 Unity 界面(LCTT 译注:Unity 是 Canonical 公司为 Ubuntu 操作系统的 GNOME 桌面环境开发的图形化界面)在提升桌面占有率上少有作为。我能理解其中的缘由,现在它主要做一些诸如可以使开发团队的工作更轻松的事情。但是最终,我还是认为 Unity 为 Ubuntu MATE 和 Linux Mint 的普及铺平道路。
|
||||
|
||||
我最好奇的一点是 Ubuntu's IRC 和邮件列表的发展(LCTT 译注:可以在 Ubuntu LoCo Teams 的 IRC Chat 上提问关于地方团队和计划的事件的问题,也可以和一些不同团队的成员进行交流)。事实是,他们都不能像 Ubuntu 问答板块那样文档化。至于邮件列表,我一直认为这对于合作是一种很痛苦的过时方法,但这仅仅是我的个人看法——其他人可能有不同的看法,也可能会认为它很好。
|
||||
|
||||
你怎么看?你认为 Ubuntu 将来会占据主要的份额吗?也许你会认为 Arch 和 Linux Mint 或者其他的发行版会在普及度上打败 Ubuntu? 既然这样,那请大声说出你最喜爱的发行版。如果这个发行版是 Ubuntu 衍生版 ,说说你为什么更喜欢它而不是 Ubuntu 本身。如果不出意外,Ubuntu 会成为构建其他发行版的基础,我想很多人都是这样认为的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.datamation.com/open-source/why-ubuntu-based-distros-are-leaders.html
|
||||
|
||||
作者:[Matt Hartley][a]
|
||||
译者:[vim-kakali](https://github.com/vim-kakali)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.datamation.com/author/Matt-Hartley-3080.html
|
||||
[1]: http://www.ubuntu.com/
|
||||
[2]: https://www.debian.org/
|
||||
[3]: http://www.datamation.com/open-source/ubuntu-snap-packages-the-good-the-bad-the-ugly.html
|
||||
[4]: http://loco.ubuntu.com/
|
||||
[5]: http://askubuntu.com/
|
@ -0,0 +1,64 @@
|
||||
教你用 google-drive-ocamlfuse 在 Linux 上挂载 Google Drive
|
||||
=====================
|
||||
|
||||
> 如果你在找一个方便的方式在 Linux 机器上挂载你的 Google Drive 文件夹, Jack Wallen 将教你怎么使用 google-drive-ocamlfuse 来挂载 Google Drive。
|
||||
|
||||
![](http://tr4.cbsistatic.com/hub/i/2016/05/18/ee5d7b81-e5be-4b24-843d-d3ca99230a63/651be96ac8714698f8100afa6883e64d/linuxcloudhero.jpg)
|
||||
|
||||
*图片来源: Jack Wallen*
|
||||
|
||||
Google 还没有发行 Linux 版本的 Google Drive 应用,尽管现在有很多方法从 Linux 中访问你的 Drive 文件。
|
||||
|
||||
如果你喜欢界面化的工具,你可以选择 Insync。如果你喜欢用命令行,有很多像 Grive2 这样的工具,和更容易使用的以 Ocaml 语言编写的基于 FUSE 的文件系统。我将会用后面这种方式演示如何在 Linux 桌面上挂载你的 Google Drive。尽管这是通过命令行完成的,但是它的用法会简单到让你吃惊。它太简单了以至于谁都能做到。
|
||||
|
||||
这个系统的特点:
|
||||
|
||||
- 对普通文件/文件夹有完全的读写权限
|
||||
- 对于 Google Docs,sheets,slides 这三个应用只读
|
||||
- 能够访问 Drive 回收站(.trash)
|
||||
- 处理重复文件功能
|
||||
- 支持多个帐号
|
||||
|
||||
让我们接下来完成 google-drive-ocamlfuse 在 Ubuntu 16.04 桌面的安装,然后你就能够访问云盘上的文件了。
|
||||
|
||||
### 安装
|
||||
|
||||
1. 打开终端。
|
||||
2. 用 `sudo add-apt-repository ppa:alessandro-strada/ppa` 命令添加必要的 PPA
|
||||
3. 出现提示的时候,输入你的 root 密码并按下回车。
|
||||
4. 用 `sudo apt-get update` 命令更新应用。
|
||||
5. 输入 `sudo apt-get install google-drive-ocamlfuse` 命令安装软件。
|
||||
|
||||
### 授权
|
||||
|
||||
接下来就是授权 google-drive-ocamlfuse,让它有权限访问你的 Google 账户。先回到终端窗口敲下命令 `google-drive-ocamlfuse`,这个命令将会打开一个浏览器窗口,它会提示你登陆你的 Google 帐号或者如果你已经登陆了 Google 帐号,它会询问是否允许 google-drive-ocamlfuse 访问 Google 账户。如果你还没有登录,先登录然后点击“允许”。接下来的窗口(在 Ubuntu 16.04 桌面上会出现,但不会出现在 Elementary OS Freya 桌面上)将会询问你是否授给 gdfuse 和 OAuth2 Endpoint 访问你的 Google 账户的权限,再次点击“允许”。然后出现的窗口就会告诉你等待授权令牌下载完成,这个时候就能最小化浏览器了。当你的终端提示如下图一样的内容,你就能知道令牌下载完了,并且你已经可以挂载 Google Drive 了。
|
||||
|
||||
![](http://tr4.cbsistatic.com/hub/i/r/2016/05/18/a493122b-445f-4aca-8974-5ec41192eede/resize/620x/6ae5907ad2c08dc7620b7afaaa9e389c/googledriveocamlfuse3.png)
|
||||
|
||||
*应用已经得到授权,你可以进行后面的工作。*
|
||||
|
||||
### 挂载 Google Drive
|
||||
|
||||
在挂载 Google Drive 之前,你得先创建一个文件夹,作为挂载点。在终端里,敲下`mkdir ~/google-drive`命令在你的家目录下创建一个新的文件夹。最后敲下命令`google-drive-ocamlfuse ~/google-drive`将你的 Google Drive 挂载到 google-drive 文件夹中。
|
||||
|
||||
这时你可以查看本地 google-drive 文件夹中包含的 Google Drive 文件/文件夹。你可以把 Google Drive 当作本地文件系统来进行工作。
|
||||
|
||||
当你想卸载 google-drive 文件夹,输入命令 `fusermount -u ~/google-drive`。
|
||||
|
||||
### 没有 GUI,但它特别好用
|
||||
|
||||
我发现这个特别的系统非常容易使用,在同步 Google Drive 时它出奇的快,并且这可以作为一种本地备份你的 Google Drive 账户的巧妙方式。(LCTT 译注:然而首先你得能使用……)
|
||||
|
||||
试试 google-drive-ocamlfuse,看看你能用它做出什么有趣的事。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.techrepublic.com/article/how-to-mount-your-google-drive-on-linux-with-google-drive-ocamlfuse/
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
译者:[GitFuture](https://github.com/GitFuture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.techrepublic.com/search/?a=jack+wallen
|
@ -1,17 +1,17 @@
|
||||
在 Ubuntu 16.04 上安装使用 VBoxManage 以及 VBoxManage 命令行选项的用法
|
||||
在 Linux 上安装使用 VirtualBox 的命令行管理界面 VBoxManage
|
||||
=================
|
||||
|
||||
VirtualBox 拥有一套命令行工具,然后你可以使用 VirtualBox 的命令行界面 (CLI) 对远端无界面的服务器上的虚拟机进行管理操作。在这篇教程中,你将会学到如何在没有 GUI 的情况下使用 VBoxManage 创建、启动一个虚拟机。VBoxManage 是 VirtualBox 的命令行界面,你可以在你的主机操作系统的命令行中来用它实现对 VirtualBox 的所有操作。VBoxManage 拥有图形化用户界面所支持的全部功能,而且它支持的功能远不止这些。它提供虚拟引擎的所有功能,甚至包含 GUI 还不能实现的那些功能。如果你想尝试不同的用户界面而不仅仅是 GUI,或者更改虚拟机更多高级和实验性的配置,那么你就需要用到命令行。
|
||||
VirtualBox 拥有一套命令行工具,你可以使用 VirtualBox 的命令行界面 (CLI) 对远程无界面的服务器上的虚拟机进行管理操作。在这篇教程中,你将会学到如何在没有 GUI 的情况下使用 VBoxManage 创建、启动一个虚拟机。VBoxManage 是 VirtualBox 的命令行界面,你可以在你的主机操作系统的命令行中用它来实现对 VirtualBox 的所有操作。VBoxManage 拥有图形化用户界面所支持的全部功能,而且它支持的功能远不止这些。它提供虚拟引擎的所有功能,甚至包含 GUI 还不能实现的那些功能。如果你想尝试下不同的用户界面而不仅仅是 GUI,或者更改虚拟机更多高级和实验性的配置,那么你就需要用到命令行。
|
||||
|
||||
当你想要在 VirtualBox 上创建或运行虚拟机时,你会发现 VBoxManage 非常有用,你只需要使用远程主机的终端就够了。这对于服务器来说是一种常见的情形,因为在服务器上需要进行虚拟机的远程操作。
|
||||
当你想要在 VirtualBox 上创建或运行虚拟机时,你会发现 VBoxManage 非常有用,你只需要使用远程主机的终端就够了。这对于需要远程管理虚拟机的服务器来说是一种常见的情形。
|
||||
|
||||
### 准备工作
|
||||
|
||||
在开始使用 VBoxManage 的命令行工具前,确保在运行着 Ubuntu 16.04 的服务器上,你拥有超级用户的权限或者你能够使用 sudo 命令,而且你已经在服务器上安装了 Oracle Virtual Box。 然后你需要安装 VirtualBox 扩展包,这是运行远程桌面环境,访问无界面启动虚拟机所必须的。(headless的翻译拿不准,翻译为无界面启动)
|
||||
在开始使用 VBoxManage 的命令行工具前,确保在运行着 Ubuntu 16.04 的服务器上,你拥有超级用户的权限或者你能够使用 sudo 命令,而且你已经在服务器上安装了 Oracle Virtual Box。 然后你需要安装 VirtualBox 扩展包,这是运行 VRDE 远程桌面环境,访问无界面虚拟机所必须的。
|
||||
|
||||
### 安装 VBoxManage
|
||||
|
||||
通过 [Virtual Box Download Page][1] 这个链接,你能够获取你所需要的软件扩展包的最新版本,扩展包的版本和你安装的 VirtualBox 版本需要一致!
|
||||
通过 [Virtual Box 下载页][1] 这个链接,你能够获取你所需要的软件扩展包的最新版本,扩展包的版本和你安装的 VirtualBox 版本需要一致!
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/12.png)
|
||||
|
||||
@ -71,11 +71,11 @@ $ VBoxManage modifyvm Ubuntu10.10 --memory 512
|
||||
$ VBoxManage storagectl Ubuntu16.04 --name IDE --add ide --controller PIIX4 --bootable on
|
||||
```
|
||||
|
||||
这里的 “storagect1” 是给虚拟机创建存储控制器的,“--name” 指定了虚拟机里需要创建、更改或者移除的存储控制器的名称。“--add” 选项指明系统总线类型,可选的选项有 ide / sata / scsi / floppy,存储控制器必须要连接到系统总线。“--controller” 选择主板的类型,主板需要根据需要的存储控制器选择,可选的选项有 LsiLogic / LSILogicSAS / BusLogic / IntelAhci / PIIX3 / PIIX4 / ICH6 / I82078。最后的 “--bootable” 表示控制器是否可以引导。
|
||||
这里的 “storagect1” 是给虚拟机创建存储控制器的,“--name” 指定了虚拟机里需要创建、更改或者移除的存储控制器的名称。“--add” 选项指明存储控制器所需要连接到的系统总线类型,可选的选项有 ide / sata / scsi / floppy。“--controller” 选择主板的类型,主板需要根据需要的存储控制器选择,可选的选项有 LsiLogic / LSILogicSAS / BusLogic / IntelAhci / PIIX3 / PIIX4 / ICH6 / I82078。最后的 “--bootable” 表示控制器是否可以引导系统。
|
||||
|
||||
上面的命令创建了叫做 IDE 的存储控制器。然后虚拟设备就能通过 “storageattach” 命令连接到控制器。
|
||||
上面的命令创建了叫做 IDE 的存储控制器。之后虚拟介质就能通过 “storageattach” 命令连接到该控制器。
|
||||
|
||||
然后运行下面这个命令来创建一个叫做 SATA 的存储控制器,它将会连接到硬盘镜像上。
|
||||
然后运行下面这个命令来创建一个叫做 SATA 的存储控制器,它将会连接到之后的硬盘镜像上。
|
||||
|
||||
```
|
||||
$ VBoxManage storagectl Ubuntu16.04 --name SATA --add sata --controller IntelAhci --bootable on
|
||||
@ -87,7 +87,7 @@ $ VBoxManage storagectl Ubuntu16.04 --name SATA --add sata --controller IntelAhc
|
||||
$ VBoxManage storageattach Ubuntu16.04 --storagectl SATA --port 0 --device 0 --type hdd --medium "your_iso_filepath"
|
||||
```
|
||||
|
||||
用媒体把 SATA 存储控制器连接到 Ubuntu16.04 虚拟机中,也就是之前创建的虚拟硬盘镜像里。
|
||||
这将把 SATA 存储控制器及介质(比如之前创建的虚拟磁盘镜像)连接到 Ubuntu16.04 虚拟机中。
|
||||
|
||||
运行下面的命令添加像网络连接,音频之类的功能。
|
||||
|
||||
@ -120,9 +120,9 @@ $VBoxManage controlvm
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/81.png)
|
||||
|
||||
完结!
|
||||
###完结
|
||||
|
||||
从这篇文章中,我们了解了 Oracle Virtual Box 中一个十分实用的工具,就是 VBoxManage,包含了 VBoxManage 的安装和在 Ubuntu 16.04 系统上的使用。文章包含详细的教程, 通过 VBoxManage 中实用的命令来创建和管理虚拟机。希望这篇文章对你有帮助,另外别忘了分享你的评论或者建议。
|
||||
从这篇文章中,我们了解了 Oracle Virtual Box 中一个十分实用的工具 VBoxManage,文章包含了 VBoxManage 的安装和在 Ubuntu 16.04 系统上的使用,包括通过 VBoxManage 中实用的命令来创建和管理虚拟机。希望这篇文章对你有帮助,另外别忘了分享你的评论或者建议。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -130,7 +130,7 @@ via: http://linuxpitstop.com/install-and-use-command-line-tool-vboxmanage-on-ubu
|
||||
|
||||
作者:[Kashif][a]
|
||||
译者:[GitFuture](https://github.com/GitFuture)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -5,15 +5,15 @@
|
||||
|
||||
*简介:这个快速指南将向你展示所有的基础 Git 命令以及用法。你可以下载这些命令作为快速参考。*
|
||||
|
||||
我们在早先一篇文章中已经见过快速指南和 [Vi cheat sheet 下载][1]了。在这篇文章里,我们将会看到开始使用 Git 所需要的基础命令。
|
||||
我们在早先一篇文章中已经快速介绍过 [Vi 速查表][1]了。在这篇文章里,我们将会介绍开始使用 Git 时所需要的基础命令。
|
||||
|
||||
### GIT
|
||||
### Git
|
||||
|
||||
[Git][2] 是一个分布式版本控制系统,它被用在大量开源项目中。它是在 2005 年由 Linux 创始人 [Linus Torvalds][3] 写就的。这个程序允许非线性的项目开发,并且能够通过存储在本地服务器高效处理大量数据。在这个教程里,我们将要和 Git 愉快玩耍并学习如何开始使用它。
|
||||
|
||||
我在这个教程里使用 Ubuntu,但你可以使用你选择的任何发行版。除了安装以外,剩下的所有命令在任何 Linux 发行版上都是一样的。
|
||||
|
||||
### 安装 GIT
|
||||
### 安装 Git
|
||||
|
||||
要安装 git 执行以下命令:
|
||||
|
||||
@ -23,11 +23,11 @@ sudo apt-get install git-core
|
||||
|
||||
在它完成下载之后,你就安装好了 Git 并且可以使用了。
|
||||
|
||||
### 设置 GIT:
|
||||
### 设置 Git
|
||||
|
||||
在 Git 安装之后,不论是从 apt-get 还是从源码安装,你需要将你的用户名和邮箱地址复制到 gitconfig 文件。你可以访问 ~/.gitconfig 这个文件。
|
||||
|
||||
全新安装 Git 之后打开它会是完全空白的页面:
|
||||
全新安装 Git 之后打开它会是完全空白的:
|
||||
|
||||
```
|
||||
sudo vim ~/.gitconfig
|
||||
@ -42,7 +42,7 @@ git config --global user.email user@example.com
|
||||
|
||||
然后你就完成设置了。现在让我们开始 Git。
|
||||
|
||||
### 仓库:
|
||||
### 仓库
|
||||
|
||||
创建一个新目录,打开它并运行以下命令:
|
||||
|
||||
@ -52,13 +52,11 @@ git init
|
||||
|
||||
![](http://itsfoss.com/wp-content/uploads/2016/05/Playing-around-git-1-1024x173.png)
|
||||
|
||||
这个命令会创建一个新的 git 仓库。你的本地仓库由三个 git 维护的“树”组成。
|
||||
这个命令会创建一个新的 Git 仓库(repository)。你的本地仓库由三个 Git 维护的“树”组成。
|
||||
|
||||
第一个是你的**工作目录**,保存实际的文件。第二个是索引,实际上扮演的是暂存区,最后一个是 HEAD,它指向你最后一个 commit 提交。
|
||||
第一个是你的工作目录(Working Directory),保存实际的文件。第二个是索引,实际上扮演的是暂存区(staging area),最后一个是 HEAD,它指向你最后一个 commit 提交。使用 git clone /path/to/repository 签出你的仓库(从你刚创建的仓库或服务器上已存在的仓库)。
|
||||
|
||||
使用 git clone /path/to/repository 签出你的仓库(从你刚创建的仓库或服务器上已存在的仓库)。
|
||||
|
||||
### 添加文件并提交:
|
||||
### 添加文件并提交
|
||||
|
||||
你可以用以下命令添加改动:
|
||||
|
||||
@ -98,7 +96,7 @@ git commit -a
|
||||
|
||||
### 推送你的改动
|
||||
|
||||
你的改动在你本地工作副本的 HEAD 中。如果你还没有从一个已存在的仓库克隆或想将你的仓库连接到远程服务器,你需要先添加它:
|
||||
你的改动在你本地工作副本的 HEAD 中。如果你还没有从一个已存在的仓库克隆,或想将你的仓库连接到远程服务器,你需要先添加它:
|
||||
|
||||
```
|
||||
git remote add origin <服务器地址>
|
||||
@ -110,9 +108,9 @@ git remote add origin <服务器地址>
|
||||
git push -u origin master
|
||||
```
|
||||
|
||||
### 分支:
|
||||
### 分支
|
||||
|
||||
分支用于开发特性,它们之间是互相独立的。主分支 master 是你创建一个仓库时的“默认”分支。使用其它分支用于开发,在完成时将它合并回主分支。
|
||||
分支用于开发特性,分支之间是互相独立的。主分支 master 是你创建一个仓库时的“默认”分支。使用其它分支用于开发,在完成时将它合并回主分支。
|
||||
|
||||
创建一个名为“mybranch”的分支并切换到它之上:
|
||||
|
||||
@ -144,19 +142,19 @@ git push origin <分支名>
|
||||
|
||||
### 更新和合并
|
||||
|
||||
要将你本地仓库更新到最新提交,运行:
|
||||
要将你本地仓库更新到最新的提交上,运行:
|
||||
|
||||
```
|
||||
git pull
|
||||
```
|
||||
|
||||
在你的工作目录获取和合并远程变动。要合并其它分支到你的活动分支(如 master),使用:
|
||||
在你的工作目录获取并合并远程变动。要合并其它分支到你的活动分支(如 master),使用:
|
||||
|
||||
```
|
||||
git merge <分支>
|
||||
```
|
||||
|
||||
在这两种情况下,git 会尝试自动合并(auto-merge)改动。不幸的是,这不总是可能的,可能会导致冲突。你需要负责通过编辑 git 显示的文件,手动合并那些冲突。改动之后,你需要用以下命令将它们标记为已合并:
|
||||
在这两种情况下,git 会尝试自动合并(auto-merge)改动。不幸的是,这不总是可能的,可能会导致冲突。你需要通过编辑 git 所显示的文件,手动合并那些冲突。改动之后,你需要用以下命令将它们标记为已合并:
|
||||
|
||||
```
|
||||
git add <文件名>
|
||||
@ -168,7 +166,7 @@ git add <文件名>
|
||||
git diff <源分支> <目标分支>
|
||||
```
|
||||
|
||||
### GIT 日志:
|
||||
### Git 日志
|
||||
|
||||
你可以这么查看仓库历史:
|
||||
|
||||
@ -176,7 +174,7 @@ git diff <源分支> <目标分支>
|
||||
git log
|
||||
```
|
||||
|
||||
要查看每个提交一行样式的日志你可以用:
|
||||
要以每个提交一行的样式查看日志,你可以用:
|
||||
|
||||
```
|
||||
git log --pretty=oneline
|
||||
@ -196,9 +194,9 @@ git log --name-status
|
||||
|
||||
在这整个过程中如果你需要任何帮助,你可以用 git --help。
|
||||
|
||||
Git 棒不棒!!!祝贺你你已经会 git 基础了。如果你愿意的话,你可以从下面这个链接下载这些基础 Git 命令作为快速参考:
|
||||
Git 棒不棒?!祝贺你你已经会 Git 基础了。如果你愿意的话,你可以从下面这个链接下载这些基础 Git 命令作为快速参考:
|
||||
|
||||
[下载 Git Cheat Sheet][4]
|
||||
- [下载 Git 速查表][4]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -207,7 +205,7 @@ via: http://itsfoss.com/basic-git-commands-cheat-sheet/
|
||||
|
||||
作者:[Rakhi Sharma][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,98 @@
|
||||
如何在 Linux 上录制你的终端操作
|
||||
=================================================
|
||||
|
||||
录制一个终端操作可能是一个帮助他人学习 Linux 、展示一系列正确命令行操作的和分享知识的通俗易懂方法。不管是出于什么目的,从终端复制粘贴文本需要重复很多次,而录制视频的过程也是相当麻烦,有时候还不能录制。在这次的文章中,我们将简单的了解一下以 gif 格式记录和分享终端会话的方法。
|
||||
|
||||
### 预先要求
|
||||
|
||||
如果你只是希望能记录你的终端会话,并且能在终端进行回放或者和他人分享,那么你只需要一个叫做:ttyrec 的软件。Ubuntu 用户可以通过运行这行代码进行安装:
|
||||
|
||||
```
|
||||
sudo apt-get install ttyrec
|
||||
```
|
||||
|
||||
如果你想将生成的视频转换成一个 gif 文件,这样能够和那些不使用终端的人分享,就可以发布到网站上去,或者你只是想做一个 gif 方便使用而不想写命令。那么你需要安装额外的两个软件包。第一个就是 imagemagick , 你可以通过以下的命令安装:
|
||||
|
||||
```
|
||||
sudo apt-get install imagemagick
|
||||
```
|
||||
|
||||
第二个软件包就是:tty2gif.py,访问其[项目网站][1]下载。这个软件包需要安装如下依赖:
|
||||
|
||||
```
|
||||
sudo apt-get install python-opster
|
||||
```
|
||||
|
||||
### 录制
|
||||
|
||||
开始录制终端操作,你需要的仅仅是键入 `ttyprec` ,然后回车。这个命令将会在后台运行一个实时的记录工具。我们可以通过键入`exit`或者`ctrl+d`来停止。ttyrec 默认会在主目录下创建一个`ttyrecord`的文件。
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_1.jpg)
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_2.jpg)
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_3.jpg)
|
||||
|
||||
### 回放
|
||||
|
||||
回放这个文件非常简单。你只需要打开终端并且使用 `ttyplay` 命令打开 `ttyrecord` 文件即可。(在这个例子里,我们使用 ttyrecord 作为文件名,当然,你也可以改成你用的文件名)
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_4.jpg)
|
||||
|
||||
然后就可以开始播放这个文件。这个视频记录了所有的操作,包括你的删除,修改。这看起来像一个拥有自我意识的终端,但是这个命令执行的过程并不是只是为了给系统看,而是为了更好的展现给人。
|
||||
|
||||
注意一点,播放这个记录是完全可控的,你可以通过点击 `+` 或者 `-` 进行加速减速,或者 `0`和 `1` 暂停和恢复播放。
|
||||
|
||||
### 导出成 GIF
|
||||
|
||||
为了方便,我们通常会将视频记录转换为 gif 格式,并且,这个非常容易做到。以下是方法:
|
||||
|
||||
将之前下载的 tty2gif.py 这个文件拷贝到 ttyprecord 文件(或者你命名的那个视频文件)相同的目录,然后在这个目录下打开终端,输入命令:
|
||||
|
||||
```
|
||||
python tty2gif.py typing ttyrecord
|
||||
```
|
||||
|
||||
如果出现了错误,检查一下你是否有安装 python-opster 包。如果还是有错误,使用如下命令进行排除。
|
||||
|
||||
```
|
||||
sudo apt-get install xdotool
|
||||
export WINDOWID=$(xdotool getwindowfocus)
|
||||
```
|
||||
|
||||
然后重复这个命令 `python tty2gif.py` 并且你将会看到在 ttyrecord 目录下多了一些 gif 文件。
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_5.jpg)
|
||||
|
||||
接下来的一步就是整合所有的 gif 文件,将他打包成一个 gif 文件。我们通过使用 imagemagick 工具。输入下列命令:
|
||||
|
||||
```
|
||||
convert -delay 25 -loop 0 *.gif example.gif
|
||||
```
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/pic_6.jpg)
|
||||
|
||||
你可以使用任意的文件名,我用的是 example.gif。 并且,你可以改变这个延时和循环时间。 Enjoy。
|
||||
|
||||
![](https://www.howtoforge.com/images/how-to-record-your-terminal-session-on-linux/example.gif)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/how-to-record-your-terminal-session-on-linux/
|
||||
|
||||
作者:[Bill Toulas][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://twitter.com/howtoforgecom
|
||||
[1]: https://bitbucket.org/antocuni/tty2gif/raw/61d5596c916512ce5f60fcc34f02c686981e6ac6/tty2gif.py
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
在 Ubuntu Mate 16.04 上通过 PPA 升级 Mate 1.14
|
||||
=================================================================
|
||||
|
||||
Mate 桌面环境 1.14 现在可以在 Ubuntu Mate 16.04 ("Xenial Xerus") 上使用了。根据这个[发布版本][1]的描述,为了全面测试 Mate 1.14,所以 Mate 桌面环境 1.14 已经在 PPA 上发布 2 个月了。因此,你不太可能遇到安装的问题。
|
||||
|
||||
![](https://2.bp.blogspot.com/-v38tLvDAxHg/V1k7beVd5SI/AAAAAAAAX7A/1X72bmQ3ia42ww6kJ_61R-CZ6yrYEBSpgCLcB/s400/mate114-ubuntu1604.png)
|
||||
|
||||
**现在 PPA 提供 Mate 1.14.1 包含如下改变(Ubuntu Mate 16.04 默认安装的是 Mate 1.12.x):**
|
||||
|
||||
- 客户端的装饰应用现在可以正确的在所有主题中渲染;
|
||||
- 触摸板配置现在支持边缘操作和双指滚动;
|
||||
- 在 Caja 中的 Python 扩展可以被单独管理;
|
||||
- 所有三个窗口焦点模式都是可选的;
|
||||
- Mate Panel 中的所有菜单栏图标和菜单图标可以改变大小;
|
||||
- 音量和亮度 OSD 目前可以启用和禁用;
|
||||
- 更多的改进和 bug 修改;
|
||||
|
||||
Mate 1.14 同时改进了整个桌面环境中对 GTK+ 3 的支持,包括各种 GTK+3 小应用。但是,Ubuntu MATE 的博客中提到:PPA 的发行包使用 GTK+ 2 编译是“为了确保对 Ubuntu MATE 16.04 还有各种各样的第三方 MATE 应用、插件、扩展的支持"。
|
||||
|
||||
MATE 1.14 的完整修改列表[点击此处][2]阅读。
|
||||
|
||||
### 在 Ubuntu MATE 16.04 中升级 MATE 1.14.x
|
||||
|
||||
在 Ubuntu MATE 16.04 中打开终端,并且输入如下命令,来从官方的 Xenial MATE PPA 中升级最新的 MATE 桌面环境:
|
||||
|
||||
```
|
||||
sudo apt-add-repository ppa:ubuntu-mate-dev/xenial-mate
|
||||
sudo apt update
|
||||
sudo apt dist-upgrade
|
||||
```
|
||||
|
||||
**注意**: mate-netspeed 应用将会在升级中删除。因为该应用现在已经是 mate-applets 应用报的一部分,所以它依旧是可以使用的。
|
||||
|
||||
一旦升级完成,请重启你的系统,享受全新的 MATE!
|
||||
|
||||
### 如何回滚这次升级
|
||||
|
||||
如果你并不满意 MATE 1.14, 比如你遭遇了一些 bug 。或者你想回到 MATE 的官方源版本,你可以使用如下的命令清除 PPA,并且下载降级包。
|
||||
|
||||
```
|
||||
sudo apt install ppa-purge
|
||||
sudo ppa-purge ppa:ubuntu-mate-dev/xenial-mate
|
||||
```
|
||||
|
||||
在所有的 MATE 包降级之后,重启系统。
|
||||
|
||||
via [Ubuntu MATE blog][3]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.webupd8.org/2016/06/install-mate-114-in-ubuntu-mate-1604.html
|
||||
|
||||
作者:[Andrew][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.webupd8.org/p/about.html
|
||||
[1]: https://ubuntu-mate.org/blog/mate-desktop-114-for-xenial-xerus/
|
||||
[2]: http://mate-desktop.com/blog/2016-04-08-mate-1-14-released/
|
||||
[3]: https://ubuntu-mate.org/blog/mate-desktop-114-for-xenial-xerus/
|
125
published/201607/20160610 Getting started with ReactOS.md
Normal file
125
published/201607/20160610 Getting started with ReactOS.md
Normal file
@ -0,0 +1,125 @@
|
||||
ReactOS 新手指南
|
||||
====================================
|
||||
|
||||
ReactOS 是一个比较年轻的开源操作系统,它提供了一个和 Windows NT 类似的图形界面,并且它的目标也是提供一个与 NT 功能和应用程序兼容性差不多的系统。这个项目在没有使用任何 Unix 架构的情况下实现了一个类似 Wine 的用户模式。它的开发者们从头实现了 NT 的架构以及对于 FAT32 的兼容,因此它也不需要负任何法律责任。这也就是说,它不是又双叒叕一个 Linux 发行版,而是一个独特的类 Windows 系统,并且是开源世界的一部分。这份快速指南是给那些想要一个易于使用的 Windows 的开源替代品的人准备的。
|
||||
|
||||
### 安装系统
|
||||
|
||||
在开始安装这个系统之前,我需要说明一下,ReactOS 的最低硬件要求是 500MB 硬盘以及仅仅 96MB 内存。我会在一个 32 位的虚拟机里面演示安装过程。
|
||||
|
||||
现在,你需要使用箭头键来选择你想要语言,而后通过回车键来确认。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_1.png)
|
||||
|
||||
之后,再次敲击回车键来继续安装。你也可以选择按“R”键来修复现有的系统。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_2.png)
|
||||
|
||||
在第三屏中,你将看到一个警告说这个系统还是早期开发版本。再次敲击回车键,你将看到一个需要你最后确认的配置概览。如果你认为没问题,就按回车。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_3.png)
|
||||
|
||||
然后,我们就到了分区这一步,在这里,你可以使用“D”键删除高亮分区,分别使用“P”键、“E”键以及“L”键来添加一个主分区、拓展分区或逻辑分区。如果你想要自己添加一个分区,你需要输入这个分区的大小(以 MB 为单位),然后通过回车来确认。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_4.png)
|
||||
|
||||
但是,如果你有未使用的硬盘空间,在分区过程直接敲击回车键可以自动在你选中的分区上安装 ReactOS。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_5.png)
|
||||
|
||||
下一步是选择分区的格式,不过现在我们只能选择 FAT32。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_6.png)
|
||||
|
||||
再下一步是选择安装文件夹。我就使用默认的“/ReactOS”了,应该没有问题。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_7.png)
|
||||
|
||||
然后就是等待...
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_8.png)
|
||||
|
||||
最后,我们要选择启动程序的安装位置。如果你是在实机上操作的话,第一个选项应该是最安全的。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_9.png)
|
||||
|
||||
总地来说,我认为 ReactOS 的安装向导很直接。尽管安装程序的界面可能看起来一点也不现代、不友好,但是大多数情况下作为用户的我们只需要狂敲回车就能安个差不多。这就是说,ReactOS 的开发版安装起来也是相对简单方便的。
|
||||
|
||||
### 设置 ReactOS
|
||||
|
||||
在我们重启进入新系统之后,“设置向导”会帮助你设置系统。目前,这个向导仅支持设置语言和键盘格式。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_10.png)
|
||||
|
||||
我在这里选择了第二个键盘格式。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_11.png)
|
||||
|
||||
我还可以设置一个改变键盘布局的快捷键。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_12.png)
|
||||
|
||||
之后我添加了用户名…
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_13.png)
|
||||
|
||||
…以及管理员密码…
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_14.png)
|
||||
|
||||
在设置好时间之后,我们就算完成了系统设置。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_15.png)
|
||||
|
||||
### ReactOS 之内
|
||||
|
||||
当我们历经千辛万苦,终于首次进入 ReactOS 的界面时,系统会检测硬件并自动帮助我们安装驱动。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_16.png)
|
||||
|
||||
这是我这里被自动检测出来的三个硬件:
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_17.png)
|
||||
|
||||
在上一张图片里你看到的是 ReactOS 的“应用管理器”,这东西是 Linux 的标配。不过你不会在这里找到任何与 Linux 有关系的东西。只有在这个系统里工作良好的开源软件才会在这个管理器中出现。这就导致了管理器中有的分类下挤得满满当当,有的却冷清异常。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_18.png)
|
||||
|
||||
我试着通过软件中心安装了 Firefox 以及通过直接下载 exe 文件双击安装 Notepad++。这两个应用都能完美运行:它们的图标出现在了桌面上,在菜单中也出现了它们的名字,Notepad++ 也出现在了软件中心右侧的分类栏里。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_19.png)
|
||||
|
||||
我没有尝试运行任何现代的 Windows 游戏,如果你想配置 Direct 3D 的话,你可以转到 “我的电脑/控制选项/WineD3D 配置”。在那里,你能看到很多 Direct3D 选项,大致与 dx 8 的选项类似。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_20.png)
|
||||
|
||||
ReactOS 还有一个好的地方,就是我们可以通过“我的电脑”来操作注册表。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_21.png)
|
||||
|
||||
如果你需要一个简单点的工具,你可以在应用菜单里打开注册表编辑器。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_22.png)
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_23.png)
|
||||
|
||||
最后,如果你认为 ReactOS 看起来有点过时了的话,你可以在桌面右击选择“属性”,之后在“外观”那里选择你喜欢的主题和颜色。
|
||||
|
||||
![](https://www.howtoforge.com/images/getting-started-with-eeactos/pic_24.png)
|
||||
|
||||
### 结论
|
||||
|
||||
老实说,我对 ReactOS 的工作方式印象深刻。它相当稳定、连贯、快速,并且真正人性化。抛开 Windows 的阴影(过时的应用菜单,不合理的菜单结构)不谈的话,ReactOS 几乎做到了尽善尽美。它可能不会有太多应用可供选择,现有的功能也可能不够强大,但是我确信它将会繁荣壮大。关于它的数据显示出了它的人气,我确定将要围绕它建立起来的社区将会很快就壮大到能把这个项目带往成功之路的地步。如今,ReactOS 的最新版本是 0.4.1。如果想要以开源的方式运行 Windows 的应用,那么它就是你的菜!
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/getting-started-with-reactos/
|
||||
|
||||
作者:[Bill Toulas][a]
|
||||
译者:[name1e5s](https://github.com/name1e5s)
|
||||
校对:[PurlingNayuki](https://github.com/PurlingNayuki)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.howtoforge.com/tutorial/getting-started-with-reactos/
|
@ -0,0 +1,141 @@
|
||||
Linux 新手必知必会的 10 条 Linux 基本命令
|
||||
=====================================================================
|
||||
|
||||
![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/4225072_orig.png)
|
||||
|
||||
|
||||
Linux 对我们的生活产生了巨大的冲击。至少你的安卓手机使用的就是 Linux 核心。尽管如此,在第一次开始使用 Linux 时你还是会感到难以下手。因为在 Linux 中,通常需要使用终端命令来取代 Windows 系统中的点击启动图标操作。但是不必担心,这里我们会介绍 10 个 Linux 基本命令来帮助你开启 Linux 神秘之旅。
|
||||
|
||||
|
||||
### 帮助新手走出第一步的 10 个 Linux 基本命令
|
||||
|
||||
当我们谈论 Linux 命令时,实质上是在谈论 Linux 系统本身。这短短的 10 个 Linux 基本命令不会让你变成天才或者 Linux 专家,但是能帮助你轻松开始 Linux 之旅。使用这些基本命令会帮助新手们完成 Linux 的日常任务,由于它们的使用频率如此至高,所以我更乐意称他们为 Linux 命令之王!
|
||||
|
||||
让我们开始学习这 10 条 Linux 基本命令吧。
|
||||
|
||||
|
||||
#### 1. sudo
|
||||
|
||||
这条命令的意思是“以超级用户的身份执行”,是 SuperUserDo 的简写,它是新手将要用到的最重要的一条 Linux 命令。当一条单行命令需要 root 权限的时候,`sudo`命令就派上用场了。你可以在每一条需要 root 权限的命令前都加上`sudo`。
|
||||
|
||||
```
|
||||
$ sudo su
|
||||
```
|
||||
|
||||
|
||||
#### 2. ls (list)
|
||||
|
||||
|
||||
跟其他人一样,你肯定也经常想看看目录下都有些什么东西。使用列表命令,终端会把当前工作目录下所有的文件以及文件夹展示给你。比如说,我当前处在 /home 文件夹中,我想看看 /home 文件夹中都有哪些文件和目录。
|
||||
|
||||
```
|
||||
/home$ ls
|
||||
```
|
||||
|
||||
|
||||
在 /home 中执行`ls`命令将会返回类似下面的内容:
|
||||
|
||||
```
|
||||
imad lost+found
|
||||
```
|
||||
|
||||
|
||||
#### 3. cd
|
||||
|
||||
变更目录命令(cd)是终端中总会被用到的主要命令。它是最常用到的 Linux 基本命令之一。此命令使用非常简单,当你打算从当前目录跳转至某个文件夹时,只需要将文件夹键入此命令之后即可。如果你想跳转至上层目录,只需要在此命令之后键入两个点 (..) 就可以了。
|
||||
|
||||
举个例子,我现在处在 /home 目录中,我想移动到 /home 目录中的 usr 文件夹下,可以通过以下命令来完成操作。
|
||||
|
||||
```
|
||||
/home $ cd usr
|
||||
|
||||
/home/usr $
|
||||
```
|
||||
|
||||
|
||||
#### 4. mkdir
|
||||
|
||||
只是可以切换目录还是不够完美。有时候你会想要新建一个文件夹或子文件夹。此时可以使用 mkdir 命令来完成操作。使用方法很简单,只需要把新的文件夹名跟在 mkdir 命令之后就好了。
|
||||
|
||||
```
|
||||
~$ mkdir folderName
|
||||
```
|
||||
|
||||
|
||||
#### 5. cp
|
||||
|
||||
拷贝-粘贴(copy-and-paste)是我们组织文件需要用到的重要命令。使用 `cp` 命令可以帮助你在终端当中完成拷贝-粘贴操作。首先确定你想要拷贝的文件,然后键入打算粘贴此文件的目标位置。
|
||||
|
||||
```
|
||||
$ cp src des
|
||||
```
|
||||
|
||||
注意:如果目标目录对新建文件需要 root 权限时,你可以使用 `sudo` 命令来完成文件拷贝操作。
|
||||
|
||||
|
||||
#### 6. rm
|
||||
|
||||
rm 命令可以帮助你移除文件甚至目录。如果不希望每删除一个文件都提示确认一次,可以用`-f`参数来强制执行。也可以使用 `-r` 参数来递归的移除文件夹。
|
||||
|
||||
```
|
||||
$ rm myfile.txt
|
||||
```
|
||||
|
||||
|
||||
#### 7. apt-get
|
||||
|
||||
这个命令会依据发行版的不同而有所区别。在基于 Debian 的发行版中,我们拥有 Advanced Packaging Tool(APT)包管理工具来安装、移除和升级包。apt-get 命令会帮助你安装需要在 Linux 系统中运行的软件。它是一个功能强大的命令行,可以用来帮助你对软件执行安装、升级和移除操作。
|
||||
|
||||
在其他发行版中,例如 Fedora、Centos,都各自不同的包管理工具。Fedora 之前使用的是 yum,不过现在 dnf 成了它默认的包管理工具。
|
||||
|
||||
```
|
||||
$ sudo apt-get update
|
||||
|
||||
$ sudo dnf update
|
||||
```
|
||||
|
||||
|
||||
#### 8. grep
|
||||
|
||||
当你需要查找一个文件,但是又忘记了它具体的位置和路径时,`grep` 命令会帮助你解决这个难题。你可以提供文件的关键字,使用`grep`命令来查找到它。
|
||||
|
||||
```
|
||||
$ grep user /etc/passwd
|
||||
```
|
||||
|
||||
|
||||
#### 9. cat
|
||||
|
||||
作为一个用户,你应该会经常需要浏览脚本内的文本或者代码。`cat`命令是 Linux 系统的基本命令之一,它的用途就是将文件的内容展示给你。
|
||||
|
||||
```
|
||||
$ cat CMakeLists.txt
|
||||
```
|
||||
|
||||
|
||||
#### 10. poweroff
|
||||
|
||||
最后一个命令是 `poweroff`。有时你需要直接在终端中执行关机操作。此命令可以完成这个任务。由于关机操作需要 root 权限,所以别忘了在此命令之前添加`sudo`。
|
||||
|
||||
```
|
||||
$ sudo poweroff
|
||||
```
|
||||
|
||||
|
||||
### 总结
|
||||
|
||||
如我在文章开始所言,这 10 条命令并不会让你立即成为一个 Linux 大拿,但它们会让你在初期快速上手 Linux。以这些命令为基础,给自己设置一个目标,每天学习一到三条命令,这就是此文的目的所在。在下方评论区分享有趣并且有用的命令。别忘了跟你的朋友分享此文。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linuxandubuntu.com/home/10-basic-linux-commands-that-every-linux-newbies-should-remember
|
||||
|
||||
作者:[Commenti][a]
|
||||
译者:[mr-ping](https://github.com/mr-ping)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.linuxandubuntu.com/home/10-basic-linux-commands-that-every-linux-newbies-should-remember#comments
|
||||
[1]: http://linuxandubuntu.com/home/category/linux
|
@ -0,0 +1,113 @@
|
||||
惊艳!6款面向儿童的 Linux 发行版
|
||||
======================================
|
||||
|
||||
毫无疑问未来是属于 Linux 和开源的。为了实现这样的未来、使 Linux 占据一席之地,人们已经着手开发尽可能简单的、面向儿童的 Linux 发行版,并尝试教导他们如何使用 Linux 操作系统。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Linux-Distros-For-Kids.png)
|
||||
>面向儿童的 Linux 发行版
|
||||
|
||||
Linux 是一款非常强大的操作系统,原因之一便是它支撑了互联网上绝大多数的服务器。但出于对其用户友好性的担忧,坊间时常展开有关于 Linux 应如何取代 Mac OS X 或 Windows 的争论。而我认为用户应该接受 Linux 来见识它真正的威力。
|
||||
|
||||
如今,Linux 运行在绝大多数设备上,从智能手机到平板电脑,笔记本电脑,工作站,服务器,超级计算机,再到汽车,航空管制系统,电冰箱,到处都有 Linux 的身影。正如我在开篇所说,有了这一切, Linux 是未来的操作系统。
|
||||
|
||||
>参考阅读: [30 Big Companies and Devices Running on Linux][1]
|
||||
|
||||
未来是属于孩子们的,教育要从娃娃抓起。所以,要让小孩子尽早地学习计算机,而 Linux 就是其中一个重要的部分。
|
||||
|
||||
对小孩来说,一个常见的现象是,当他们在一个适合他的环境中学习时,好奇心和早期学习的能力会使他自己养成喜好探索的性格。
|
||||
|
||||
说了这么多儿童应该学习 Linux 的原因,接下来我就列出这些令人激动的发行版。你可以把它们推荐给小孩子来帮助他们开始学习使用 Linux 。
|
||||
|
||||
### Sugar on a Stick
|
||||
|
||||
Sugar on a Stick (译注:“糖棒”)是 Sugar 实验室旗下的工程,Sugar 实验室是一个由志愿者领导的非盈利组织。这一发行版旨在设计大量的免费工具来促进儿童在探索中学会技能,发现、创造,并将这些反映到自己的思想上。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Sugar-Neighborhood-View.png)
|
||||
>Sugar Neighborhood 界面
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Sugar-Activity-Library.png)
|
||||
>Sugar 应用程序
|
||||
|
||||
你既可以将 Sugar 看作是普通的桌面环境,也可以把它当做是帮助鼓励孩子学习、提高参与活动的积极性的一款应用合集。
|
||||
|
||||
访问主页: <https://www.sugarlabs.org/>
|
||||
|
||||
### Edubuntu
|
||||
|
||||
Edubuntu 是基于当下最流行的发行版 Ubuntu 而开发的一款非官方发行版。主要致力于降低学校、家庭和社区安装、使用 Ubuntu 自由软件的难度。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Edubuntu-Apps.jpg)
|
||||
>Edubuntu 桌面应用
|
||||
|
||||
它是由来自不同组织的学生、教师、家长、一些利益相关者甚至黑客支持的,这些人都坚信自由的学习和共享知识能够提高自己和社区的发展。
|
||||
|
||||
该项目的主要目标是通过组建一款能够降低安装、管理软件难度的操作系统来增强学习和教育水平。
|
||||
|
||||
访问主页: <http://www.edubuntu.org/>
|
||||
|
||||
### Doudou Linux
|
||||
|
||||
Doudou Linux 是专为方便孩子们在建设创新思维时使用计算机而设计的发行版。它提供了简单但是颇具教育意义的应用来使儿童在应用过程中学习发现新的知识。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Doudou-Linux.png)
|
||||
>Doudou Linux
|
||||
|
||||
其最引人注目的一点便是内容过滤功能,顾名思义,它能够阻止孩童访问网络上的限制性内容。如果想要更进一步的儿童保护功能,Doudou Linux 还提供了互联网用户隐私功能,能够去除网页中的特定加载内容。
|
||||
|
||||
访问主页: <http://www.doudoulinux.org/>
|
||||
|
||||
### LinuxKidX
|
||||
|
||||
这是一款整合了许多专为儿童设计的教育软件的基于 Slackware Linux 发行版的 LiveCD。它使用 KDE 作为默认桌面环境并配置了诸如 Ktouch 打字指导,Kstars 虚拟天文台,Kalzium 元素周期表和 KwordQuiz 单词测试等应用。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/LinuxKidX.jpg)
|
||||
>LinuxKidX
|
||||
|
||||
访问主页: <http://linuxkidx.blogspot.in/>
|
||||
|
||||
### Ubermix
|
||||
|
||||
Ubermix 基于 Ubuntu 构建,同样以教学为目的。默认配备了超过60款应用,帮助学生更好地学习,同时给教师教学提供便利。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/ubermix.png)
|
||||
>Ubermix Linux
|
||||
|
||||
Ubermix 还具有5分钟快速安装和快速恢复等功能,可以给小孩子更好的帮助。
|
||||
|
||||
访问主页: <http://www.ubermix.org/>
|
||||
|
||||
### Qimo
|
||||
|
||||
因为很多读者曾向我询问过 Qimo 发行版的情况,所以我把它写进这篇文章。但是截止发稿时,Qimo 儿童版的开发已经终止,不再提供更新。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Qimo-Linux.png)
|
||||
>Qimo Linux
|
||||
|
||||
你仍然可以在 Ubuntu 或者其他的 Linux 发行版中找到大多数儿童游戏。正如这些开发商所说,他们并不是要终止为孩子们开发教育软件,而是在开发能够提高儿童读写能力的 android 应用。
|
||||
|
||||
如果你想进一步了解,可以移步他们的官方网站。
|
||||
|
||||
访问主页: <http://www.qimo4kids.com/>
|
||||
|
||||
以上这些便是我所知道的面向儿童的Linux发行版,或有缺漏,欢迎评论补充。
|
||||
|
||||
如果你想让我们知道你对如何想儿童介绍 Linux 或者你对未来的 Linux ,特别是桌面计算机上的 Linux,欢迎与我联系。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/best-linux-distributions-for-kids/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
|
||||
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[HaohongWANG](https://github.com/HaohongWANG)
|
||||
校对:[Ezio](https://github.com/oska874)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: http://www.tecmint.com/big-companies-and-devices-running-on-gnulinux/
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,227 @@
|
||||
使用 OpenCV 识别图片中的猫咪
|
||||
=======================================
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/cat_face_detector_result_04.jpg)
|
||||
|
||||
你知道 OpenCV 可以识别在图片中小猫的脸吗?而且是拿来就能用,不需要其它的库之类的。
|
||||
|
||||
之前我也不知道。
|
||||
|
||||
但是在 [Kendrick Tan 曝出这个功能][1]后,我需要亲自体验一下……去看看到 OpenCV 是如何在我没有察觉到的情况下,将这一个功能添加进了他的软件库(就像一只悄悄溜进空盒子的猫咪一样,等待别人发觉)。
|
||||
|
||||
下面,我将会展示如何使用 OpenCV 的猫咪检测器在图片中识别小猫的脸。同样的,该技术也可以用在视频流中。
|
||||
|
||||
### 使用 OpenCV 在图片中检测猫咪
|
||||
|
||||
如果你查找过 [OpenCV 的代码仓库][3],尤其是在 [haarcascades 目录][4]里(OpenCV 在这里保存处理它预先训练好的 Haar 分类器,以检测各种物体、身体部位等), 你会看到这两个文件:
|
||||
|
||||
- haarcascade_frontalcatface.xml
|
||||
- haarcascade\_frontalcatface\_extended.xml
|
||||
|
||||
这两个 Haar Cascade 文件都将被用来在图片中检测小猫的脸。实际上,我使用了相同的 cascades 分类器来生成这篇博文顶端的图片。
|
||||
|
||||
在做了一些调查工作之后,我发现这些 cascades 分类器是由鼎鼎大名的 [Joseph Howse][5]训练和贡献给 OpenCV 仓库的,他写了很多很棒的教程和书籍,在计算机视觉领域有着很高的声望。
|
||||
|
||||
下面,我将会展示给你如何使用 Howse 的 Haar cascades 分类器来检测图片中的小猫。
|
||||
|
||||
### 猫咪检测代码
|
||||
|
||||
让我们开始使用 OpenCV 来检测图片中的猫咪。新建一个叫 cat_detector.py 的文件,并且输入如下的代码:
|
||||
|
||||
```
|
||||
# import the necessary packages
|
||||
import argparse
|
||||
import cv2
|
||||
|
||||
# construct the argument parse and parse the arguments
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-i", "--image", required=True,
|
||||
help="path to the input image")
|
||||
ap.add_argument("-c", "--cascade",
|
||||
default="haarcascade_frontalcatface.xml",
|
||||
help="path to cat detector haar cascade")
|
||||
args = vars(ap.parse_args())
|
||||
```
|
||||
|
||||
第 2 和第 3 行主要是导入了必要的 python 包。6-12 行用于解析我们的命令行参数。我们仅要求一个必需的参数 `--image` ,它是我们要使用 OpenCV 检测猫咪的图片。
|
||||
|
||||
我们也可以(可选的)通过 `--cascade` 参数指定我们的 Haar cascade 分类器的路径。默认使用 `haarcascades_frontalcatface.xml`,假定这个文件和你的 `cat_detector.py` 在同一目录下。
|
||||
|
||||
注意:我已经打包了猫咪的检测代码,还有在这个教程里的样本图片。你可以在博文原文的 “下载” 部分下载到。如果你是刚刚接触 Python+OpenCV(或者 Haar cascade),我建议你下载这个 zip 压缩包,这个会方便你跟着教程学习。
|
||||
|
||||
接下来,就是检测猫的时刻了:
|
||||
|
||||
```
|
||||
# load the input image and convert it to grayscale
|
||||
image = cv2.imread(args["image"])
|
||||
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
# load the cat detector Haar cascade, then detect cat faces
|
||||
# in the input image
|
||||
detector = cv2.CascadeClassifier(args["cascade"])
|
||||
rects = detector.detectMultiScale(gray, scaleFactor=1.3,
|
||||
minNeighbors=10, minSize=(75, 75))
|
||||
```
|
||||
|
||||
在 15、16 行,我们从硬盘上读取了图片,并且进行灰度化(这是一个在将图片传给 Haar cascade 分类器之前的常用的图片预处理步骤,尽管不是必须的)
|
||||
|
||||
20 行,从硬盘加载 Haar casacade 分类器,即猫咪检测器,并且实例化 `cv2.CascadeClassifier` 对象。
|
||||
|
||||
在 21、22 行通过调用 `detector` 的 `detectMultiScale` 方法使用 OpenCV 完成猫脸检测。我们给 `detectMultiScale` 方法传递了四个参数。包括:
|
||||
|
||||
1. 图片 `gray`,我们要在该图片中检测猫脸。
|
||||
2. 检测猫脸时的[图片金字塔][6] 的检测粒度 `scaleFactor` 。更大的粒度将会加快检测的速度,但是会对检测准确性( true-positive)产生影响。相反的,一个更小的粒度将会影响检测的时间,但是会增加准确性( true-positive)。但是,细粒度也会增加误报率(false-positive)。你可以看这篇博文的“ Haar cascades 注意事项”部分来获得更多的信息。
|
||||
3. `minNeighbors` 参数控制了检定框的最少数量,即在给定区域内被判断为猫脸的最少数量。这个参数可以很好的排除误报(false-positive)结果。
|
||||
4. 最后,`minSize` 参数不言自明。这个值描述每个检定框的最小宽高尺寸(单位是像素),这个例子中就是 75\*75
|
||||
|
||||
`detectMultiScale` 函数会返回 `rects`,这是一个 4 元组列表。这些元组包含了每个检测到的猫脸的 (x,y) 坐标值,还有宽度、高度。
|
||||
|
||||
最后,让我们在图片上画下这些矩形来标识猫脸:
|
||||
|
||||
```
|
||||
# loop over the cat faces and draw a rectangle surrounding each
|
||||
for (i, (x, y, w, h)) in enumerate(rects):
|
||||
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
|
||||
cv2.putText(image, "Cat #{}".format(i + 1), (x, y - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 0, 255), 2)
|
||||
|
||||
# show the detected cat faces
|
||||
cv2.imshow("Cat Faces", image)
|
||||
cv2.waitKey(0)
|
||||
```
|
||||
|
||||
给我们这些框(比如,rects)的数据,我们在 25 行依次遍历它。
|
||||
|
||||
在 26 行,我们在每张猫脸的周围画上一个矩形。27、28 行展示了一个整数,即图片中猫咪的数量。
|
||||
|
||||
最后,31,32 行在屏幕上展示了输出的图片。
|
||||
|
||||
### 猫咪检测结果
|
||||
|
||||
为了测试我们的 OpenCV 猫咪检测器,可以在原文的最后,下载教程的源码。
|
||||
|
||||
然后,在你解压缩之后,你将会得到如下的三个文件/目录:
|
||||
|
||||
1. cat_detector.py:我们的主程序
|
||||
2. haarcascade_frontalcatface.xml: 猫咪检测器 Haar cascade
|
||||
3. images:我们将会使用的检测图片目录。
|
||||
|
||||
到这一步,执行以下的命令:
|
||||
|
||||
```
|
||||
$ python cat_detector.py --image images/cat_01.jpg
|
||||
```
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/cat_face_detector_result_01.jpg)
|
||||
|
||||
*图 1. 在图片中检测猫脸,甚至是猫咪部分被遮挡了。*
|
||||
|
||||
注意,我们已经可以检测猫脸了,即使它的其余部分是被遮挡的。
|
||||
|
||||
试下另外的一张图片:
|
||||
|
||||
```
|
||||
python cat_detector.py --image images/cat_02.jpg
|
||||
```
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/cat_face_detector_result_02.jpg)
|
||||
|
||||
*图 2. 使用 OpenCV 检测猫脸的第二个例子,这次猫脸稍有不同。*
|
||||
|
||||
这次的猫脸和第一次的明显不同,因为它正在发出“喵呜”叫声的当中。这种情况下,我们依旧能检测到正确的猫脸。
|
||||
|
||||
在下面这张图片的结果也是正确的:
|
||||
|
||||
```
|
||||
$ python cat_detector.py --image images/cat_03.jpg
|
||||
```
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/cat_face_detector_result_03.jpg)
|
||||
|
||||
*图 3. 使用 OpenCV 和 python 检测猫脸*
|
||||
|
||||
我们最后的一个样例就是在一张图中检测多张猫脸:
|
||||
|
||||
```
|
||||
$ python cat_detector.py --image images/cat_04.jpg
|
||||
```
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/cat_face_detector_result_04.jpg)
|
||||
|
||||
*图 4. 在同一张图片中使用 OpenCV 检测多只猫*
|
||||
|
||||
注意,Haar cascade 返回的检定框不一定是以你预期的顺序。这种情况下,中间的那只猫会被标记成第三只。你可以通过判断他们的 (x, y) 坐标来自己排序这些检定框。
|
||||
|
||||
#### 关于精度的说明
|
||||
|
||||
在这个 xml 文件中的注释非常重要,Joseph Hower 提到了这个猫脸检测器有可能会将人脸识别成猫脸。
|
||||
|
||||
这种情况下,他推荐使用两种检测器(人脸 & 猫脸),然后将出现在人脸识别结果中的结果剔除掉。
|
||||
|
||||
#### Haar cascades 注意事项
|
||||
|
||||
这个方法首先出现在 Paul Viola 和 Michael Jones 2001 年出版的 [Rapid Object Detection using a Boosted Cascade of Simple Features][7] 论文中。现在它已经成为了计算机识别领域引用最多的论文之一。
|
||||
|
||||
这个算法能够识别图片中的对象,无论它们的位置和比例。而且最令人感兴趣的或许是它能在现有的硬件条件下实现实时检测。
|
||||
|
||||
在他们的论文中,Viola 和 Jones 关注在训练人脸检测器;但是,这个框架也能用来检测各类事物,如汽车、香蕉、路标等等。
|
||||
|
||||
#### 问题是?
|
||||
|
||||
Haar cascades 最大的问题就是如何确定 `detectMultiScale` 方法的参数正确。特别是 `scaleFactor` 和 `minNeighbors` 参数。你很容易陷入一张一张图片调参数的坑,这个就是该对象检测器很难被实用化的原因。
|
||||
|
||||
这个 `scaleFactor` 变量控制了用来检测对象的图片的各种比例的[图像金字塔][8]。如果 `scaleFactor` 参数过大,你就只需要检测图像金字塔中较少的层,这可能会导致你丢失一些在图像金字塔层之间缩放时少了的对象。
|
||||
|
||||
换句话说,如果 `scaleFactor` 参数过低,你会检测过多的金字塔图层。这虽然可以能帮助你检测到更多的对象。但是他会造成计算速度的降低,还会**明显**提高误报率。Haar cascades 分类器就是这样。
|
||||
|
||||
为了避免这个,我们通常使用 [Histogram of Oriented Gradients + 线性 SVM 检测][9] 替代。
|
||||
|
||||
上述的 HOG + 线性 SVM 框架的参数更容易调优。而且更好的误报率也更低,但是唯一不好的地方是无法实时运算。
|
||||
|
||||
### 对对象识别感兴趣?并且希望了解更多?
|
||||
|
||||
![](http://www.pyimagesearch.com/wp-content/uploads/2016/05/custom_object_detector_example.jpg)
|
||||
|
||||
*图 5. 在 PyImageSearch Gurus 课程中学习如何构建自定义的对象识别器。*
|
||||
|
||||
如果你对学习如何训练自己的自定义对象识别器感兴趣,请务必要去了解下 PyImageSearch Gurus 课程。
|
||||
|
||||
在这个课程中,我提供了 15 节课,覆盖了超过 168 页的教程,来教你如何从 0 开始构建自定义的对象识别器。你会掌握如何应用 HOG + 线性 SVM 框架来构建自己的对象识别器来识别路标、面孔、汽车(以及附近的其它东西)。
|
||||
|
||||
要学习 PyImageSearch Gurus 课程(有 10 节示例免费课程),点此:https://www.pyimagesearch.com/pyimagesearch-gurus/?src=post-cat-detection
|
||||
|
||||
### 总结
|
||||
|
||||
在这篇博文里,我们学习了如何使用 OpenCV 默认就有的 Haar cascades 分类器来识别图片中的猫脸。这些 Haar casacades 是由 [Joseph Howse][9] 训练兵贡献给 OpenCV 项目的。我是在 Kendrick Tan 的[这篇文章][10]中开始注意到这个。
|
||||
|
||||
尽管 Haar cascades 相当有用,但是我们也经常用 HOG + 线性 SVM 替代。因为后者相对而言更容易使用,并且可以有效地降低误报率。
|
||||
|
||||
我也会[在 PyImageSearch Gurus 课程中][11]详细的讲述如何构建定制的 HOG + 线性 SVM 对象识别器,来识别包括汽车、路标在内的各种事物。
|
||||
|
||||
不管怎样,我希望你喜欢这篇博文。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.pyimagesearch.com/2016/06/20/detecting-cats-in-images-with-opencv/
|
||||
|
||||
作者:[Adrian Rosebrock][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.pyimagesearch.com/author/adrian/
|
||||
[1]: http://kendricktan.github.io/find-cats-in-photos-using-computer-vision.html
|
||||
[2]: http://www.pyimagesearch.com/2016/06/20/detecting-cats-in-images-with-opencv/#
|
||||
[3]: https://github.com/Itseez/opencv
|
||||
[4]: https://github.com/Itseez/opencv/tree/master/data/haarcascades
|
||||
[5]: http://nummist.com/
|
||||
[6]: http://www.pyimagesearch.com/2015/03/16/image-pyramids-with-python-and-opencv/
|
||||
[7]: https://www.cs.cmu.edu/~efros/courses/LBMV07/Papers/viola-cvpr-01.pdf
|
||||
[8]: http://www.pyimagesearch.com/2015/03/16/image-pyramids-with-python-and-opencv/
|
||||
[9]: http://www.pyimagesearch.com/2014/11/10/histogram-oriented-gradients-object-detection/
|
||||
[10]: http://kendricktan.github.io/find-cats-in-photos-using-computer-vision.html
|
||||
[11]: https://www.pyimagesearch.com/pyimagesearch-gurus/
|
||||
|
||||
|
||||
|
118
published/201607/20160620 Monitor Linux With Netdata.md
Normal file
118
published/201607/20160620 Monitor Linux With Netdata.md
Normal file
@ -0,0 +1,118 @@
|
||||
用 Netdata 监控 Linux
|
||||
=======
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/netdata-945x400.png)
|
||||
|
||||
Netdata 是一个实时的资源监控工具,它拥有基于 web 的友好界面,由 [FireHQL][1] 开发和维护。通过这个工具,你可以通过图表来了解 CPU,RAM,硬盘,网络,Apache, Postfix 等软硬件的资源使用情况。它很像 Nagios 等别的监控软件;但是,Netdata 仅仅支持通过 Web 界面进行实时监控。
|
||||
|
||||
### 了解 Netdata
|
||||
|
||||
目前 Netdata 还没有验证机制,如果你担心别人能从你的电脑上获取相关信息的话,你应该设置防火墙规则来限制访问。UI 很简单,所以任何人看懂图形并理解他们看到的结果,至少你会对它的快速安装印象深刻。
|
||||
|
||||
它的 web 前端响应很快,而且不需要 Flash 插件。 UI 很整洁,保持着 Netdata 应有的特性。第一眼看上去,你能够看到很多图表,幸运的是绝大多数常用的图表数据(像 CPU,RAM,网络和硬盘)都在顶部。如果你想深入了解图形化数据,你只需要下滑滚动条,或者点击在右边菜单的项目。通过每个图表的右下方的按钮, Netdata 还能让你控制图表的显示,重置,缩放。
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2016/06/Capture-1.png)
|
||||
|
||||
*Netdata 图表控制*
|
||||
|
||||
Netdata 并不会占用多少系统资源,它占用的内存不会超过 40MB。因为这个软件是作者用 C 语言写的。
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2016/06/Capture.png)
|
||||
|
||||
*Netdata 显示的内存使用情况*
|
||||
|
||||
### 下载 Netdata
|
||||
|
||||
要下载这个软件,你可以访问 [Netdata 的 GitHub 页面][2],然后点击页面左边绿色的 "Clone or download" 按钮 。你应该能看到以下两个选项:
|
||||
|
||||
#### 通过 ZIP 文件下载
|
||||
|
||||
一种方法是下载 ZIP 文件。它包含仓库里的所有东西。但是如果仓库更新了,你需要重新下载 ZIP 文件。下载完 ZIP 文件后,你要用 `unzip` 命令行工具来解压文件。运行下面的命令能把 ZIP 文件的内容解压到 `netdata` 文件夹。
|
||||
|
||||
```
|
||||
$ cd ~/Downloads
|
||||
$ unzip netdata-master.zip
|
||||
```
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2016/06/Capture-2.png)
|
||||
|
||||
*解压 Netdata*
|
||||
|
||||
没必要在 unzip 命令后加上 `-d` 选项,因为文件都是是放在 ZIP 文件的根文件夹里面。如果没有那个文件夹, unzip 会把所有东西都解压到当前目录下面(这会让文件非常混乱)。
|
||||
|
||||
#### 通过 Git 下载
|
||||
|
||||
还有一种方式是通过 git 下载整个仓库。当然,你的系统需要安装 git。Git 在 Fedora 系统是默认安装的。如果没有安装,你可以用下面的命令在命令行里安装 git。
|
||||
|
||||
```
|
||||
$ sudo dnf install git
|
||||
```
|
||||
|
||||
安装好 git 后,你要把仓库 “clone” 到你的系统里。运行下面的命令。
|
||||
|
||||
```
|
||||
$ git clone https://github.com/firehol/netdata.git
|
||||
```
|
||||
|
||||
这个命令会在当前工作目录克隆(或者说复制一份)仓库。
|
||||
|
||||
### 安装 Netdata
|
||||
|
||||
有些软件包是你成功构造 Netdata 时候需要的。 还好,一行命令就可以安装你所需要的东西([这写在它的安装文档中][3])。在命令行运行下面的命令就能满足安装 Netdata 需要的所有依赖关系。
|
||||
|
||||
```
|
||||
$ dnf install zlib-devel libuuid-devel libmnl-devel gcc make git autoconf autogen automake pkgconfig
|
||||
```
|
||||
|
||||
当所有需要的软件包都安装好了,你就 cd 到 netdata/ 目录,运行 netdata-installer.sh 脚本。
|
||||
|
||||
```
|
||||
$ sudo ./netdata-installer.sh
|
||||
```
|
||||
|
||||
然后就会提示你按回车键,开始安装程序。如果要继续的话,就按下回车吧。
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Capture-3-600x341.png)
|
||||
|
||||
*Netdata 的安装*
|
||||
|
||||
如果一切顺利,你的系统上就已经安装并且运行了 Netdata。安装脚本还会在相应的文件夹里添加一个卸载脚本,叫做 `netdata-uninstaller.sh`。如果你以后不想使用 Netdata,运行这个脚本可以从你的系统里面卸载掉 Netdata。
|
||||
|
||||
你可以通过 systemctl 查看它的运行状态。
|
||||
|
||||
```
|
||||
$ sudo systemctl status netdata
|
||||
```
|
||||
|
||||
### 使用 Netdata
|
||||
|
||||
既然我们已经安装并且运行了 Netdata,你就能够通过 19999 端口来访问 web 界面。下面的截图是我在一个测试机器上运行的 Netdata。
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Capture-4-768x458.png)
|
||||
|
||||
*关于 Netdata 运行时的概览*
|
||||
|
||||
恭喜!你已经成功安装并且能够看到漂亮的外观和图形,以及你的机器性能的高级统计数据。无论是否是你个人的机器,你都可以向你的朋友们炫耀,因为你能够深入的了解你的服务器性能,Netdata 在任何机器上的性能报告都非常出色。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/monitor-linux-netdata/
|
||||
|
||||
作者:[Martino Jones][a]
|
||||
译者:[GitFuture](https://github.com/GitFuture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/monitor-linux-netdata/
|
||||
[1]: https://firehol.org/
|
||||
[2]: https://github.com/firehol/netdata
|
||||
[3]: https://github.com/firehol/netdata/wiki/Installation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,106 @@
|
||||
Android 4.4 移植到了 PowerPC 架构,支持大端架构
|
||||
===========================================================
|
||||
|
||||
eInfochips(一家软件厂商) 已将将 Android 4.4 系统移植到 PowerPC 架构,它将用于一家航空电子客户用来监视引擎的健康状况的人机界面(HMI:Human Machine Interface)。
|
||||
|
||||
eInfochips 已经开发了第一个面向 PowerPC 架构的 CPU 的 Android 移植版本,并支持大端(Big Endian)架构。此移植基于 Android 开源项目 [Android Open Source Project (AOSP)] 中 Android 4.4 (KitKat) 的代码,其功能内核的版本号为 3.12.19。
|
||||
|
||||
Android 开始兴起的时候,PowerPC 正在快速丢失和 ARM 架构共同角逐的市场。高端的网络客户和其它的企业级的嵌入式工具大多运行在诸如飞思卡尔(Freescale)的 PowerQUICC 和 QorIQ 这样的 PowerPC 处理器上,但是并不是 Linux 系统。不过,有几个 Android 的移植计划。在 2009 年,飞思卡尔和 Embedded Alley(一家软件厂商,当前是 Mentor Graphics 的 Linux 团队的一部分)[宣布了针对 PowerQUICC 和 QorIQ 芯片的移植版本][15],当前由 NXP 公司构建。另一个名为 [Android-PowerPC][16] 的项目也作出了相似的工作。
|
||||
|
||||
这些努力来的都并不容易,然而,当航空公司找到 eInfochips,希望能够为他们那些基于 PowerPC 的引擎监控系统添加 Android 应用程序以改善人机界面。该公司找出了这些早期的移植版本,然而,它们都相距甚远。所以,他们不得不从头开始新的移植。
|
||||
|
||||
最主要的问题是这些移植的 Android 版本实在是太老了,和现在的 Android 差别太大了。Embedded Alley 移植的版本为 Android 1.5 (Cupcake),它于 2009 年发布,Linux 内核版本为 2.6.28。而 Android-PowerPC 项目最后一版的移植是 Android 2.2 (Froyo),它于 2010 年发布,内核版本为 2.6.32。此外,航空公司还有一些额外的技术诉求,例如对大端架构(Big Endian)的支持,这种老式的内存访问方式仍旧应用于网络通信和电信行业。然而那些早期的移植版本仅能够支持小端(Little Endian)的内存访问。
|
||||
|
||||
### 来自 eInfochips 的全新 PowerPC 架构移植
|
||||
|
||||
eInfochips, 它最为出名的应该是那些基于 ARM/骁龙处理器的模块计算机板卡,例如 [Eragon 600][17]。 它已经完成了基于 QorIQ 的 Android 4.4 系统移植,且发布了白皮书介绍了该项目。采用该项目的航空电子设备客户仍旧不愿透露名称,目前仍旧不清楚什么时候会公开此该移植版本。
|
||||
|
||||
![](http://files.linuxgizmos.com/einfochips_porting_android_on_powerpc.jpg)
|
||||
|
||||
*图片来自 eInfochips 的博客日志*
|
||||
|
||||
全新的 PowerPC Android 项目包括:
|
||||
|
||||
- 基于 PowerPC [e5500][1] 仿生定制
|
||||
- 基于 Android KitKat 的大端支持
|
||||
- 使用 GCC 5.2 工具链开发
|
||||
- Android 4.4 框架的 PowerPC 支持
|
||||
- PowerPC e5500 的 Android 内核版本为 3.12.19
|
||||
|
||||
根据 eInfochips 的销售经理 Sooryanarayanan Balasubramanian 描述,该航空电子客户想要使用 Android 主要是因为熟悉的界面能够缩减培训的时间,并且让程序更新和增加新程序变得更加容易。他继续解释说:“这次成功的移植了 Android,使得今后的工作仅仅需要在应用层作出修修改改,而不再向以前一样需要在所有层面之间作相互的校验。”,“这是第一次在航空航天工业作出这些尝试,这需要在设计时尽量认真。”
|
||||
|
||||
通过白皮书,可以知道将 Android 移植到 PowerPC 上需要对框架、核心库、开发工具链、运行时链接器、对象链接器和开源编译工具作出大量的修改。在字节码生成阶段,移植团队决定使用便携模式(portable mode)而不是快速解释模式(fast interpreter mode)。这是因为还没有 PowerPC 可用的快速解释模式,而使用开源的 [libffi][18] 的便携模式能够支持 PowerPC。
|
||||
|
||||
同时,团队还面临着在 Android 运行时 (ART) 环境和 Dalvik 虚拟机 (DVM) 环境之间的选择。他们发现,ART 环境下的便携模式还未经测试且缺乏良好的文档支持,所以最终选择了 DVM 环境下的便携模式。
|
||||
|
||||
白皮书中还提及了其它的一些在移植过程中遇到的困难,包括重新开发工具链,重写脚本以解决 AOSP 对编译器标志“非标准”使用的问题。最终完成的移植版本提供了 37 个服务,以及提供了无界面的 Android 部署,在前端使用用户空间的模拟 UI。
|
||||
|
||||
|
||||
### 目标硬件
|
||||
|
||||
感谢来自 [eInfochips 博客日志][2] 的图片(如下图所示),让我们能够确认此 PowerPC 的 Android 移植项目的硬件平台。这个板卡为 [X-ES Xpedite 6101][3],它是一个加固级 XMC/PrPMC 夹层模组。
|
||||
|
||||
![](http://hackerboards.com/files/xes_xpedite6101-sm.jpg)
|
||||
|
||||
*X-ES Xpedite 6101 照片和框图*
|
||||
|
||||
X-ES Xpedite 6101 板卡拥有一个可选的 NXP 公司基于 QorIQ T 系列通信处理器(T2081、T1042 和 T1022),它们分别集成了 8 个、4 个和 2 个 e6500 核心,稍有不同的是,T2081 的处理器主频为 1.8GHz,T1042/22 的处理器主频为 1.4GHz。所有的核心都集成了 AltiVec SIMD 引擎,这也就意味着它能够提供 DSP 级别的浮点运算性能。所有以上 3 款 X-ES 板卡都能够支持最高 8GB 的 DDR3-1600 ECC SDRAM 内存。外加 512MB NOR 和 32GB 的 NAND 闪存。
|
||||
|
||||
![](http://hackerboards.com/files/nxp_qoriq_t2081_block-sm.jpg)
|
||||
|
||||
*NXP T2081 框图*
|
||||
|
||||
板卡的 I/O 包括一个 x4 PCI Express Gen2 通道,以及双工的千兆级网卡、 RS232/422/485 串口和 SATA 3.0 接口。此外,它可选 3 款 QorIQ 处理器,Xpedite 6101 提供了三种 [X-ES 加固等级][19],分别是额定工作温度 0 ~ 55°C, -40 ~ 70°C, 或者是 -40 ~ 85°C,且包含 3 类冲击和抗振类别。
|
||||
|
||||
此外,我们已经介绍过的基于 X-ES QorIQ 的 XMC/PrPMC 板卡包括 [XPedite6401 和 XPedite6370][20],它们支持已有的板卡级 Linux 、风河的 VxWorks(一种实时操作系统) 和 Green Hills 的 Integrity(也是一种操作系统)。
|
||||
|
||||
|
||||
### 更多信息
|
||||
|
||||
eInfochips Android PowerPC 移植白皮书可以[在此][4]下载(需要先免费注册)。
|
||||
|
||||
### 相关资料
|
||||
|
||||
- [Commercial embedded Linux distro boosts virtualization][5]
|
||||
- [Freescale unveils first ARM-based QorIQ SoCs][6]
|
||||
- [High-end boards run Linux on 64-bit ARM QorIQ SoCs][7]
|
||||
- [Free, Open Enea Linux taps Yocto Project and Linaro code][8]
|
||||
- [LynuxWorks reverts to its LynxOS roots, changes name][9]
|
||||
- [First quad- and octa-core QorIQ SoCs unveiled][10]
|
||||
- [Free white paper shows how Linux won embedded][11]
|
||||
- [Quad-core Snapdragon COM offers three dev kit options][12]
|
||||
- [Tiny COM runs Linux on quad-core 64-bit Snapdragon 410][13]
|
||||
- [PowerPC based IoT gateway COM ships with Linux BSP][14]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://hackerboards.com/powerpc-gains-android-4-4-port-with-big-endian-support/
|
||||
|
||||
作者:[Eric Brown][a]
|
||||
译者:[dongfengweixiao](https://github.com/dongfengweixiao)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://hackerboards.com/powerpc-gains-android-4-4-port-with-big-endian-support/
|
||||
[1]: http://linuxdevices.linuxgizmos.com/low-cost-powerquicc-chips-offer-flexible-interconnect-options/
|
||||
[2]: https://www.einfochips.com/blog/k2-categories/aerospace/presenting-a-case-for-porting-android-on-powerpc-architecture.html
|
||||
[3]: http://www.xes-inc.com/products/processor-mezzanines/xpedite6101/
|
||||
[4]: http://biz.einfochips.com/portingandroidonpowerpc
|
||||
[5]: http://hackerboards.com/commercial-embedded-linux-distro-boosts-virtualization/
|
||||
[6]: http://hackerboards.com/freescale-unveils-first-arm-based-qoriq-socs/
|
||||
[7]: http://hackerboards.com/high-end-boards-run-linux-on-64-bit-arm-qoriq-socs/
|
||||
[8]: http://hackerboards.com/free-open-enea-linux-taps-yocto-and-linaro-code/
|
||||
[9]: http://hackerboards.com/lynuxworks-reverts-to-its-lynxos-roots-changes-name/
|
||||
[10]: http://hackerboards.com/first-quad-and-octa-core-qoriq-socs-unveiled/
|
||||
[11]: http://hackerboards.com/free-white-paper-shows-how-linux-won-embedded/
|
||||
[12]: http://hackerboards.com/quad-core-snapdragon-com-offers-three-dev-kit-options/
|
||||
[13]: http://hackerboards.com/tiny-com-runs-linux-and-android-on-quad-core-64-bit-snapdragon-410/
|
||||
[14]: http://hackerboards.com/powerpc-based-iot-gateway-com-ships-with-linux-bsp/
|
||||
[15]: http://linuxdevices.linuxgizmos.com/android-ported-to-powerpc/
|
||||
[16]: http://www.androidppc.com/
|
||||
[17]: http://hackerboards.com/quad-core-snapdragon-com-offers-three-dev-kit-options/
|
||||
[18]: https://sourceware.org/libffi/
|
||||
[19]: http://www.xes-inc.com/capabilities/ruggedization/
|
||||
[20]: http://hackerboards.com/high-end-boards-run-linux-on-64-bit-arm-qoriq-socs/
|
@ -0,0 +1,105 @@
|
||||
Fedora 中的容器技术:systemd-nspawn
|
||||
===
|
||||
|
||||
欢迎来到“Fedora 中的容器技术”系列!本文是该系列文章中的第一篇,它将说明你可以怎样使用 Fedora 中各种可用的容器技术。本文将学习 `systemd-nspawn` 的相关知识。
|
||||
|
||||
### 容器是什么?
|
||||
|
||||
一个容器就是一个用户空间实例,它能够在与托管容器的系统(叫做宿主系统)相隔离的环境中运行一个程序或者一个操作系统。这和 `chroot` 或 [虚拟机][1] 的思想非常类似。运行在容器中的进程是由与宿主操作系统相同的内核来管理的,但它们是与宿主文件系统以及其它进程隔离开的。
|
||||
|
||||
### 什么是 systemd-nspawn?
|
||||
|
||||
systemd 项目认为应当将容器技术变成桌面的基础部分,并且应当和用户的其余系统集成在一起。为此,systemd 提供了 `systemd-nspawn`,这款工具能够使用多种 Linux 技术创建容器。它也提供了一些容器管理工具。
|
||||
|
||||
`systemd-nspawn` 和 `chroot` 在许多方面都是类似的,但是前者更加强大。它虚拟化了文件系统、进程树以及客户系统中的进程间通信。它的吸引力在于它提供了很多用于管理容器的工具,例如用来管理容器的 `machinectl`。由 `systemd-nspawn` 运行的容器将会与 systemd 组件一同运行在宿主系统上。举例来说,一个容器的日志可以输出到宿主系统的日志中。
|
||||
|
||||
在 Fedora 24 上,`systemd-nspawn` 已经从 systemd 软件包分离出来了,所以你需要安装 `systemd-container` 软件包。一如往常,你可以使用 `dnf install systemd-container` 进行安装。
|
||||
|
||||
### 创建容器
|
||||
|
||||
使用 `systemd-nspawn` 创建一个容器是很容易的。假设你有一个专门为 Debian 创造的应用,并且无法在其它发行版中正常运行。那并不是一个问题,我们可以创造一个容器!为了设置容器使用最新版本的 Debian(现在是 Jessie),你需要挑选一个目录来放置你的系统。我暂时将使用目录 `~/DebianJessie`。
|
||||
|
||||
一旦你创建完目录,你需要运行 `debootstrap`,你可以从 Fedora 仓库中安装它。对于 Debian Jessie,你运行下面的命令来初始化一个 Debian 文件系统。
|
||||
|
||||
```
|
||||
$ debootstrap --arch=amd64 stable ~/DebianJessie
|
||||
```
|
||||
|
||||
以上默认你的架构是 x86_64。如果不是的话,你必须将架构的名称改为 `amd64`。你可以使用 `uname -m` 得知你的机器架构。
|
||||
|
||||
一旦设置好你的根目录,你就可以使用下面的命令来启动你的容器。
|
||||
|
||||
```
|
||||
$ systemd-nspawn -bD ~/DebianJessie
|
||||
```
|
||||
|
||||
容器将会在数秒后准备好并运行,当你试图登录时就会注意到:你无法使用你的系统上任何账户。这是因为 `systemd-nspawn` 虚拟化了用户。修复的方法很简单:将之前的命令中的 `-b` 移除即可。你将直接进入容器的 root 用户的 shell。此时,你只能使用 `passwd` 命令为 root 设置密码,或者使用 `adduser` 命令添加一个新用户。一旦设置好密码或添加好用户,你就可以把 `-b` 标志添加回去然后继续了。你会进入到熟悉的登录控制台,然后你使用设置好的认证信息登录进去。
|
||||
|
||||
以上对于任意你想在容器中运行的发行版都适用,但前提是你需要使用正确的包管理器创建系统。对于 Fedora,你应使用 DNF 而非 `debootstrap`。想要设置一个最小化的 Fedora 系统,你可以运行下面的命令,要将“/absolute/path/”替换成任何你希望容器存放的位置。
|
||||
|
||||
```
|
||||
$ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd dnf fedora-release
|
||||
```
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-04-14.png)
|
||||
|
||||
### 设置网络
|
||||
|
||||
如果你尝试启动一个服务,但它绑定了你宿主机正在使用的端口,你将会注意到这个问题:你的容器正在使用和宿主机相同的网络接口。幸运的是,`systemd-nspawn` 提供了几种可以将网络从宿主机分开的方法。
|
||||
|
||||
#### 本地网络
|
||||
|
||||
第一种方法是使用 `--private-network` 标志,它默认仅创建一个回环设备。这对于你不需要使用网络的环境是非常理想的,例如构建系统和其它持续集成系统。
|
||||
|
||||
#### 多个网络接口
|
||||
|
||||
如果你有多个网络接口设备,你可以使用 `--network-interface` 标志给容器分配一个接口。想要给我的容器分配 `eno1`,我会添加选项 `--network-interface=eno1`。当某个接口分配给一个容器后,宿主机就不能同时使用那个接口了。只有当容器彻底关闭后,宿主机才可以使用那个接口。
|
||||
|
||||
#### 共享网络接口
|
||||
|
||||
对于我们中那些并没有额外的网络设备的人来说,还有其它方法可以访问容器。一种就是使用 `--port` 选项。这会将容器中的一个端口定向到宿主机。使用格式是 `协议:宿主机端口:容器端口`,这里的协议可以是 `tcp` 或者 `udp`,`宿主机端口` 是宿主机的一个合法端口,`容器端口` 则是容器中的一个合法端口。你可以省略协议,只指定 `宿主机端口:容器端口`。我通常的用法类似 `--port=2222:22`。
|
||||
|
||||
你可以使用 `--network-veth` 启用完全的、仅宿主机模式的网络,这会在宿主机和容器之间创建一个虚拟的网络接口。你也可以使用 `--network-bridge` 桥接二者的连接。
|
||||
|
||||
### 使用 systemd 组件
|
||||
|
||||
如果你容器中的系统含有 D-Bus,你可以使用 systemd 提供的实用工具来控制并监视你的容器。基础安装的 Debian 并不包含 `dbus`。如果你想在 Debian Jessie 中使用 `dbus`,你需要运行命令 `apt install dbus`。
|
||||
|
||||
#### machinectl
|
||||
|
||||
为了能够轻松地管理容器,systemd 提供了 `machinectl` 实用工具。使用 `machinectl`,你可以使用 `machinectl login name` 登录到一个容器中、使用 `machinectl status name`检查状态、使用 `machinectl reboot name` 启动容器或者使用 `machinectl poweroff name` 关闭容器。
|
||||
|
||||
### 其它 systemd 命令
|
||||
|
||||
多数 systemd 命令,例如 `journalctl`, `systemd-analyze` 和 `systemctl`,都支持使用 `--machine` 选项来指定容器。例如,如果你想查看一个名为 “foobar” 的容器的日志,你可以使用 `journalctl --machine=foobar`。你也可以使用 `systemctl --machine=foobar status service` 来查看运行在这个容器中的服务状态。
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-09-25.png)
|
||||
|
||||
### 和 SELinux 一起工作
|
||||
|
||||
如果你要使用 SELinux 强制模式(Fedora 默认模式),你需要为你的容器设置 SELinux 环境。想要那样的话,你需要在宿主系统上运行下面两行命令。
|
||||
|
||||
```
|
||||
$ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?"
|
||||
$ restorecon -R /path/to/container/
|
||||
```
|
||||
|
||||
确保使用你的容器路径替换 “/path/to/container”。对于我的容器 "DebianJessie",我会运行下面的命令:
|
||||
|
||||
```
|
||||
$ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/DebianJessie(/.*)?"
|
||||
$ restorecon -R /home/johnmh/DebianJessie/
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/
|
||||
|
||||
作者:[John M. Harris, Jr.][a]
|
||||
译者:[ChrisLeeGit](https://github.com/chrisleegit)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/
|
||||
[1]: https://en.wikipedia.org/wiki/Virtual_machine
|
@ -0,0 +1,123 @@
|
||||
如何在 Linux 上永久挂载一个 Windows 共享
|
||||
==================================================
|
||||
|
||||
> 如果你已经厌倦了每次重启 Linux 就得重新挂载 Windows 共享,读读这个让共享永久挂载的简单方法。
|
||||
|
||||
![](http://tr2.cbsistatic.com/hub/i/2016/06/02/e965310b-b38d-43e6-9eac-ea520992138b/68fd9ec5d6731cc405bdd27f2f42848d/linuxadminhero.jpg)
|
||||
|
||||
*图片: Jack Wallen*
|
||||
|
||||
在 Linux 上和一个 Windows 网络进行交互从来就不是件轻松的事情。想想多少企业正在采用 Linux,需要在这两个平台上彼此协作。幸运的是,有了一些工具的帮助,你可以轻松地将 Windows 网络驱动器映射到一台 Linux 机器上,甚至可以确保在重启 Linux 机器之后共享还在。
|
||||
|
||||
### 在我们开始之前
|
||||
|
||||
要实现这个,你需要用到命令行。过程十分简单,但你需要编辑 /etc/fstab 文件,所以小心操作。还有,我假设你已经让 Samba 正常工作了,可以手动从 Windows 网络挂载共享到你的 Linux 机器,还知道这个共享的主机 IP 地址。
|
||||
|
||||
准备好了吗?那就开始吧。
|
||||
|
||||
### 创建你的挂载点
|
||||
|
||||
我们要做的第一件事是创建一个文件夹,他将作为共享的挂载点。为了简单起见,我们将这个文件夹命名为 share,放在 /media 之下。打开你的终端执行以下命令:
|
||||
|
||||
```
|
||||
sudo mkdir /media/share
|
||||
```
|
||||
|
||||
### 安装一些软件
|
||||
|
||||
现在我们得安装允许跨平台文件共享的系统;这个系统是 cifs-utils。在终端窗口输入:
|
||||
|
||||
```
|
||||
sudo apt-get install cifs-utils
|
||||
```
|
||||
|
||||
这个命令同时还会安装 cifs-utils 所有的依赖。
|
||||
|
||||
安装完成之后,打开文件 /etc/nsswitch.conf 并找到这一行:
|
||||
|
||||
```
|
||||
hosts: files mdns4_minimal [NOTFOUND=return] dns
|
||||
```
|
||||
|
||||
编辑这一行,让它看起来像这样:
|
||||
|
||||
```
|
||||
hosts: files mdns4_minimal [NOTFOUND=return] wins dns
|
||||
```
|
||||
|
||||
现在你需要安装 windbind 让你的 Linux 机器可以在 DHCP 网络中解析 Windows 机器名。在终端里执行:
|
||||
|
||||
```
|
||||
sudo apt-get install libnss-windbind windbind
|
||||
```
|
||||
|
||||
用这个命令重启网络服务:
|
||||
|
||||
```
|
||||
sudo service networking restart
|
||||
```
|
||||
|
||||
### 挂载网络驱动器
|
||||
|
||||
现在我们要映射网络驱动器。这里我们必须编辑 /etc/fstab 文件。在你做第一次编辑之前,用这个命令备份以下这个文件:
|
||||
|
||||
```
|
||||
sudo cp /etc/fstab /etc/fstab.old
|
||||
```
|
||||
|
||||
如果你需要恢复这个文件,执行以下命令:
|
||||
|
||||
```
|
||||
sudo mv /etc/fstab.old /etc/fstab
|
||||
```
|
||||
|
||||
在你的主目录创建一个认证信息文件 .smbcredentials。在这个文件里添加你的用户名和密码,就像这样(USER 和 PASSWORD 替换为实际的用户名和密码):
|
||||
|
||||
```
|
||||
username=USER
|
||||
|
||||
password=PASSWORD
|
||||
```
|
||||
|
||||
你需要知道挂载这个驱动器的用户的组 ID(GID)和用户 ID(UID)。执行命令:
|
||||
|
||||
```
|
||||
id USER
|
||||
```
|
||||
|
||||
USER 是你的实际用户名,你应该会看到类似这样的信息:
|
||||
|
||||
```
|
||||
uid=1000(USER) gid=1000(GROUP)
|
||||
```
|
||||
|
||||
USER 是实际的用户名,GROUP 是组名。在(USER)和(GROUP)之前的数字将会被用在 /etc/fstab 文件之中。
|
||||
|
||||
是时候编辑 /etc/fstab 文件了。在你的编辑器中打开那个文件并添加下面这行到文件末尾(替换以下全大写字段以及远程机器的 IP 地址):
|
||||
|
||||
```
|
||||
//192.168.1.10/SHARE /media/share cifs credentials=/home/USER/.smbcredentials,iocharset=uft8,gid=GID,udi=UID,file_mode=0777,dir_mode=0777 0 0
|
||||
```
|
||||
|
||||
**注意**:上面这些内容应该在同一行上。
|
||||
|
||||
保存并关闭那个文件。执行 sudo mount -a 命令,共享将被挂载。检查一下 /media/share,你应该能看到那个网络共享上的文件和文件夹了。
|
||||
|
||||
### 共享很简单
|
||||
|
||||
有了 cifs-utils 和 Samba,映射网络共享在一台 Linux 机器上简单得让人难以置信。现在,你再也不用在每次机器启动的时候手动重新挂载那些共享了。
|
||||
|
||||
更多网络提示和技巧,订阅我们的 Data Center 消息吧。
|
||||
[订阅](https://secure.techrepublic.com/user/login/?regSource=newsletter-button&position=newsletter-button&appId=true&redirectUrl=http%3A%2F%2Fwww.techrepublic.com%2Farticle%2Fhow-to-permanently-mount-a-windows-share-on-linux%2F&)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.techrepublic.com/article/how-to-permanently-mount-a-windows-share-on-linux/
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
译者:[alim0x](https://github.com/alim0x)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.techrepublic.com/search/?a=jack+wallen
|
@ -0,0 +1,63 @@
|
||||
IT 运行在云端,而云运行在 Linux 上。你怎么看?
|
||||
===================================================================
|
||||
|
||||
> IT 正在逐渐迁移到云端。那又是什么驱动了云呢?答案是 Linux。 当连微软的 Azure 都开始拥抱 Linux 时,你就应该知道这一切都已经改变了。
|
||||
|
||||
![](http://zdnet1.cbsistatic.com/hub/i/r/2016/06/24/7d2b00eb-783d-4202-bda2-ca65d45c460a/resize/770xauto/732db8df725ede1cc38972788de71a0b/linux-owns-cloud.jpg)
|
||||
|
||||
*图片: ZDNet*
|
||||
|
||||
不管你接不接受, 云正在接管 IT 已经成为现实。 我们这几年见证了 [ 云在内部 IT 的崛起 ][1] 。 那又是什么驱动了云呢? 答案是 Linux 。
|
||||
|
||||
[Uptime Institute][2] 最近对 1000 个 IT 决策者进行了调查,发现约 50% 左右的资深企业 IT 决策者认为在将来[大部分的 IT 工作应该放在云上 ][3] 或托管网站上。在这个调查中,23% 的人认为这种改变即将发生在明年,有 70% 的人则认为这种情况会在四年内出现。
|
||||
|
||||
这一点都不奇怪。 我们中的许多人仍热衷于我们的物理服务器和机架, 但一般运营一个自己的数据中心并不会产生任何的经济效益。
|
||||
|
||||
很简单, 只需要对比你[运行在你自己的硬件上的资本费用(CAPEX)和使用云的业务费用(OPEX)][4]即可。 但这并不是说你应该把所有的东西都一股脑外包出去,而是说在大多数情况下你应该把许多工作都迁移到云端。
|
||||
|
||||
相应地,如果你想充分地利用云,你就得了解 Linux 。
|
||||
|
||||
[亚马逊的 AWS][5]、 [Apache CloudStack][6]、 [Rackspace][7]、[谷歌的 GCP][8] 以及 [ OpenStack ][9] 的核心都是运行在 Linux 上的。那么结果如何?截至到 2014 年, [在 Linux 服务器上部署的应用达到所有企业的 79% ][10],而 在 Windows 服务器上部署的则跌到 36%。从那时起, Linux 就获得了更多的发展动力。
|
||||
|
||||
即便是微软自身也明白这一点。
|
||||
|
||||
Azure 的技术主管 Mark Russinovich 曾说,仅仅在过去的几年内微软就从[四分之一的 Azure 虚拟机运行在 Linux 上][11] 变为[将近三分之一的 Azure 虚拟机运行在 Linux 上][12]。
|
||||
|
||||
试想一下。微软,一家正逐渐将[云变为自身财政收入的主要来源][13] 的公司,其三分之一的云产业依靠于 Linux 。
|
||||
|
||||
即使是到目前为止, 这些不论喜欢或者不喜欢微软的人都很难想象得到[微软会从一家以商业软件为基础的软件公司转变为一家开源的、基于云服务的企业][14] 。
|
||||
|
||||
Linux 对于这些专用服务器机房的渗透甚至比它刚开始的时候更深了。 举个例子, [Docker 最近发行了其在 Windows 10 和 Mac OS X 上的公测版本 ][15] 。 这难道是意味着 [Docker][16] 将会把其同名的容器服务移植到 Windows 10 和 Mac 上吗? 并不是的。
|
||||
|
||||
在这两个平台上, Docker 只是运行在一个 Linux 虚拟机内部。 在 Mac OS 上是 HyperKit ,在 Windows 上则是 Hyper-V 。 在图形界面上可能看起来就像另一个 Mac 或 Windows 上的应用, 但在其内部的容器仍然是运行在 Linux 上的。
|
||||
|
||||
所以,就像大量的安卓手机和 Chromebook 的用户压根就不知道他们所运行的是 Linux 系统一样。这些 IT 用户也会随之悄然地迁移到 Linux 和云上。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.zdnet.com/article/it-runs-on-the-cloud-and-the-cloud-runs-on-linux-any-questions/
|
||||
|
||||
作者:[Steven J. Vaughan-Nichols][a]
|
||||
译者:[chenxinlong](https://github.com/chenxinlong)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.zdnet.com/meet-the-team/us/steven-j-vaughan-nichols/
|
||||
[1]: http://www.zdnet.com/article/2014-the-year-the-cloud-killed-the-datacenter/
|
||||
[2]: https://uptimeinstitute.com/
|
||||
[3]: http://www.zdnet.com/article/move-to-cloud-accelerating-faster-than-thought-survey-finds/
|
||||
[4]: http://www.zdnet.com/article/rethinking-capex-and-opex-in-a-cloud-centric-world/
|
||||
[5]: https://aws.amazon.com/
|
||||
[6]: https://cloudstack.apache.org/
|
||||
[7]: https://www.rackspace.com/en-us
|
||||
[8]: https://cloud.google.com/
|
||||
[9]: http://www.openstack.org/
|
||||
[10]: http://www.zdnet.com/article/linux-foundation-finds-enterprise-linux-growing-at-windows-expense/
|
||||
[11]: http://news.microsoft.com/bythenumbers/azure-virtual
|
||||
[12]: http://www.zdnet.com/article/microsoft-nearly-one-in-three-azure-virtual-machines-now-are-running-linux/
|
||||
[13]: http://www.zdnet.com/article/microsofts-q3-azure-commercial-cloud-strong-but-earnings-revenue-light/
|
||||
[14]: http://www.zdnet.com/article/why-microsoft-is-turning-into-an-open-source-company/
|
||||
[15]: http://www.zdnet.com/article/new-docker-betas-for-azure-windows-10-now-available/
|
||||
[16]: http://www.docker.com/
|
||||
|
@ -0,0 +1,78 @@
|
||||
用树莓派计算模块搭建的工业单板计算机
|
||||
=====================================================
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi-thm.jpg)
|
||||
|
||||
在 Kickstarter 众筹网站上,一个叫 “MyPi” 的项目用树莓派计算模块制作了一款 SBC(LCTT 译注: Single Board Computer 单板计算机),提供一个 mini-PCIe 插槽,串口,宽范围输入电源,以及模块扩展等功能。
|
||||
|
||||
你也许觉得奇怪,都 2016 年了,为什么还会有人发布这样一款长得有点像三明治,用过时的 ARM11 构建的 COM (LCTT 译注: Compuer on Module,模块化计算机)版本的树莓派单板计算机:[树莓派计算模块][1]。原因是这样的,首先,目前仍然有大量工业应用不需要太多 CPU 处理能力,第二,树莓派计算模块仍是目前仅有的基于树莓派硬件的 COM,虽然更便宜、有点像 COM 并采用同样的 700MHz 处理器的 [零号树莓派][2] 也很类似。
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi-sm.jpg)
|
||||
|
||||
*安装了 COM 和 I/O 组件的 MyPi*
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_encl-sm.jpg)
|
||||
|
||||
*装入了可选的工业外壳中*
|
||||
|
||||
另外,Embedded Micro Technology 还表示它的 SBC 还设计成可升级替换为支持的树莓派计算模块 —— 采用了树莓派 3 的四核、Cortex-A53 博通 BCM2837处理器的 SoC。因为这个产品最近很快就会到货,不确定他们怎么能及时为 Kickstarter 赞助者处理好这一切。不过,以后能支持也挺不错,就算要为这个升级付费也可以接受。
|
||||
|
||||
MyPi 并不是唯一一款新的基于树莓派计算模块的商业嵌入式设备。Pigeon Computers 在五月份启动了 [Pigeon RB100][3] 的项目,是一个基于 COM 的工业自动化控制器。不过,包括 [Techbase Modberry][4] 在内的这一类设备大都出现在 2014 年 COM 发布之后的一小段时间内。
|
||||
|
||||
MyPi 的目标是 30 天内筹集 $21,696,目前已经实现了三分之一。早期参与包的价格 $119 起,九月份发货。其他选项有 $187 版本,里面包含了价值 $30 的树莓派计算模块,以及各种线缆。套件里还有各种插件板以及工业外壳可选。
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_baseboard-sm.jpg)
|
||||
|
||||
*不带 COM 和插件板的 MyPi 主板*
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_detail-sm.jpg)
|
||||
|
||||
*以及它的接口定义*
|
||||
|
||||
树莓派计算模块能给 MyPi 带来博通 BCM2835 Soc,512MB 内存,以及 4GB eMMC 存储空间。MyPi 主板扩展了一个 microSD 卡槽,一个 HDMI 接口,两个 USB 2.0 接口,一个 10/100M 以太网口,还有一个像网口的 RS232 端口(通过 USB 连接)。
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_angle1-sm.jpg)
|
||||
|
||||
*插上树莓派计算模块和 mini-PCIe 模块的 MyPi 的两个视角*
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_angle2.jpg)
|
||||
|
||||
*插上树莓派计算模块和 mini-PCIe 模块的 MyPi 的两个视角*
|
||||
|
||||
MyPi 还将配备一个 mini-PCIe 插槽,据说“只支持 USB,以及只适用 mPCIe 形式的调制解调器”。还带有一个 SIM 卡插槽。板上还有双标准的树莓派摄像头接口,一个音频输出接口,自带备用电池的 RTC,LED 灯。还支持宽范围的 9-23V 直流输入。
|
||||
|
||||
Embedded Micro 表示,MyPi 是为那些树莓派爱好者们设计的,他们拼接了太多 HAT 外接板,已经不能有效地工作了,或者不能很好地装入工业外壳里。MyPi 支持 HAT,另外还提供了公司自己定义的 “ASIO” (特定应用接口)插件模块,它会将自己的 I/O 扩展到载板上,载板再将它们连到载板边上的 8针的绿色凤凰式工业 I/O 连接器(标记了“ASIO Out”)上,在下面图片里有描述。
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_io-sm.jpg)
|
||||
|
||||
*MyPi 的模块扩展接口*
|
||||
|
||||
就像 Kickstarter 页面里描述的:“比起在板边插满带 IO 信号接头的 HAT 板,我们更愿意把同样的 IO 信号接到另一个接头,它直接接到绿色的工业接头上。” 另外,“通过简单地延长卡上的插脚长度(抬高),你将来可以直接扩展 IO 集 - 这些都不需要任何排线!”Embedded Micro 表示。
|
||||
|
||||
![](http://hackerboards.com/files/embeddedmicro_mypi_with_iocards-sm.jpg)
|
||||
|
||||
*MyPi 和它的可选 I/O 插件板卡*
|
||||
|
||||
像上面展示的,这家公司为 MyPi 提供了一系列可靠的 ASIO 插卡,。一开始这些会包括 CAN 总线,4-20mA 传感器信号,RS485,窄带 RF,等等。
|
||||
|
||||
### 更多信息
|
||||
|
||||
MyPi 在 Kickstarter 上提供了 7 月 23 日到期的 79 英镑($119)早期参与包(不包括树莓派计算模块),预计九月份发货。更多信息请查看 [Kickstarter 上 MyPi 的页面][5] 以及 [Embedded Micro Technology 官网][6]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://hackerboards.com/industrial-sbc-builds-on-rpi-compute-module/
|
||||
|
||||
作者:[Eric Brown][a]
|
||||
译者:[zpl1025](https://github.com/zpl1025)
|
||||
校对:[Ezio](https://github.com/oska874)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://hackerboards.com/industrial-sbc-builds-on-rpi-compute-module/
|
||||
[1]: http://hackerboards.com/raspberry-pi-morphs-into-30-dollar-com/
|
||||
[2]: http://hackerboards.com/pi-zero-tweak-adds-camera-connector-keeps-5-price/
|
||||
[3]: http://hackerboards.com/automation-controller-runs-linux-on-raspberry-pi-com/
|
||||
[4]: http://hackerboards.com/automation-controller-taps-raspberry-pi-compute-module/
|
||||
[5]: https://www.kickstarter.com/projects/410598173/mypi-industrial-strength-raspberry-pi-for-iot-proj
|
||||
[6]: http://www.embeddedpi.com/
|
@ -0,0 +1,126 @@
|
||||
如何隐藏你的 Linux 的命令行历史
|
||||
================================================================
|
||||
|
||||
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/06/commandline-history-featured.jpg)
|
||||
|
||||
如果你是 Linux 命令行的用户,有的时候你可能不希望某些命令记录在你的命令行历史中。原因可能很多,例如,你在公司担任某个职位,你有一些不希望被其它人滥用的特权。亦或者有些特别重要的命令,你不希望在你浏览历史列表时误执行。
|
||||
|
||||
然而,有方法可以控制哪些命令进入历史列表,哪些不进入吗?或者换句话说,我们在 Linux 终端中可以开启像浏览器一样的无痕模式吗?答案是肯定的,而且根据你想要的具体目标,有很多实现方法。在这篇文章中,我们将讨论一些行之有效的方法。
|
||||
|
||||
注意:文中出现的所有命令都在 Ubuntu 下测试过。
|
||||
|
||||
### 不同的可行方法
|
||||
|
||||
前面两种方法已经在之前[一篇文章][1]中描述了。如果你已经了解,这部分可以略过。然而,如果你不了解,建议仔细阅读。
|
||||
|
||||
#### 1. 在命令前插入空格
|
||||
|
||||
是的,没看错。在命令前面插入空格,这条命令会被 shell 忽略,也就意味着它不会出现在历史记录中。但是这种方法有个前提,只有在你的环境变量 `HISTCONTROL` 设置为 "ignorespace" 或者 "ignoreboth" 才会起作用。在大多数情况下,这个是默认值。
|
||||
|
||||
所以,像下面的命令(LCTT 译注:这里`[space]`表示输入一个空格):
|
||||
|
||||
```
|
||||
[space]echo "this is a top secret"
|
||||
```
|
||||
|
||||
如果你之前执行过如下设置环境变量的命令,那么上述命令不会出现在历史记录中。
|
||||
|
||||
```
|
||||
export HISTCONTROL = ignorespace
|
||||
```
|
||||
|
||||
下面的截图是这种方式的一个例子。
|
||||
|
||||
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/06/commandline-history-bash-command-space.png)
|
||||
|
||||
第四个 "echo" 命令因为前面有空格,它没有被记录到历史中。
|
||||
|
||||
#### 2. 禁用当前会话的所有历史记录
|
||||
|
||||
如果你想禁用某个会话所有历史,你可以在开始命令行工作前简单地清除环境变量 HISTFILESIZE 的值即可。执行下面的命令来清除其值:
|
||||
|
||||
```
|
||||
export HISTFILESIZE=0
|
||||
```
|
||||
|
||||
HISTFILESIZE 表示对于 bash 会话其历史文件中可以保存命令的个数(行数)。默认情况,它设置了一个非零值,例如在我的电脑上,它的值为 1000。
|
||||
|
||||
所以上面所提到的命令将其值设置为 0,结果就是直到你关闭终端,没有东西会存储在历史记录中。记住同样你也不能通过按向上的箭头按键或运行 history 命令来看到之前执行的命令。
|
||||
|
||||
#### 3. 工作结束后清除整个历史
|
||||
|
||||
这可以看作是前一部分所提方案的另外一种实现。唯一的区别是在你完成所有工作之后执行这个命令。下面是刚说到的命令:
|
||||
|
||||
```
|
||||
history -cw
|
||||
```
|
||||
|
||||
刚才已经提到,这个和 HISTFILESIZE 方法有相同效果。
|
||||
|
||||
#### 4. 只针对你的工作关闭历史记录
|
||||
|
||||
虽然前面描述的方法(2 和 3)可以实现目的,它们可以清除整个历史,在很多情况下,有些可能不是我们所期望的。有时候你可能想保存直到你开始命令行工作之间的历史记录。对于这样的需求,你开始在工作前执行下述命令:
|
||||
|
||||
```
|
||||
[space]set +o history
|
||||
```
|
||||
|
||||
备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录。
|
||||
|
||||
上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。
|
||||
|
||||
要重新开启历史功能,执行下面的命令:
|
||||
|
||||
```
|
||||
[Space]set -o history
|
||||
```
|
||||
|
||||
它将环境恢复原状,也就是你完成了你的工作,执行上述命令之后的命令都会出现在历史中。
|
||||
|
||||
#### 5. 从历史记录中删除指定的命令
|
||||
|
||||
现在假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办?很简单。直接动手删除它们。通过下面的命令来删除:
|
||||
|
||||
```
|
||||
history | grep "part of command you want to remove"
|
||||
```
|
||||
|
||||
上面的命令会输出历史记录中匹配的命令,每一条前面会有个数字。
|
||||
|
||||
一旦你找到你想删除的命令,执行下面的命令,从历史记录中删除那个指定的项:
|
||||
|
||||
```
|
||||
history -d [num]
|
||||
```
|
||||
|
||||
下面是这个例子的截图。
|
||||
|
||||
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/06/commandline-history-delete-specific-commands.png)
|
||||
|
||||
第二个 ‘echo’命令被成功的删除了。
|
||||
|
||||
(LCTT 译注:如果你不希望上述命令本身也被记录进历史中,你可以在上述命令前加个空格)
|
||||
|
||||
同样的,你可以使用向上的箭头一直往回翻看历史记录。当你发现你感兴趣的命令出现在终端上时,按下 “Ctrl + U”清除整行,也会从历史记录中删除它。
|
||||
|
||||
### 总结
|
||||
|
||||
有多种不同的方法可以操作 Linux 命令行历史来满足你的需求。然而请记住,从历史中隐藏或者删除命令通常不是一个好习惯,尽管本质上这并没有错。但是你必须知道你在做什么,以及可能产生的后果。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.maketecheasier.com/linux-command-line-history-incognito/
|
||||
|
||||
作者:[Himanshu Arora][a]
|
||||
译者:[chunyang-wen](https://github.com/chunyang-wen)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.maketecheasier.com/author/himanshu/
|
||||
[1]: https://www.maketecheasier.com/command-line-history-linux/
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,101 @@
|
||||
如何在 Ubuntu Linux 16.04上安装开源的 Discourse 论坛
|
||||
===============================================================================
|
||||
|
||||
Discourse 是一个开源的论坛,它可以以邮件列表、聊天室或者论坛等多种形式工作。它是一个广受欢迎的现代的论坛工具。在服务端,它使用 Ruby on Rails 和 Postgres 搭建, 并且使用 Redis 缓存来减少读取时间 , 在客户端,它使用支持 Java Script 的浏览器。它非常容易定制,结构良好,并且它提供了转换插件,可以对你现存的论坛、公告板进行转换,例如: vBulletin、phpBB、Drupal、SMF 等等。在这篇文章中,我们将学习在 Ubuntu 操作系统下安装 Discourse。
|
||||
|
||||
它以安全作为设计思想,所以发垃圾信息的人和黑客们不能轻易的实现其企图。它能很好的支持各种现代设备,并可以相应的调整以手机和平板的显示。
|
||||
|
||||
### 在 Ubuntu 16.04 上安装 Discourse
|
||||
|
||||
让我们开始吧 ! 最少需要 1G 的内存,并且官方支持的安装过程需要已经安装了 docker。 说到 docker,它还需要安装Git。要满足以上的两点要求我们只需要运行下面的命令:
|
||||
|
||||
```
|
||||
wget -qO- https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/124.png)
|
||||
|
||||
用不了多久就安装好了 docker 和 Git,安装结束以后,在你的系统上的 /var 分区创建一个 Discourse 文件夹(当然你也可以选择其他的分区)。
|
||||
|
||||
```
|
||||
mkdir /var/discourse
|
||||
```
|
||||
|
||||
现在我们来克隆 Discourse 的 Github 仓库到这个新建的文件夹。
|
||||
|
||||
```
|
||||
git clone https://github.com/discourse/discourse_docker.git /var/discourse
|
||||
```
|
||||
|
||||
进入这个克隆的文件夹。
|
||||
|
||||
```
|
||||
cd /var/discourse
|
||||
```
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/314.png)
|
||||
|
||||
你将看到“discourse-setup” 脚本文件,运行这个脚本文件进行 Discourse 的初始化。
|
||||
|
||||
```
|
||||
./discourse-setup
|
||||
```
|
||||
|
||||
**备注: 在安装 discourse 之前请确保你已经安装好了邮件服务器。**
|
||||
|
||||
安装向导将会问你以下六个问题:
|
||||
|
||||
```
|
||||
Hostname for your Discourse?
|
||||
Email address for admin account?
|
||||
SMTP server address?
|
||||
SMTP user name?
|
||||
SMTP port [587]:
|
||||
SMTP password? []:
|
||||
```
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/411.png)
|
||||
|
||||
当你提交了以上信息以后, 它会让你提交确认, 如果一切都很正常,点击回车以后安装开始。
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/511.png)
|
||||
|
||||
现在“坐等放宽”,需要花费一些时间来完成安装,倒杯咖啡,看看有什么错误信息没有。
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/610.png)
|
||||
|
||||
安装成功以后看起来应该像这样。
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/710.png)
|
||||
|
||||
现在打开浏览器,如果已经做了域名解析,你可以使用你的域名来连接 Discourse 页面 ,否则你只能使用IP地址了。你将看到如下信息:
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/85.png)
|
||||
|
||||
就是这个,点击 “Sign Up” 选项创建一个新的账户,然后进行你的 Discourse 设置。
|
||||
|
||||
![](http://linuxpitstop.com/wp-content/uploads/2016/06/106.png)
|
||||
|
||||
### 结论
|
||||
|
||||
它安装简便,运行完美。 它拥有现代论坛所有必备功能。它以 GPL 发布,是完全开源的产品。简单、易用、以及特性丰富是它的最大特点。希望你喜欢这篇文章,如果有问题,你可以给我们留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxpitstop.com/install-discourse-on-ubuntu-linux-16-04/
|
||||
|
||||
作者:[Aun][a]
|
||||
译者:[kokialoves](https://github.com/kokialoves)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://linuxpitstop.com/author/aun/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
在 Linux 下使用任务管理器
|
||||
====================================
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/06/Task-Manager-in-Linux.jpg)
|
||||
|
||||
有很多 Linux 初学者经常问起的问题,“**Linux 有任务管理器吗?**”,“**怎样在 Linux 上打开任务管理器呢?**”
|
||||
|
||||
来自 Windows 的用户都知道任务管理器非常有用。你可以在 Windows 中按下 `Ctrl+Alt+Del` 打开任务管理器。这个任务管理器向你展示了所有的正在运行的进程和它们消耗的内存,你可以从任务管理器程序中选择并杀死一个进程。
|
||||
|
||||
当你刚使用 Linux 的时候,你也会寻找一个**在 Linux 相当于任务管理器**的一个东西。一个 Linux 使用专家更喜欢使用命令行的方式查找进程和消耗的内存等等,但是你不用必须使用这种方式,至少在你初学 Linux 的时候。
|
||||
|
||||
所有主流的 Linux 发行版都有一个类似于任务管理器的东西。大部分情况下,它叫系统监视器(System Monitor),不过实际上它依赖于你的 Linux 的发行版及其使用的[桌面环境][1]。
|
||||
|
||||
在这篇文章中,我们将会看到如何在以 GNOME 为[桌面环境][2]的 Linux 上找到并使用任务管理器。
|
||||
|
||||
### 在使用 GNOME 桌面环境的 Linux 上的任务管理器等价物
|
||||
|
||||
使用 GNOME 时,按下 super 键(Windows 键)来查找任务管理器:
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/06/system-monitor-gnome-fedora.png)
|
||||
|
||||
当你启动系统监视器的时候,它会向你展示所有正在运行的进程及其消耗的内存。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/06/fedora-system-monitor.jpeg)
|
||||
|
||||
你可以选择一个进程并且点击“终止进程(End Process)”来杀掉它。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/06/kill-process-fedora.png)
|
||||
|
||||
你也可以在资源(Resources)标签里面看到关于一些统计数据,例如 CPU 的每个核心的占用,内存用量、网络用量等。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/06/system-stats-fedora.png)
|
||||
|
||||
这是图形化的方式。如果你想使用命令行,在终端里运行“top”命令然后你就可以看到所有运行的进程及其消耗的内存。你也可以很容易地使用命令行[杀死进程][3]。
|
||||
|
||||
这就是关于在 Fedora Linux 上任务管理器的知识。我希望这个教程帮你学到了知识,如果你有什么问题,请尽管问。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/task-manager-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[xinglianfly](https://github.com/xinglianfly)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject)原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[1]: https://wiki.archlinux.org/index.php/desktop_environment
|
||||
[2]: https://itsfoss.com/best-linux-desktop-environments/
|
||||
[3]: https://itsfoss.com/how-to-find-the-process-id-of-a-program-and-kill-it-quick-tip/
|
31
published/201607/20160630 What makes up the Fedora kernel.md
Normal file
31
published/201607/20160630 What makes up the Fedora kernel.md
Normal file
@ -0,0 +1,31 @@
|
||||
Fedora 内核是由什么构成的?
|
||||
====================================
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/kernel-945x400.png)
|
||||
|
||||
每个 Fedora 系统都运行着一个内核。许多代码片段组合在一起使之成为现实。
|
||||
|
||||
每个 Fedora 内核都起始于一个来自于[上游社区][1]的基线版本——通常称之为 vanilla 内核。上游内核就是标准。(Fedora 的)目标是包含尽可能多的上游代码,这样使得 bug 修复和 API 更新更加容易,同时也会有更多的人审查代码。理想情况下,Fedora 能够直接获取 kernel.org 的内核,然后发送给所有用户。
|
||||
|
||||
现实情况是,使用 vanilla 内核并不能完全满足 Fedora。Vanilla 内核可能并不支持一些 Fedora 用户希望拥有的功能。用户接收的 [Fedora 内核] 是在 vanilla 内核之上打了很多补丁的内核。这些补丁被认为“不在树上(out of tree)”。许多这些位于补丁树之外的补丁都不会存在太久。如果某补丁能够修复一个问题,那么该补丁可能会被合并到 Fedora 树,以便用户能够更快地收到修复。当内核变基到一个新版本时,在新版本中的补丁都将被清除。
|
||||
|
||||
一些补丁会在 Fedora 内核树上存在很长时间。一个很好的例子是,安全启动补丁就是这类补丁。这些补丁提供了 Fedora 希望支持的功能,即使上游社区还没有接受它们。保持这些补丁更新是需要付出很多努力的,所以 Fedora 尝试减少不被上游内核维护者接受的补丁数量。
|
||||
|
||||
通常来说,想要在 Fedora 内核中获得一个补丁的最佳方法是先给 [Linux 内核邮件列表(LKML)][3] 发送补丁,然后请求将该补丁包含到 Fedora 中。如果某个维护者接受了补丁,就意味着 Fedora 内核树中将来很有可能会包含该补丁。一些来自于 GitHub 等地方的还没有提交给 LKML 的补丁是不可能进入内核树的。首先向 LKML 发送补丁是非常重要的,它能确保 Fedora 内核树中携带的补丁是功能正常的。如果没有社区审查,Fedora 最终携带的补丁将会充满 bug 并会导致问题。
|
||||
|
||||
Fedora 内核中包含的代码来自许多地方。一切都需要提供最佳的体验。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/makes-fedora-kernel/
|
||||
|
||||
作者:[Laura Abbott][a]
|
||||
译者:[ChrisLeeGit](https://github.com/chrisleegit)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/makes-fedora-kernel/
|
||||
[1]: http://www.kernel.org/
|
||||
[2]: http://pkgs.fedoraproject.org/cgit/rpms/kernel.git/
|
||||
[3]: http://www.labbott.name/blog/2015/10/02/the-art-of-communicating-with-lkml/
|
@ -0,0 +1,144 @@
|
||||
如何在 Ubuntu 上建立网桥
|
||||
=======================================================================
|
||||
|
||||
> 作为一个 Ubuntu 16.04 LTS 的初学者。如何在 Ubuntu 14.04 和 16.04 的主机上建立网桥呢?
|
||||
|
||||
顾名思义,网桥的作用是通过物理接口连接内部和外部网络。对于虚拟端口或者 LXC/KVM/Xen/容器来说,这非常有用。网桥虚拟端口看起来是网络上的一个常规设备。在这个教程中,我将会介绍如何在 Ubuntu 服务器上通过 bridge-utils (brctl) 命令行来配置 Linux 网桥。
|
||||
|
||||
### 网桥化的网络示例
|
||||
|
||||
![](http://s0.cyberciti.org/uploads/faq/2016/07/my-br0-br1-setup.jpg)
|
||||
|
||||
*图 01: Kvm/Xen/LXC 容器网桥示例 (br0)*
|
||||
|
||||
在这个例子中,eth0 和 eth1 是物理网络接口。eth0 连接着局域网,eth1 连接着上游路由器和互联网。
|
||||
|
||||
### 安装 bridge-utils
|
||||
|
||||
使用 [apt-get 命令][1] 安装 bridge-utils:
|
||||
|
||||
```
|
||||
$ sudo apt-get install bridge-utils
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
````
|
||||
$ sudo apt install bridge-utils
|
||||
```
|
||||
|
||||
样例输出:
|
||||
|
||||
![](http://s0.cyberciti.org/uploads/faq/2016/07/ubuntu-install-bridge-utils.jpg)
|
||||
|
||||
*图 02: Ubuntu 安装 bridge-utils 包*
|
||||
|
||||
### 在 Ubuntu 服务器上创建网桥
|
||||
|
||||
使用你熟悉的文本编辑器修改 `/etc/network/interfaces` ,例如 vi 或者 nano :
|
||||
|
||||
```
|
||||
$ sudo cp /etc/network/interfaces /etc/network/interfaces.bakup-1-july-2016
|
||||
$ sudo vi /etc/network/interfaces
|
||||
```
|
||||
|
||||
接下来设置 eth1 并且将它映射到 br1 ,输入如下(删除或者注释所有 eth1 相关配置):
|
||||
|
||||
```
|
||||
# br1 使用静态公网 IP 地址,并以 ISP 的路由器作为网关
|
||||
auto br1
|
||||
iface br1 inet static
|
||||
address 208.43.222.51
|
||||
network 255.255.255.248
|
||||
netmask 255.255.255.0
|
||||
broadcast 208.43.222.55
|
||||
gateway 208.43.222.49
|
||||
bridge_ports eth1
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
bridge_maxwait 0
|
||||
```
|
||||
|
||||
接下来设置 eth0 并将它映射到 br0,输入如下(删除或者注释所有 eth0 相关配置):
|
||||
|
||||
```
|
||||
auto br0
|
||||
iface br0 inet static
|
||||
address 10.18.44.26
|
||||
netmask 255.255.255.192
|
||||
broadcast 10.18.44.63
|
||||
dns-nameservers 10.0.80.11 10.0.80.12
|
||||
# set static route for LAN
|
||||
post-up route add -net 10.0.0.0 netmask 255.0.0.0 gw 10.18.44.1
|
||||
post-up route add -net 161.26.0.0 netmask 255.255.0.0 gw 10.18.44.1
|
||||
bridge_ports eth0
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
bridge_maxwait 0
|
||||
```
|
||||
|
||||
### 关于 br0 和 DHCP 的一点说明
|
||||
|
||||
如果使用 DHCP ,配置选项是这样的:
|
||||
|
||||
```
|
||||
auto br0
|
||||
iface br0 inet dhcp
|
||||
bridge_ports eth0
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
bridge_maxwait 0
|
||||
```
|
||||
|
||||
保存并且关闭文件。
|
||||
|
||||
### 重启服务器或者网络服务
|
||||
|
||||
你需要重启服务器或者输入下列命令来重启网络服务(在 SSH 登录的会话中这可能不管用):
|
||||
|
||||
```
|
||||
$ sudo systemctl restart networking
|
||||
```
|
||||
|
||||
如果你证使用 Ubuntu 14.04 LTS 或者更老的没有 systemd 的系统,输入:
|
||||
|
||||
```
|
||||
$ sudo /etc/init.d/restart networking
|
||||
```
|
||||
|
||||
### 验证网络配置成功
|
||||
|
||||
使用 ping/ip 命令来验证 LAN 和 WAN 网络接口运行正常:
|
||||
```
|
||||
# 查看 br0 和 br1
|
||||
ip a show
|
||||
# 查看路由信息
|
||||
ip r
|
||||
# ping 外部站点
|
||||
ping -c 2 cyberciti.biz
|
||||
# ping 局域网服务器
|
||||
ping -c 2 10.0.80.12
|
||||
```
|
||||
|
||||
样例输出:
|
||||
|
||||
![](http://s0.cyberciti.org/uploads/faq/2016/07/br0-br1-eth0-eth1-configured-on-ubuntu.jpg)
|
||||
|
||||
*图 03: 验证网桥的以太网连接*
|
||||
|
||||
现在,你就可以配置 br0 和 br1 来让 XEN/KVM/LXC 容器访问因特网或者私有局域网了。再也没有必要去设置特定路由或者 iptables 的 SNAT 规则了。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.cyberciti.biz/faq/how-to-create-bridge-interface-ubuntu-linux/
|
||||
|
||||
作者:[VIVEK GITE][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://twitter.com/nixcraft
|
||||
[1]: http://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html
|
||||
|
@ -0,0 +1,228 @@
|
||||
使用 Python 创建你自己的 Shell (一)
|
||||
==========================================
|
||||
|
||||
我很想知道一个 shell (像 bash,csh 等)内部是如何工作的。于是为了满足自己的好奇心,我使用 Python 实现了一个名为 **yosh** (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。
|
||||
|
||||
(提示:你可以在[这里](https://github.com/supasate/yosh)查找本博文使用的源代码,代码以 MIT 许可证发布。在 Mac OS X 10.11.5 上,我使用 Python 2.7.10 和 3.4.3 进行了测试。它应该可以运行在其他类 Unix 环境,比如 Linux 和 Windows 上的 Cygwin。)
|
||||
|
||||
让我们开始吧。
|
||||
|
||||
### 步骤 0:项目结构
|
||||
|
||||
对于此项目,我使用了以下的项目结构。
|
||||
|
||||
```
|
||||
yosh_project
|
||||
|-- yosh
|
||||
|-- __init__.py
|
||||
|-- shell.py
|
||||
```
|
||||
|
||||
`yosh_project` 为项目根目录(你也可以把它简单命名为 `yosh`)。
|
||||
|
||||
`yosh` 为包目录,且 `__init__.py` 可以使它成为与包的目录名字相同的包(如果你不用 Python 编写的话,可以忽略它。)
|
||||
|
||||
`shell.py` 是我们主要的脚本文件。
|
||||
|
||||
### 步骤 1:Shell 循环
|
||||
|
||||
当启动一个 shell,它会显示一个命令提示符并等待你的命令输入。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会重新回到这里,并循环等待下一条指令。
|
||||
|
||||
在 `shell.py` 中,我们会以一个简单的 main 函数开始,该函数调用了 shell_loop() 函数,如下:
|
||||
|
||||
```
|
||||
def shell_loop():
|
||||
# Start the loop here
|
||||
|
||||
|
||||
def main():
|
||||
shell_loop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
接着,在 `shell_loop()` 中,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。
|
||||
|
||||
```
|
||||
import sys
|
||||
|
||||
SHELL_STATUS_RUN = 1
|
||||
SHELL_STATUS_STOP = 0
|
||||
|
||||
|
||||
def shell_loop():
|
||||
status = SHELL_STATUS_RUN
|
||||
|
||||
while status == SHELL_STATUS_RUN:
|
||||
### 显示命令提示符
|
||||
sys.stdout.write('> ')
|
||||
sys.stdout.flush()
|
||||
|
||||
### 读取命令输入
|
||||
cmd = sys.stdin.readline()
|
||||
```
|
||||
|
||||
之后,我们切分命令(tokenize)输入并进行执行(execute)(我们即将实现 `tokenize` 和 `execute` 函数)。
|
||||
|
||||
因此,我们的 shell_loop() 会是如下这样:
|
||||
|
||||
```
|
||||
import sys
|
||||
|
||||
SHELL_STATUS_RUN = 1
|
||||
SHELL_STATUS_STOP = 0
|
||||
|
||||
|
||||
def shell_loop():
|
||||
status = SHELL_STATUS_RUN
|
||||
|
||||
while status == SHELL_STATUS_RUN:
|
||||
### 显示命令提示符
|
||||
sys.stdout.write('> ')
|
||||
sys.stdout.flush()
|
||||
|
||||
### 读取命令输入
|
||||
cmd = sys.stdin.readline()
|
||||
|
||||
### 切分命令输入
|
||||
cmd_tokens = tokenize(cmd)
|
||||
|
||||
### 执行该命令并获取新的状态
|
||||
status = execute(cmd_tokens)
|
||||
```
|
||||
|
||||
这就是我们整个 shell 循环。如果我们使用 `python shell.py` 启动我们的 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它会抛出错误,因为我们还没定义 `tokenize` 函数。
|
||||
|
||||
为了退出 shell,可以尝试输入 ctrl-c。稍后我将解释如何以优雅的形式退出 shell。
|
||||
|
||||
### 步骤 2:命令切分(tokenize)
|
||||
|
||||
当用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的长字符串。因此,我们必须切分该字符串(分割一个字符串为多个元组)。
|
||||
|
||||
咋一看似乎很简单。我们或许可以使用 `cmd.split()`,以空格分割输入。它对类似 `ls -a my_folder` 的命令起作用,因为它能够将命令分割为一个列表 `['ls', '-a', 'my_folder']`,这样我们便能轻易处理它们了。
|
||||
|
||||
然而,也有一些类似 `echo "Hello World"` 或 `echo 'Hello World'` 以单引号或双引号引用参数的情况。如果我们使用 cmd.spilt,我们将会得到一个存有 3 个标记的列表 `['echo', '"Hello', 'World"']` 而不是 2 个标记的列表 `['echo', 'Hello World']`。
|
||||
|
||||
幸运的是,Python 提供了一个名为 `shlex` 的库,它能够帮助我们如魔法般地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。)
|
||||
|
||||
|
||||
```
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
...
|
||||
|
||||
def tokenize(string):
|
||||
return shlex.split(string)
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
然后我们将这些元组发送到执行进程。
|
||||
|
||||
### 步骤 3:执行
|
||||
|
||||
这是 shell 中核心而有趣的一部分。当 shell 执行 `mkdir test_dir` 时,到底发生了什么?(提示: `mkdir` 是一个带有 `test_dir` 参数的执行程序,用于创建一个名为 `test_dir` 的目录。)
|
||||
|
||||
`execvp` 是这一步的首先需要的函数。在我们解释 `execvp` 所做的事之前,让我们看看它的实际效果。
|
||||
|
||||
```
|
||||
import os
|
||||
...
|
||||
|
||||
def execute(cmd_tokens):
|
||||
### 执行命令
|
||||
os.execvp(cmd_tokens[0], cmd_tokens)
|
||||
|
||||
### 返回状态以告知在 shell_loop 中等待下一个命令
|
||||
return SHELL_STATUS_RUN
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
再次尝试运行我们的 shell,并输入 `mkdir test_dir` 命令,接着按下回车键。
|
||||
|
||||
在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目录正确地创建了。
|
||||
|
||||
因此,`execvp` 实际上做了什么?
|
||||
|
||||
`execvp` 是系统调用 `exec` 的一个变体。第一个参数是程序名字。`v` 表示第二个参数是一个程序参数列表(参数数量可变)。`p` 表示将会使用环境变量 `PATH` 搜索给定的程序名字。在我们上一次的尝试中,它将会基于我们的 `PATH` 环境变量查找`mkdir` 程序。
|
||||
|
||||
(还有其他 `exec` 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。)
|
||||
|
||||
`exec` 会用即将运行的新进程替换调用进程的当前内存。在我们的例子中,我们的 shell 进程内存会被替换为 `mkdir` 程序。接着,`mkdir` 成为主进程并创建 `test_dir` 目录。最后该进程退出。
|
||||
|
||||
这里的重点在于**我们的 shell 进程已经被 `mkdir` 进程所替换**。这就是我们的 shell 消失且不会等待下一条命令的原因。
|
||||
|
||||
因此,我们需要其他的系统调用来解决问题:`fork`。
|
||||
|
||||
`fork` 会分配新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为**子进程**,调用者进程为**父进程**。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。
|
||||
|
||||
让我们看看修改的代码。
|
||||
|
||||
```
|
||||
...
|
||||
|
||||
def execute(cmd_tokens):
|
||||
### 分叉一个子 shell 进程
|
||||
### 如果当前进程是子进程,其 `pid` 被设置为 `0`
|
||||
### 否则当前进程是父进程的话,`pid` 的值
|
||||
### 是其子进程的进程 ID。
|
||||
pid = os.fork()
|
||||
|
||||
if pid == 0:
|
||||
### 子进程
|
||||
### 用被 exec 调用的程序替换该子进程
|
||||
os.execvp(cmd_tokens[0], cmd_tokens)
|
||||
elif pid > 0:
|
||||
### 父进程
|
||||
while True:
|
||||
### 等待其子进程的响应状态(以进程 ID 来查找)
|
||||
wpid, status = os.waitpid(pid, 0)
|
||||
|
||||
### 当其子进程正常退出时
|
||||
### 或者其被信号中断时,结束等待状态
|
||||
if os.WIFEXITED(status) or os.WIFSIGNALED(status):
|
||||
break
|
||||
|
||||
### 返回状态以告知在 shell_loop 中等待下一个命令
|
||||
return SHELL_STATUS_RUN
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
当我们的父进程调用 `os.fork()` 时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,且并行运行着。
|
||||
|
||||
如果运行的代码属于子进程,`pid` 将为 `0`。否则,如果运行的代码属于父进程,`pid` 将会是子进程的进程 id。
|
||||
|
||||
当 `os.execvp` 在子进程中被调用时,你可以想象子进程的所有源代码被替换为正被调用程序的代码。然而父进程的代码不会被改变。
|
||||
|
||||
当父进程完成等待子进程退出或终止时,它会返回一个状态,指示继续 shell 循环。
|
||||
|
||||
### 运行
|
||||
|
||||
现在,你可以尝试运行我们的 shell 并输入 `mkdir test_dir2`。它应该可以正确执行。我们的主 shell 进程仍然存在并等待下一条命令。尝试执行 `ls`,你可以看到已创建的目录。
|
||||
|
||||
但是,这里仍有一些问题。
|
||||
|
||||
第一,尝试执行 `cd test_dir2`,接着执行 `ls`。它应该会进入到一个空的 `test_dir2` 目录。然而,你将会看到目录并没有变为 `test_dir2`。
|
||||
|
||||
第二,我们仍然没有办法优雅地退出我们的 shell。
|
||||
|
||||
我们将会在 [第二部分][1] 解决诸如此类的问题。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://hackercollider.com/articles/2016/07/05/create-your-own-shell-in-python-part-1/
|
||||
|
||||
作者:[Supasate Choochaisri][a]
|
||||
译者:[cposture](https://github.com/cposture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://disqus.com/by/supasate_choochaisri/
|
||||
[1]: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/
|
@ -0,0 +1,211 @@
|
||||
使用 Python 创建你自己的 Shell(下)
|
||||
===========================================
|
||||
|
||||
在[上篇][1]中,我们已经创建了一个 shell 主循环、切分了命令输入,以及通过 `fork` 和 `exec` 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。
|
||||
|
||||
### 步骤 4:内置命令
|
||||
|
||||
“`cd test_dir2` 无法修改我们的当前目录” 这句话是对的,但在某种意义上也是错的。在执行完该命令之后,我们仍然处在同一目录,从这个意义上讲,它是对的。然而,目录实际上已经被修改,只不过它是在子进程中被修改。
|
||||
|
||||
还记得我们分叉(fork)了一个子进程,然后执行命令,执行命令的过程没有发生在父进程上。结果是我们只是改变了子进程的当前目录,而不是父进程的目录。
|
||||
|
||||
然后子进程退出,而父进程在原封不动的目录下继续运行。
|
||||
|
||||
因此,这类与 shell 自己相关的命令必须是内置命令。它必须在 shell 进程中执行而不是在分叉中(forking)。
|
||||
|
||||
#### cd
|
||||
|
||||
让我们从 `cd` 命令开始。
|
||||
|
||||
我们首先创建一个 `builtins` 目录。每一个内置命令都会被放进这个目录中。
|
||||
|
||||
```shell
|
||||
yosh_project
|
||||
|-- yosh
|
||||
|-- builtins
|
||||
| |-- __init__.py
|
||||
| |-- cd.py
|
||||
|-- __init__.py
|
||||
|-- shell.py
|
||||
```
|
||||
|
||||
在 `cd.py` 中,我们通过使用系统调用 `os.chdir` 实现自己的 `cd` 命令。
|
||||
|
||||
```python
|
||||
import os
|
||||
from yosh.constants import *
|
||||
|
||||
def cd(args):
|
||||
os.chdir(args[0])
|
||||
|
||||
return SHELL_STATUS_RUN
|
||||
```
|
||||
|
||||
注意,我们会从内置函数返回 shell 的运行状态。所以,为了能够在项目中继续使用常量,我们将它们移至 `yosh/constants.py`。
|
||||
|
||||
```shell
|
||||
yosh_project
|
||||
|-- yosh
|
||||
|-- builtins
|
||||
| |-- __init__.py
|
||||
| |-- cd.py
|
||||
|-- __init__.py
|
||||
|-- constants.py
|
||||
|-- shell.py
|
||||
```
|
||||
|
||||
在 `constants.py` 中,我们将状态常量都放在这里。
|
||||
|
||||
```python
|
||||
SHELL_STATUS_STOP = 0
|
||||
SHELL_STATUS_RUN = 1
|
||||
```
|
||||
|
||||
现在,我们的内置 `cd` 已经准备好了。让我们修改 `shell.py` 来处理这些内置函数。
|
||||
|
||||
```python
|
||||
...
|
||||
### 导入常量
|
||||
from yosh.constants import *
|
||||
|
||||
### 使用哈希映射来存储内建的函数名及其引用
|
||||
built_in_cmds = {}
|
||||
|
||||
def tokenize(string):
|
||||
return shlex.split(string)
|
||||
|
||||
def execute(cmd_tokens):
|
||||
### 从元组中分拆命令名称与参数
|
||||
cmd_name = cmd_tokens[0]
|
||||
cmd_args = cmd_tokens[1:]
|
||||
|
||||
### 如果该命令是一个内建命令,使用参数调用该函数
|
||||
if cmd_name in built_in_cmds:
|
||||
return built_in_cmds[cmd_name](cmd_args)
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
我们使用一个 python 字典变量 `built_in_cmds` 作为哈希映射(hash map),以存储我们的内置函数。我们在 `execute` 函数中提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。
|
||||
|
||||
(提示:`built_in_cmds[cmd_name]` 返回能直接使用参数调用的函数引用。)
|
||||
|
||||
我们差不多准备好使用内置的 `cd` 函数了。最后一步是将 `cd` 函数添加到 `built_in_cmds` 映射中。
|
||||
|
||||
```
|
||||
...
|
||||
### 导入所有内建函数引用
|
||||
from yosh.builtins import *
|
||||
|
||||
...
|
||||
|
||||
### 注册内建函数到内建命令的哈希映射中
|
||||
def register_command(name, func):
|
||||
built_in_cmds[name] = func
|
||||
|
||||
|
||||
### 在此注册所有的内建命令
|
||||
def init():
|
||||
register_command("cd", cd)
|
||||
|
||||
|
||||
def main():
|
||||
###在开始主循环之前初始化 shell
|
||||
init()
|
||||
shell_loop()
|
||||
```
|
||||
|
||||
我们定义了 `register_command` 函数,以添加一个内置函数到我们内置的命令哈希映射。接着,我们定义 `init` 函数并且在这里注册内置的 `cd` 函数。
|
||||
|
||||
注意这行 `register_command("cd", cd)` 。第一个参数为命令的名字。第二个参数为一个函数引用。为了能够让第二个参数 `cd` 引用到 `yosh/builtins/cd.py` 中的 `cd` 函数引用,我们必须将以下这行代码放在 `yosh/builtins/__init__.py` 文件中。
|
||||
|
||||
```
|
||||
from yosh.builtins.cd import *
|
||||
```
|
||||
|
||||
因此,在 `yosh/shell.py` 中,当我们从 `yosh.builtins` 导入 `*` 时,我们可以得到已经通过 `yosh.builtins` 导入的 `cd` 函数引用。
|
||||
|
||||
我们已经准备好了代码。让我们尝试在 `yosh` 同级目录下以模块形式运行我们的 shell,`python -m yosh.shell`。
|
||||
|
||||
现在,`cd` 命令可以正确修改我们的 shell 目录了,同时非内置命令仍然可以工作。非常好!
|
||||
|
||||
#### exit
|
||||
|
||||
最后一块终于来了:优雅地退出。
|
||||
|
||||
我们需要一个可以修改 shell 状态为 `SHELL_STATUS_STOP` 的函数。这样,shell 循环可以自然地结束,shell 将到达终点而退出。
|
||||
|
||||
和 `cd` 一样,如果我们在子进程中分叉并执行 `exit` 函数,其对父进程是不起作用的。因此,`exit` 函数需要成为一个 shell 内置函数。
|
||||
|
||||
让我们从这开始:在 `builtins` 目录下创建一个名为 `exit.py` 的新文件。
|
||||
|
||||
```
|
||||
yosh_project
|
||||
|-- yosh
|
||||
|-- builtins
|
||||
| |-- __init__.py
|
||||
| |-- cd.py
|
||||
| |-- exit.py
|
||||
|-- __init__.py
|
||||
|-- constants.py
|
||||
|-- shell.py
|
||||
```
|
||||
|
||||
`exit.py` 定义了一个 `exit` 函数,该函数仅仅返回一个可以退出主循环的状态。
|
||||
|
||||
```
|
||||
from yosh.constants import *
|
||||
|
||||
def exit(args):
|
||||
return SHELL_STATUS_STOP
|
||||
```
|
||||
|
||||
然后,我们导入位于 `yosh/builtins/__init__.py` 文件的 `exit` 函数引用。
|
||||
|
||||
```
|
||||
from yosh.builtins.cd import *
|
||||
from yosh.builtins.exit import *
|
||||
```
|
||||
|
||||
最后,我们在 `shell.py` 中的 `init()` 函数注册 `exit` 命令。
|
||||
|
||||
```
|
||||
...
|
||||
|
||||
### 在此注册所有的内建命令
|
||||
def init():
|
||||
register_command("cd", cd)
|
||||
register_command("exit", exit)
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
到此为止!
|
||||
|
||||
尝试执行 `python -m yosh.shell`。现在你可以输入 `exit` 优雅地退出程序了。
|
||||
|
||||
### 最后的想法
|
||||
|
||||
我希望你能像我一样享受创建 `yosh` (**y**our **o**wn **sh**ell)的过程。但我的 `yosh` 版本仍处于早期阶段。我没有处理一些会使 shell 崩溃的极端状况。还有很多我没有覆盖的内置命令。为了提高性能,一些非内置命令也可以实现为内置命令(避免新进程创建时间)。同时,大量的功能还没有实现(请看 [公共特性](http://tldp.org/LDP/Bash-Beginners-Guide/html/x7243.html) 和 [不同特性](http://www.tldp.org/LDP/intro-linux/html/x12249.html))
|
||||
|
||||
我已经在 https://github.com/supasate/yosh 中提供了源代码。请随意 fork 和尝试。
|
||||
|
||||
现在该是创建你真正自己拥有的 Shell 的时候了。
|
||||
|
||||
Happy Coding!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/
|
||||
|
||||
作者:[Supasate Choochaisri][a]
|
||||
译者:[cposture](https://github.com/cposture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://disqus.com/by/supasate_choochaisri/
|
||||
[1]: https://linux.cn/article-7624-1.html
|
||||
[2]: http://tldp.org/LDP/Bash-Beginners-Guide/html/x7243.html
|
||||
[3]: http://www.tldp.org/LDP/intro-linux/html/x12249.html
|
||||
[4]: https://github.com/supasate/yosh
|
@ -0,0 +1,67 @@
|
||||
使用 Vagrant 控制你的 DigitalOcean 云主机
|
||||
=========================================================
|
||||
|
||||
![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/fedora-vagrant-do-945x400.jpg)
|
||||
|
||||
[Vagrant][1] 是一个使用虚拟机创建和支持虚拟开发环境的应用。Fedora 官方已经在本地系统上通过库 `libvirt` [支持 Vagrant][2]。[DigitalOcean][3] 是一个提供一键部署 Fedora 云服务实例到全 SSD 服务器的云计算服务提供商。在[最近的 Raleigh 举办的 FAD 大会][4]中,Fedora 云计算队伍为 Vagrant 打包了一个新的插件,它能够帮助 Fedora 用户通过使用本地的 Vagrantfile 文件来管理 DigitalOcean 上的云服务实例。
|
||||
|
||||
### 如何使用这个插件
|
||||
|
||||
第一步在命令行下是安装软件。
|
||||
|
||||
```
|
||||
$ sudo dnf install -y vagrant-digitalocean
|
||||
```
|
||||
|
||||
安装 结束之后,下一步是创建本地的 Vagrantfile 文件。下面是一个例子。
|
||||
|
||||
```
|
||||
$ mkdir digitalocean
|
||||
$ cd digitalocean
|
||||
$ cat Vagrantfile
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.hostname = 'dropletname.kushaldas.in'
|
||||
# Alternatively, use provider.name below to set the Droplet name. config.vm.hostname takes precedence.
|
||||
|
||||
config.vm.provider :digital_ocean do |provider, override|
|
||||
override.ssh.private_key_path = '/home/kdas/.ssh/id_rsa'
|
||||
override.vm.box = 'digital_ocean'
|
||||
override.vm.box_url = "https://github.com/devopsgroup-io/vagrant- digitalocean/raw/master/box/digital_ocean.box"
|
||||
|
||||
provider.token = 'Your AUTH Token'
|
||||
provider.image = 'fedora-23-x64'
|
||||
provider.region = 'nyc2'
|
||||
provider.size = '512mb'
|
||||
provider.ssh_key_name = 'Kushal'
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Vagrant DigitalOcean 插件的注意事项
|
||||
|
||||
一定要记住的几个关于 SSH 的关键命名规范 : 如果你已经在 DigitalOcean 上传了秘钥,请确保 `provider.ssh_key_name` 和已经在服务器中的名字吻合。 `provider.image` 具体的文档可以在[DigitalOcean documentation][5]找到。在控制面板上的 `App & API` 部分可以创建 AUTH 令牌。
|
||||
|
||||
你可以使用下面的命令启动一个实例。
|
||||
|
||||
```
|
||||
$ vagrant up --provider=digital_ocean
|
||||
```
|
||||
|
||||
这个命令会在 DigitalOcean 的启动一个服务器实例。然后你就可以使用 `vagrant ssh` 命令来 `ssh` 登录进入这个实例。可以执行 `vagrant destroy` 来删除这个实例。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/using-vagrant-digitalocean-cloud/
|
||||
|
||||
作者:[Kushal Das][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[Ezio](https://github.com/oska874)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://kushal.id.fedoraproject.org/
|
||||
[1]: https://www.vagrantup.com/
|
||||
[2]: https://fedoramagazine.org/running-vagrant-fedora-22/
|
||||
[3]: https://www.digitalocean.com/
|
||||
[4]: https://communityblog.fedoraproject.org/fedora-cloud-fad-2016/
|
||||
[5]: https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet
|
80
published/201607/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md
Normal file
80
published/201607/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md
Normal file
@ -0,0 +1,80 @@
|
||||
GNU KHATA:开源的会计管理软件
|
||||
============================================
|
||||
|
||||
作为一个活跃的 Linux 爱好者,我经常向我的朋友们介绍 Linux,帮助他们选择最适合他们的发行版本,同时也会帮助他们安装一些适用于他们工作的开源软件。
|
||||
|
||||
但是在这一次,我就变得很无奈。我的叔叔,他是一个自由职业的会计师。他会有一系列的为了会计工作的漂亮而成熟的付费软件。我不那么确定我能在在开源软件中找到这么一款可以替代的软件——直到昨天。
|
||||
|
||||
Abhishek 给我推荐了一些[很酷的软件][1],而其中 GNU Khata 脱颖而出。
|
||||
|
||||
[GNU Khata][2] 是一个会计工具。 或者,我应该说成是一系列的会计工具集合?它就像经济管理方面的 [Evernote][3] 一样。它的应用是如此之广,以至于它不但可以用于个人的财务管理,也可以用于大型公司的管理,从店铺存货管理到税率计算,都可以有效处理。
|
||||
|
||||
有个有趣的地方,Khata 这个词在印度或者是其他的印度语国家中意味着账户,所以这个会计软件叫做 GNU Khata。
|
||||
|
||||
### 安装
|
||||
|
||||
互联网上有很多关于旧的 Web 版本的 Khata 安装介绍。现在,GNU Khata 只能用在 Debian/Ubuntu 和它们的衍生版本中。我建议你按照 GNU Khata 官网给出的如下步骤来安装。我们来快速过一下。
|
||||
|
||||
- 从[这里][4]下载安装器。
|
||||
- 在下载目录打开终端。
|
||||
- 粘贴复制以下的代码到终端,并且执行。
|
||||
|
||||
```
|
||||
sudo chmod 755 GNUKhatasetup.run
|
||||
sudo ./GNUKhatasetup.run
|
||||
```
|
||||
|
||||
这就结束了,从你的 Dash 或者是应用菜单中启动 GNU Khata 吧。
|
||||
|
||||
### 第一次启动
|
||||
|
||||
GNU Khata 在浏览器中打开,并且展现以下的画面。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-1.jpg)
|
||||
|
||||
填写组织的名字、组织形式,财务年度并且点击 proceed 按钮进入管理设置页面。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-2.jpg)
|
||||
|
||||
仔细填写你的用户名、密码、安全问题及其答案,并且点击“create and login”。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-3.jpg)
|
||||
|
||||
你已经全部设置完成了。使用菜单栏来开始使用 GNU Khata 来管理你的财务吧。这很容易。
|
||||
|
||||
### 移除 GNU KHATA
|
||||
|
||||
如果你不想使用 GNU Khata 了,你可以执行如下命令移除:
|
||||
|
||||
```
|
||||
sudo apt-get remove --auto-remove gnukhata-core-engine
|
||||
```
|
||||
|
||||
你也可以通过新立得软件管理来删除它。
|
||||
|
||||
### GNU KHATA 真的是市面上付费会计应用的竞争对手吗?
|
||||
|
||||
首先,GNU Khata 以简化为设计原则。顶部的菜单栏组织的很方便,可以帮助你有效的进行工作。你可以选择管理不同的账户和项目,并且切换非常容易。[它们的官网][5]表明,GNU Khata 可以“像说印度语一样方便”(LCTT 译注:原谅我,这个软件作者和本文作者是印度人……)。同时,你知道 GNU Khata 也可以在云端使用吗?
|
||||
|
||||
所有的主流的账户管理工具,比如分类账簿、项目报表、财务报表等等都用专业的方式整理,并且支持自定义格式和即时展示。这让会计和仓储管理看起来如此的简单。
|
||||
|
||||
这个项目正在积极的发展,正在寻求实操中的反馈以帮助这个软件更加进步。考虑到软件的成熟性、使用的便利性还有免费的情况,GNU Khata 可能会成为你最好的账簿助手。
|
||||
|
||||
请在评论框里留言吧,让我们知道你是如何看待 GNU Khata 的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/using-gnu-khata/
|
||||
|
||||
作者:[Aquil Roshan][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/aquil/
|
||||
[1]: https://itsfoss.com/category/apps/
|
||||
[2]: http://www.gnukhata.in/
|
||||
[3]: https://evernote.com/
|
||||
[4]: https://cloud.openmailbox.org/index.php/s/L8ppsxtsFq1345E/download
|
||||
[5]: http://www.gnukhata.in/
|
@ -0,0 +1,36 @@
|
||||
在浏览器中体验 Ubuntu
|
||||
=====================================================
|
||||
|
||||
[Ubuntu][2] 的背后的公司 [Canonical][1] 为 Linux 推广做了很多努力。无论你有多么不喜欢 Ubuntu,你必须承认它对 “Linux 易用性”的影响。Ubuntu 以及其衍生是使用最多的 Linux 版本。
|
||||
|
||||
为了进一步推广 Ubuntu Linux,Canonical 把它放到了浏览器里,你可以在任何地方使用这个 [Ubuntu 演示版][0]。 它将帮你更好的体验 Ubuntu,以便让新人更容易决定是否使用它。
|
||||
|
||||
你可能争辩说 USB 版的 Linux 更好。我同意,但是你要知道你要下载 ISO,创建 USB 启动盘,修改配置文件,然后才能使用这个 USB 启动盘来体验。这么乏味并不是每个人都乐意这么干的。 在线体验是一个更好的选择。
|
||||
|
||||
那么,你能在 Ubuntu 在线看到什么。实际上并不多。
|
||||
|
||||
你可以浏览文件,你可以使用 Unity Dash,浏览 Ubuntu 软件中心,甚至装几个应用(当然它们不会真的安装),看一看文件浏览器和其它一些东西。以上就是全部了。但是在我看来,这已经做的很好了,让你知道它是个什么,对这个流行的操作系统有个直接感受。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg)
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg)
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg)
|
||||
|
||||
如果你的朋友或者家人对试试 Linux 抱有兴趣,但是想在安装前想体验一下 Linux 。你可以给他们以下链接:[Ubuntu 在线导览][0] 。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/ubuntu-online-demo/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[kokialoves](https://github.com/kokialoves)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[0]: http://tour.ubuntu.com/en/
|
||||
[1]: http://www.canonical.com/
|
||||
[2]: http://www.ubuntu.com/
|
200
published/201607/20160722 7 Best Markdown Editors for Linux.md
Normal file
200
published/201607/20160722 7 Best Markdown Editors for Linux.md
Normal file
@ -0,0 +1,200 @@
|
||||
Linux 上 10 个最好的 Markdown 编辑器
|
||||
======================================
|
||||
|
||||
在这篇文章中,我们会点评一些可以在 Linux 上安装使用的最好的 Markdown 编辑器。 你可以找到非常多的 Linux 平台上的 Markdown 编辑器,但是在这里我们将尽可能地为您推荐那些最好的。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Best-Linux-Markdown-Editors.png)
|
||||
|
||||
*Best Linux Markdown Editors*
|
||||
|
||||
对于不了解 Markdown 的人做个简单介绍,Markdown 是由著名的 Aaron Swartz 和 John Gruber 发明的标记语言,其最初的解析器是一个用 Perl 写的简单、轻量的[同名工具][1]。它可以将用户写的纯文本转为可用的 HTML(或 XHTML)。它实际上是一门易读,易写的纯文本语言,以及一个用于将文本转为 HTML 的转换工具。
|
||||
|
||||
希望你先对 Markdown 有一个稍微的了解,接下来让我们逐一列出这些编辑器。
|
||||
|
||||
### 1. Atom
|
||||
|
||||
Atom 是一个现代的、跨平台、开源且强大的文本编辑器,它可以运行在 Linux、Windows 和 MAC OS X 等操作系统上。用户可以在它的基础上进行定制,删减修改任何配置文件。
|
||||
|
||||
它包含了一些非常杰出的特性:
|
||||
|
||||
- 内置软件包管理器
|
||||
- 智能自动补全功能
|
||||
- 提供多窗口操作
|
||||
- 支持查找替换功能
|
||||
- 包含一个文件系统浏览器
|
||||
- 轻松自定义主题
|
||||
- 开源、高度扩展性的软件包等
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Atom-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*Atom Markdown Editor for Linux*
|
||||
|
||||
访问主页: <https://atom.io/>
|
||||
|
||||
### 2. GNU Emacs
|
||||
|
||||
Emacs 是 Linux 平台上一款的流行文本编辑器。它是一个非常棒的、具备高扩展性和定制性的 Markdown 语言编辑器。
|
||||
|
||||
它综合了以下这些神奇的特性:
|
||||
|
||||
- 带有丰富的内置文档,包括适合初学者的教程
|
||||
- 有完整的 Unicode 支持,可显示所有的人类符号
|
||||
- 支持内容识别的文本编辑模式
|
||||
- 包括多种文件类型的语法高亮
|
||||
- 可用 Emacs Lisp 或 GUI 对其进行高度定制
|
||||
- 提供了一个包系统可用来下载安装各种扩展等
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Emacs-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*Emacs Markdown Editor for Linux*
|
||||
|
||||
访问主页: <https://www.gnu.org/software/emacs/>
|
||||
|
||||
### 3. Remarkable
|
||||
|
||||
Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 Windows 操作系统。它的确是是一个卓越且功能齐全的 Markdown 编辑器,为用户提供了一些令人激动的特性。
|
||||
|
||||
一些卓越的特性:
|
||||
|
||||
- 支持实时预览
|
||||
- 支持导出 PDF 和 HTML
|
||||
- 支持 Github Markdown 语法
|
||||
- 支持定制 CSS
|
||||
- 支持语法高亮
|
||||
- 提供键盘快捷键
|
||||
- 高可定制性和其他
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Remarkable-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*Remarkable Markdown Editor for Linux*
|
||||
|
||||
访问主页: <https://remarkableapp.github.io>
|
||||
|
||||
### 4. Haroopad
|
||||
|
||||
Haroopad 是为 Linux,Windows 和 Mac OS X 构建的跨平台 Markdown 文档处理程序。用户可以用它来书写许多专家级格式的文档,包括电子邮件、报告、博客、演示文稿和博客文章等等。
|
||||
|
||||
功能齐全且具备以下的亮点:
|
||||
|
||||
- 轻松导入内容
|
||||
- 支持导出多种格式
|
||||
- 广泛支持博客和邮件
|
||||
- 支持许多数学表达式
|
||||
- 支持 Github Markdown 扩展
|
||||
- 为用户提供了一些令人兴奋的主题、皮肤和 UI 组件等等
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Haroopad-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*Haroopad Markdown Editor for Linux*
|
||||
|
||||
访问主页: <http://pad.haroopress.com/>
|
||||
|
||||
### 5. ReText
|
||||
|
||||
ReText 是为 Linux 和其它几个 POSIX 兼容操作系统提供的简单、轻量、强大的 Markdown 编辑器。它还可以作为一个 reStructuredText 编辑器,并且具有以下的特性:
|
||||
|
||||
- 简单直观的 GUI
|
||||
- 具备高定制性,用户可以自定义语法文件和配置选项
|
||||
- 支持多种配色方案
|
||||
- 支持使用多种数学公式
|
||||
- 启用导出扩展等等
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/ReText-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*ReText Markdown Editor for Linux*
|
||||
|
||||
访问主页: <https://github.com/retext-project/retext>
|
||||
|
||||
### 6. UberWriter
|
||||
|
||||
UberWriter 是一个简单、易用的 Linux Markdown 编辑器。它的开发受 Mac OS X 上的 iA writer 影响很大,同样它也具备这些卓越的特性:
|
||||
|
||||
- 使用 pandoc 进行所有的文本到 HTML 的转换
|
||||
- 提供了一个简洁的 UI 界面
|
||||
- 提供了一种专心(distraction free)模式,高亮用户最后的句子
|
||||
- 支持拼写检查
|
||||
- 支持全屏模式
|
||||
- 支持用 pandoc 导出 PDF、HTML 和 RTF
|
||||
- 启用语法高亮和数学函数等等
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/UberWriter-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*UberWriter Markdown Editor for Linux*
|
||||
|
||||
访问主页: <http://uberwriter.wolfvollprecht.de/>
|
||||
|
||||
### 7. Mark My Words
|
||||
|
||||
Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是一个相对比较新的编辑器,因此提供了包含语法高亮在内的大量的功能,简单和直观的 UI。
|
||||
|
||||
下面是一些棒极了,但还未捆绑到应用中的功能:
|
||||
|
||||
- 实时预览
|
||||
- Markdown 解析和文件 IO
|
||||
- 状态管理
|
||||
- 支持导出 PDF 和 HTML
|
||||
- 监测文件的修改
|
||||
- 支持首选项设置
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/MarkMyWords-Markdown-Editor-for-Linux.png)
|
||||
|
||||
*MarkMyWords Markdown Editor for-Linux*
|
||||
|
||||
访问主页: <https://github.com/voldyman/MarkMyWords>
|
||||
|
||||
### 8. Vim-Instant-Markdown 插件
|
||||
|
||||
Vim 是 Linux 上的一个久经考验的强大、流行而开源的文本编辑器。它用于编程极棒。它也高度支持插件功能,可以让用户为其增加一些其它功能,包括 Markdown 预览。
|
||||
|
||||
有好几种 Vim 的 Markdown 预览插件,但是 [Vim-Instant-Markdown][2] 的表现最佳。
|
||||
|
||||
###9. Bracket-MarkdownPreview 插件
|
||||
|
||||
Brackets 是一个现代、轻量、开源且跨平台的文本编辑器。它特别为 Web 设计和开发而构建。它的一些重要功能包括:支持内联编辑器、实时预览、预处理支持及更多。
|
||||
|
||||
它也是通过插件高度可扩展的,你可以使用 [Bracket-MarkdownPreview][3] 插件来编写和预览 Markdown 文档。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Brackets-Markdown-Plugin.png)
|
||||
|
||||
*Brackets Markdown Plugin Preview*
|
||||
|
||||
### 10. SublimeText-Markdown 插件
|
||||
|
||||
Sublime Text 是一个精心打造的、流行的、跨平台文本编辑器,用于代码、markdown 和普通文本。它的表现极佳,包括如下令人兴奋的功能:
|
||||
|
||||
- 简洁而美观的 GUI
|
||||
- 支持多重选择
|
||||
- 提供专心模式
|
||||
- 支持窗体分割编辑
|
||||
- 通过 Python 插件 API 支持高度插件化
|
||||
- 完全可定制化,提供命令查找模式
|
||||
|
||||
[SublimeText-Markdown][4] 插件是一个支持格式高亮的软件包,带有一些漂亮的颜色方案。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/SublimeText-Markdown-Plugin-Preview.png)
|
||||
|
||||
*SublimeText Markdown Plugin Preview*
|
||||
|
||||
### 结论
|
||||
|
||||
通过上面的列表,你大概已经知道要为你的 Linux 桌面下载、安装什么样的 Markdown 编辑器和文档处理程序了。
|
||||
|
||||
请注意,这里提到的最好的 Markdown 编辑器可能对你来说并不是最好的选择。因此你可以通过下面的反馈部分,为我们展示你认为列表中未提及的,并且具备足够的资格的,令人兴奋的 Markdown 编辑器。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/best-markdown-editors-for-linux/
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[Locez](https://github.com/locez)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: https://daringfireball.net/projects/markdown/
|
||||
[2]: https://github.com/suan/vim-instant-markdown
|
||||
[3]: https://github.com/gruehle/MarkdownPreview
|
||||
[4]: https://github.com/SublimeText-Markdown/MarkdownEditing
|
||||
|
@ -0,0 +1,69 @@
|
||||
怎样在 Ubuntu 中修改默认程序
|
||||
==============================================
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/change-default-applications-ubuntu.jpg)
|
||||
|
||||
> 简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序
|
||||
|
||||
对于我来说,安装 [VLC 多媒体播放器][1]是[安装完 Ubuntu 16.04 该做的事][2]中最先做的几件事之一。为了能够使我双击一个视频就用 VLC 打开,在我安装完 VLC 之后我会设置它为默认程序。
|
||||
|
||||
作为一个新手,你需要知道如何在 Ubuntu 中修改任何默认程序,这也是我今天在这篇指南中所要讲的。
|
||||
|
||||
### 在 UBUNTU 中修改默认程序
|
||||
|
||||
这里提及的方法适用于所有的 Ubuntu 12.04,Ubuntu 14.04 和Ubuntu 16.04。在 Ubuntu 中,这里有两种基本的方法可以修改默认程序:
|
||||
|
||||
- 通过系统设置
|
||||
- 通过右键菜单
|
||||
|
||||
#### 1.通过系统设置修改 Ubuntu 的默认程序
|
||||
|
||||
进入 Unity 面板并且搜索系统设置(System Settings):
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2013/11/System_Settings_Ubuntu.jpeg)
|
||||
|
||||
在系统设置(System Settings)中,选择详细选项(Details):
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-detail-ubuntu.jpeg)
|
||||
|
||||
在左边的面板中选择默认程序(Default Applications),你会发现在右边的面板中可以修改默认程序。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-default-applications.jpeg)
|
||||
|
||||
正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器、邮箱客户端、日历、音乐、视频和相册的默认程序。那其他类型的默认程序怎么修改?
|
||||
|
||||
不要担心,为了修改其他类型的默认程序,我们会用到右键菜单。
|
||||
|
||||
#### 2.通过右键菜单修改默认程序
|
||||
|
||||
如果你使用过 Windows 系统,你应该看见过右键菜单的“打开方式”,可以通过这个来修改默认程序。我们在 Ubuntu 中也有相似的方法。
|
||||
|
||||
右键一个还没有设置默认打开程序的文件,选择“属性(properties)”
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png)
|
||||
|
||||
*从右键菜单中选择属性*
|
||||
|
||||
在这里,你可以选择使用什么程序打开,并且设置为默认程序。
|
||||
|
||||
![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png)
|
||||
|
||||
*在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb*
|
||||
|
||||
小菜一碟不是么?一旦你做完这些,所有同样类型的文件都会用你选择的默认程序打开。
|
||||
|
||||
我很希望这个新手指南对你在修改 Ubuntu 的默认程序时有帮助。如果你有任何的疑问或者建议,可以随时在下面评论。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/change-default-applications-ubuntu/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[Locez](https://github.com/locez)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[1]: http://www.videolan.org/vlc/index.html
|
||||
[2]: https://linux.cn/article-7453-1.html
|
@ -0,0 +1,136 @@
|
||||
Terminix:一个很赞的基于 GTK3 的平铺式 Linux 终端模拟器
|
||||
============================================================
|
||||
|
||||
现在,你可以很容易的找到[大量的 Linux 终端模拟器][1],每一个都可以给用户留下深刻的印象。
|
||||
|
||||
但是,很多时候,我们会很难根据我们的喜好来找到一款心仪的日常使用的终端模拟器。这篇文章中,我们将会推荐一款叫做 Terminix 的令人激动的终端模拟机。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Terminix-Terminal-Emulator-for-Linux.png)
|
||||
|
||||
*Terminix Linux 终端模拟器*
|
||||
|
||||
Terminix 是一个使用 VTE GTK+ 3 组件的平铺式终端模拟器。使用 GTK 3 开发的原因主要是为了符合 GNOME HIG(人机接口 Human Interface Guidelines) 标准。另外,Terminix 已经在 GNOME 和 Unity 桌面环境下测试过了,也有用户在其他的 Linux 桌面环境下测试成功。
|
||||
|
||||
和其他的终端模拟器一样,Terminix 有着很多知名的特征,列表如下:
|
||||
|
||||
- 允许用户进行任意的垂直或者水平分屏
|
||||
- 支持拖拽功能来进行重新排布终端
|
||||
- 支持使用拖拽的方式终端从窗口中将脱离出来
|
||||
- 支持终端之间的输入同步,因此,可以在一个终端输入命令,而在另一个终端同步复现
|
||||
- 终端的分组配置可以保存在硬盘,并再次加载
|
||||
- 支持透明背景
|
||||
- 允许使用背景图片
|
||||
- 基于主机和目录来自动切换配置
|
||||
- 支持进程完成的通知信息
|
||||
- 配色方案采用文件存储,同时支持自定义配色方案
|
||||
|
||||
### 如何在 Linux 系统上安装 Terminix
|
||||
|
||||
现在来详细说明一下在不同的 Linux 发行版本上安装 Terminix 的步骤。首先,在此列出 Terminix 在 Linux 所需要的环境需求。
|
||||
|
||||
#### 依赖组件
|
||||
|
||||
为了正常运行,该应用需要使用如下库:
|
||||
|
||||
- GTK 3.14 或者以上版本
|
||||
- GTK VTE 0.42 或者以上版本
|
||||
- Dconf
|
||||
- GSettings
|
||||
- Nautilus 的 iNautilus-Python 插件
|
||||
|
||||
如果你已经满足了如上的系统要求,接下来就是安装 Terminix 的步骤。
|
||||
|
||||
#### 在 RHEL/CentOS 7 或者 Fedora 22-24 上
|
||||
|
||||
首先,你需要通过新建文件 `/etc/yum.repos.d/terminix.repo` 来增加软件仓库,使用你最喜欢的文本编辑器来进行编辑:
|
||||
|
||||
```
|
||||
# vi /etc/yum.repos.d/terminix.repo
|
||||
```
|
||||
|
||||
然后拷贝如下的文字到我们刚新建的文件中:
|
||||
|
||||
```
|
||||
[heikoada-terminix]
|
||||
name=Copr repo for terminix owned by heikoada
|
||||
baseurl=https://copr-be.cloud.fedoraproject.org/results/heikoada/terminix/fedora-$releasever-$basearch/
|
||||
skip_if_unavailable=True
|
||||
gpgcheck=1
|
||||
gpgkey=https://copr-be.cloud.fedoraproject.org/results/heikoada/terminix/pubkey.gpg
|
||||
enabled=1
|
||||
enabled_metadata=1
|
||||
```
|
||||
|
||||
保存文件并退出。
|
||||
|
||||
然后更新你的系统,并且安装 Terminix,步骤如下:
|
||||
|
||||
```
|
||||
---------------- On RHEL/CentOS 7 ----------------
|
||||
# yum update
|
||||
# yum install terminix
|
||||
|
||||
---------------- On Fedora 22-24 ----------------
|
||||
# dnf update
|
||||
# dnf install terminix
|
||||
```
|
||||
|
||||
#### 在 Ubuntu 16.04-14.04 和 Linux Mint 18-17
|
||||
|
||||
虽然没有基于 Debian/Ubuntu 发行版本的官方的软件包,但是你依旧可以通过如下的命令手动安装。
|
||||
|
||||
```
|
||||
$ wget -c https://github.com/gnunn1/terminix/releases/download/1.1.1/terminix.zip
|
||||
$ sudo unzip terminix.zip -d /
|
||||
$ sudo glib-compile-schemas /usr/share/glib-2.0/schemas/
|
||||
```
|
||||
|
||||
#### 其它 Linux 发行版
|
||||
|
||||
OpenSUSE 用户可以从默认仓库中安装 Terminix,Arch Linux 用户也可以安装 [AUR Terminix 软件包][2]。
|
||||
|
||||
### Terminix 截图教程
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Terminix-Terminal.png)
|
||||
|
||||
*Terminix 终端*
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Terminix-Terminal-Settings.png)
|
||||
|
||||
*Terminix 终端设置*
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/07/Terminix-Terminal-Tabs.png)
|
||||
|
||||
*Terminix 多终端界面*
|
||||
|
||||
### 如何卸载删除 Terminix
|
||||
|
||||
|
||||
如果你是手动安装的 Terminix 并且想要删除它,那么你可以参照如下的步骤来卸载它。从 [Github 仓库][3]上下载 uninstall.sh,并且给它可执行权限并且执行它:
|
||||
|
||||
```
|
||||
$ wget -c https://github.com/gnunn1/terminix/blob/master/uninstall.sh
|
||||
$ chmod +x uninstall.sh
|
||||
$ sudo sh uninstall.sh
|
||||
```
|
||||
|
||||
但是如果你是通过包管理器安装的 Terminix,你可以使用包管理器来卸载它。
|
||||
|
||||
在这篇介绍中,我们在众多优秀的终端模拟器中发现了一个重要的 Linux 终端模拟器。你可以尝试着去体验下它的新特性,并且可以将它和你现在使用的终端进行比较。
|
||||
|
||||
重要的一点,如果你想得到更多信息或者有疑问,请使用评论区,而且不要忘了,给我一个关于你使用体验的反馈。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/terminix-tiling-terminal-emulator-for-linux/
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[MikeCoder](https://github.com/MikeCoder)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: http://www.tecmint.com/linux-terminal-emulators/
|
||||
[2]: https://aur.archlinux.org/packages/terminix
|
||||
[3]: https://github.com/gnunn1/terminix
|
@ -0,0 +1,90 @@
|
||||
为你的 Linux 桌面设置一张实时的地球照片
|
||||
=================================================================
|
||||
|
||||
![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg)
|
||||
|
||||
厌倦了看同样的桌面背景了么?这里有一个(可能是)世界上最棒的东西。
|
||||
|
||||
‘[Himawaripy][1]’ 是一个 Python 3 小脚本,它会抓取由[日本 Himawari 8 气象卫星][2]拍摄的接近实时的地球照片,并将它设置成你的桌面背景。
|
||||
|
||||
安装完成后,你可以将它设置成每 10 分钟运行的定时任务(自然,它要在后台运行),这样它就可以实时地取回地球的照片并设置成背景了。
|
||||
|
||||
因为 Himawari-8 是一颗同步轨道卫星,你只能看到澳大利亚上空的地球的图片——但是它实时的天气形态、云团和光线仍使它很壮丽,对我而言要是看到英国上方的就更好了!
|
||||
|
||||
高级设置允许你配置从卫星取回的图片质量,但是要记住增加图片质量会增加文件大小及更长的下载等待!
|
||||
|
||||
最后,虽然这个脚本与其他我们提到过的其他脚本类似,它还仍保持更新及可用。
|
||||
|
||||
###获取 Himawaripy
|
||||
|
||||
Himawaripy 已经在一系列的桌面环境中都测试过了,包括 Unity、LXDE、i3、MATE 和其他桌面环境。它是自由开源软件,但是整体来说安装及配置不太简单。
|
||||
|
||||
在该项目的 [Github 主页][0]上可以找到安装和设置该应用程序的所有指导(提示:没有一键安装功能)。
|
||||
|
||||
- [实时地球壁纸脚本的 GitHub 主页][0]
|
||||
|
||||
### 安装及使用
|
||||
|
||||
![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.46.13-750x143.png)
|
||||
|
||||
一些读者请我在本文中补充一下一步步安装该应用的步骤。以下所有步骤都在其 GitHub 主页上,这里再贴一遍。
|
||||
|
||||
1、下载及解压 Himawaripy
|
||||
|
||||
这是最容易的步骤。点击下面的下载链接,然后下载最新版本,并解压到你的下载目录里面。
|
||||
|
||||
- [下载 Himawaripy 主干文件(.zip 格式)][3]
|
||||
|
||||
2、安装 python3-setuptools
|
||||
|
||||
你需要手工来安装主干软件包,Ubuntu 里面默认没有安装它:
|
||||
|
||||
```
|
||||
sudo apt install python3-setuptools
|
||||
```
|
||||
|
||||
3、安装 Himawaripy
|
||||
|
||||
在终端中,你需要切换到之前解压的目录中,并运行如下安装命令:
|
||||
|
||||
```
|
||||
cd ~/Downloads/himawaripy-master
|
||||
sudo python3 setup.py install
|
||||
```
|
||||
|
||||
4、 看看它是否可以运行并下载最新的实时图片:
|
||||
```
|
||||
himawaripy
|
||||
```
|
||||
5、 设置定时任务
|
||||
|
||||
如果你希望该脚本可以在后台自动运行并更新(如果你需要手动更新,只需要运行 ‘himarwaripy’ 即可)
|
||||
|
||||
在终端中运行:
|
||||
```
|
||||
crontab -e
|
||||
```
|
||||
在其中新加一行(默认每10分钟运行一次)
|
||||
```
|
||||
*/10 * * * * /usr/local/bin/himawaripy
|
||||
```
|
||||
关于[配置定时任务][4]可以在 Ubuntu Wiki 上找到更多信息。
|
||||
|
||||
该脚本安装后你不需要不断运行它,它会自动的每十分钟在后台运行一次。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.omgubuntu.co.uk/2016/07/set-real-time-earth-wallpaper-ubuntu-desktop
|
||||
|
||||
作者:[JOEY-ELIJAH SNEDDON][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://plus.google.com/117485690627814051450/?rel=author
|
||||
[1]: https://github.com/boramalper/himawaripy
|
||||
[2]: https://en.wikipedia.org/wiki/Himawari_8
|
||||
[0]: https://github.com/boramalper/himawaripy
|
||||
[3]: https://github.com/boramalper/himawaripy/archive/master.zip
|
||||
[4]: https://help.ubuntu.com/community/CronHowto
|
@ -0,0 +1,257 @@
|
||||
Fabric - 通过 SSH 来自动化管理 Linux 任务和布署应用
|
||||
===========================
|
||||
|
||||
当要管理远程机器或者要布署应用时,虽然你有多种命令行工具可以选择,但是其中很多工具都缺少详细的使用文档。
|
||||
|
||||
在这篇教程中,我们将会一步一步地向你介绍如何使用 fabric 来帮助你更好得管理多台服务器。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2015/11/Automate-Linux-Administration-Tasks-Using-Fabric.png)
|
||||
|
||||
*使用 Fabric 来自动化地管理 Linux 任务*
|
||||
|
||||
Fabric 是一个用 Python 编写的命令行工具库,它可以帮助系统管理员高效地执行某些任务,比如通过 SSH 到多台机器上执行某些命令,远程布署应用等。
|
||||
|
||||
在使用之前,如果你拥有使用 Python 的经验能帮你更好的使用 Fabric。当然,如果没有那也不影响使用 Fabric。
|
||||
|
||||
我们为什么要选择 Fabric:
|
||||
|
||||
- 简单
|
||||
- 完备的文档
|
||||
- 如果你会 Python,不用增加学习其他语言的成本
|
||||
- 易于安装使用
|
||||
- 使用便捷
|
||||
- 支持多台机器并行操作
|
||||
|
||||
### 在 Linux 上如何安装 Fabric
|
||||
|
||||
Fabric 有一个特点就是要远程操作的机器只需要支持标准的 OpenSSH 服务即可。只要保证在机器上安装并开启了这个服务就能使用 Fabric 来管理机器。
|
||||
|
||||
#### 依赖
|
||||
|
||||
- Python 2.5 或更新版本,以及对应的开发组件
|
||||
- Python-setuptools 和 pip(可选,但是非常推荐)gcc
|
||||
|
||||
我们推荐使用 pip 安装 Fabric,但是你也可以使用系统自带的包管理器如 `yum`, `dnf` 或 `apt-get` 来安装,包名一般是 `fabric` 或 `python-fabric`。
|
||||
|
||||
如果是基于 RHEL/CentOS 的发行版本的系统,你可以使用系统自带的 [EPEL 源][1] 来安装 fabric。
|
||||
|
||||
```
|
||||
# yum install fabric [适用于基于 RedHat 系统]
|
||||
# dnf install fabric [适用于 Fedora 22+ 版本]
|
||||
```
|
||||
|
||||
如果你是 Debian 或者其派生的系统如 Ubuntu 和 Mint 的用户,你可以使用 apt-get 来安装,如下所示:
|
||||
|
||||
```
|
||||
# apt-get install fabric
|
||||
```
|
||||
|
||||
如果你要安装开发版的 Fabric,你需要安装 pip 来安装 master 分支上最新版本。
|
||||
|
||||
```
|
||||
# yum install python-pip [适用于基于 RedHat 系统]
|
||||
# dnf install python-pip [适用于Fedora 22+ 版本]
|
||||
# apt-get install python-pip [适用于基于 Debian 系统]
|
||||
```
|
||||
|
||||
安装好 pip 后,你可以使用 pip 获取最新版本的 Fabric。
|
||||
|
||||
```
|
||||
# pip install fabric
|
||||
```
|
||||
|
||||
### 如何使用 Fabric 来自动化管理 Linux 任务
|
||||
|
||||
现在我们来开始使用 Fabric,在之前的安装的过程中,Fabric Python 脚本已经被放到我们的系统目录,当我们要运行 Fabric 时输入 `fab` 命令即可。
|
||||
|
||||
#### 在本地 Linux 机器上运行命令行
|
||||
|
||||
按照惯例,先用你喜欢的编辑器创建一个名为 fabfile.py 的 Python 脚本。你可以使用其他名字来命名脚本,但是就需要指定这个脚本的路径,如下所示:
|
||||
|
||||
```
|
||||
# fabric --fabfile /path/to/the/file.py
|
||||
```
|
||||
|
||||
Fabric 使用 `fabfile.py` 来执行任务,这个文件应该放在你执行 Fabric 命令的目录里面。
|
||||
|
||||
**例子 1**:创建入门的 `Hello World` 任务:
|
||||
|
||||
```
|
||||
# vi fabfile.py
|
||||
```
|
||||
|
||||
在文件内输入如下内容:
|
||||
|
||||
```
|
||||
def hello():
|
||||
print('Hello world, Tecmint community')
|
||||
```
|
||||
|
||||
保存文件并执行以下命令:
|
||||
|
||||
```
|
||||
# fab hello
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2015/11/Create-Fabric-Fab-Python-File.gif)
|
||||
|
||||
*Fabric 工具使用说明*
|
||||
|
||||
**例子 2**:新建一个名为 fabfile.py 的文件并打开:
|
||||
|
||||
粘贴以下代码至文件:
|
||||
|
||||
```
|
||||
#! /usr/bin/env python
|
||||
from fabric.api import local
|
||||
def uptime():
|
||||
local('uptime')
|
||||
```
|
||||
|
||||
保存文件并执行以下命令:
|
||||
|
||||
```
|
||||
# fab uptime
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2015/11/Fabric-Uptime.gif)
|
||||
|
||||
*Fabric: 检查系统运行时间*
|
||||
|
||||
让我们看看这个例子,fabfile.py 文件在本机执行了 uptime 这个命令。
|
||||
|
||||
#### 在远程 Linux 机器上运行命令来执行自动化任务
|
||||
|
||||
Fabric API 使用了一个名为 `env` 的关联数组(Python 中的词典)作为配置目录,来储存 Fabric 要控制的机器的相关信息。
|
||||
|
||||
`env.hosts` 是一个用来存储你要执行 Fabric 任务的机器的列表,如果你的 IP 地址是 192.168.0.0,想要用 Fabric 来管理地址为 192.168.0.2 和 192.168.0.6 的机器,需要的配置如下所示:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
from fabric.api import env
|
||||
env.hosts = [ '192.168.0.2', '192.168.0.6' ]
|
||||
```
|
||||
|
||||
上面这几行代码只是声明了你要执行 Fabric 任务的主机地址,但是实际上并没有执行任何任务,下面我们就来定义一些任务。Fabric 提供了一系列可以与远程服务器交互的方法。
|
||||
|
||||
Fabric 提供了众多的方法,这里列出几个经常会用到的:
|
||||
|
||||
- run - 可以在远程机器上运行的 shell 命令
|
||||
- local - 可以在本机上运行的 shell 命令
|
||||
- sudo - 使用 root 权限在远程机器上运行的 shell 命令
|
||||
- get - 从远程机器上下载一个或多个文件
|
||||
- put - 上传一个或多个文件到远程机器
|
||||
|
||||
**例子 3**:在多台机子上输出信息,新建新的 fabfile.py 文件如下所示
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
from fabric.api import env, run
|
||||
env.hosts = ['192.168.0.2','192.168.0.6']
|
||||
def echo():
|
||||
run("echo -n 'Hello, you are tuned to Tecmint ' ")
|
||||
```
|
||||
|
||||
运行以下命令执行 Fabric 任务
|
||||
|
||||
```
|
||||
# fab echo
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2015/11/Fabrick-Automate-Linux-Tasks.gif)
|
||||
|
||||
*fabric: 自动在远程 Linux 机器上执行任务*
|
||||
|
||||
**例子 4**:你可以继续改进之前创建的执行 uptime 任务的 fabfile.py 文件,让它可以在多台服务器上运行 uptime 命令,也可以检查其磁盘使用情况,如下所示:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
from fabric.api import env, run
|
||||
env.hosts = ['192.168.0.2','192.168.0.6']
|
||||
def uptime():
|
||||
run('uptime')
|
||||
def disk_space():
|
||||
run('df -h')
|
||||
```
|
||||
|
||||
保存并执行以下命令
|
||||
|
||||
```
|
||||
# fab uptime
|
||||
# fab disk_space
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2015/11/Fabric-Run-Multiple-Commands-on-Multiple-Linux-Systems.gif)
|
||||
|
||||
*Fabric:自动在多台服务器上执行任务*
|
||||
|
||||
#### 在远程服务器上自动化布署 LAMP
|
||||
|
||||
**例子 5**:我们来尝试一下在远程服务器上布署 LAMP(Linux, Apache, MySQL/MariaDB and PHP)
|
||||
|
||||
我们要写个函数在远程使用 root 权限安装 LAMP。
|
||||
|
||||
##### 在 RHEL/CentOS 或 Fedora 上
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
from fabric.api import env, run
|
||||
env.hosts = ['192.168.0.2','192.168.0.6']
|
||||
def deploy_lamp():
|
||||
run ("yum install -y httpd mariadb-server php php-mysql")
|
||||
```
|
||||
|
||||
##### 在 Debian/Ubuntu 或 Linux Mint 上
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
from fabric.api import env, run
|
||||
env.hosts = ['192.168.0.2','192.168.0.6']
|
||||
def deploy_lamp():
|
||||
sudo("apt-get install -q apache2 mysql-server libapache2-mod-php5 php5-mysql")
|
||||
```
|
||||
|
||||
保存并执行以下命令:
|
||||
|
||||
```
|
||||
# fab deploy_lamp
|
||||
```
|
||||
|
||||
注:由于安装时会输出大量信息,这个例子我们就不提供屏幕 gif 图了
|
||||
|
||||
现在你可以使用 Fabric 和上文例子所示的功能来[自动化的管理 Linux 服务器上的任务][2]了。
|
||||
|
||||
#### 一些 Fabric 有用的选项
|
||||
|
||||
- 你可以运行 `fab -help` 输出帮助信息,里面列出了所有可以使用的命令行信息
|
||||
- `–fabfile=PATH` 选项可以让你定义除了名为 fabfile.py 之外的模块
|
||||
- 如果你想用指定的用户名登录远程主机,请使用 `-user=USER` 选项
|
||||
- 如果你需要密码进行验证或者 sudo 提权,请使用 `–password=PASSWORD` 选项
|
||||
- 如果需要输出某个命令的详细信息,请使用 `–display=命令名` 选项
|
||||
- 使用 `--list` 输出所有可用的任务
|
||||
- 使用 `--list-format=FORMAT` 选项能格式化 `-list` 选项输出的信息,可选的有 short、normal、 nested
|
||||
- `--config=PATH` 选项可以指定读取配置文件的地址
|
||||
- `-–colorize-errors` 能显示彩色的错误输出信息
|
||||
- `--version` 输出当前版本
|
||||
|
||||
### 总结
|
||||
|
||||
Fabric 是一个强大并且文档完备的工具,对于新手来说也能很快上手,阅读提供的文档能帮助你更好的了解它。如果你在安装和使用 Fabric 时发现什么问题可以在评论区留言,我们会及时回复。
|
||||
|
||||
参考:[Fabric 文档][3]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/automating-linux-system-administration-tasks/
|
||||
|
||||
作者:[Aaron Kili][a]
|
||||
译者:[NearTan](https://github.com/NearTan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/aaronkili/
|
||||
[1]: https://linux.cn/article-2324-1.html
|
||||
[2]: http://www.tecmint.com/use-ansible-playbooks-to-automate-complex-tasks-on-multiple-linux-servers/
|
||||
[3]: http://docs.fabfile.org/en/1.4.0/usage/env.html
|
96
published/201608/20151208 6 creative ways to use ownCloud.md
Normal file
96
published/201608/20151208 6 creative ways to use ownCloud.md
Normal file
@ -0,0 +1,96 @@
|
||||
ownCloud 的六大神奇用法
|
||||
================================================================================
|
||||
|
||||
![Yearbook cover 2015](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/osdc-open-source-yearbook-lead1-inc0335020sw-201511-01.png)
|
||||
|
||||
(图片来源:Opensource.com)
|
||||
|
||||
[ownCloud][1] 是一个自行托管的开源文件同步和共享服务器。就像“行业老大” Dropbox、Google Drive、Box 和其他的同类服务一样,ownCloud 也可以让你访问自己的文件、日历、联系人和其他数据。你可以在自己设备之间同步任意数据(或部分数据)并分享给其他人。然而,ownCloud 要比其它的商业解决方案更棒,可以[将 ownCloud 运行在自己的服务器][2]而不是其它人的服务器上。
|
||||
|
||||
现在,让我们一起来看看在 ownCloud 上的六个创造性的应用方式。其中一些是由于 ownCloud 的开源才得以完成,而另外的则是 ownCloud 自身特有的功能。
|
||||
|
||||
### 1. 可扩展的 ownCloud “派”集群 ###
|
||||
|
||||
由于 ownCloud 是开源的,你可以选择将它运行在自己的服务器中,或者从你信任的服务商那里获取空间——没必要将你的文件存储在那些大公司的服务器中,谁知他们将你的文件存储到哪里去。[点击此处查看部分 ownCloud 服务商][3],或者下载该服务软件到你的虚拟主机中[搭建自己的服务器][4].
|
||||
|
||||
![](https://opensource.com/sites/default/files/images/life-uploads/banana-pi-owncloud-cluster.jpg)
|
||||
|
||||
*拍摄: Jörn Friedrich Dreyer. [CC BY-SA 4.0.][5]*
|
||||
|
||||
我们见过最具创意的事情就是架设[香蕉派集群][6]和[树莓派集群][7]。ownCloud 的扩展性通常用于支持成千上万的用户,但有些人则将它往不同方向发展,通过将多个微型系统集群在一起,就可以创建出运行速度超快的 ownCloud。酷毙了!
|
||||
|
||||
### 2. 密码同步 ###
|
||||
|
||||
为了让 ownCloud 更容易扩展,我们将它变得超级的模块化,甚至还有一个 [ownCloud 应用商店][8]。你可以在里边找到音乐和视频播放器、日历、联系人、生产力应用、游戏、应用模板(sketching app)等等。
|
||||
|
||||
从近 200 多个应用中仅挑选一个是一件非常困难的事,但密码管理则是一个很独特的功能。只有不超过三个应用提供这个功能:[Passwords][9]、[Secure Container][10] 和 [Passman][11]。
|
||||
|
||||
![](https://opensource.com/sites/default/files/images/life-uploads/password.png)
|
||||
|
||||
### 3. 随心所欲地存储文件 ###
|
||||
|
||||
外部存储可以让你将现有数据挂载到 ownCloud 上,让你通过一个界面来访问存储在 FTP、WebDAV、Amazon S3,甚至 Dropbox 和 Google Drive 的文件。
|
||||
|
||||
注:youtube 视频
|
||||
<iframe width="520" height="315" frameborder="0" allowfullscreen="" src="https://www.youtube.com/embed/uezzFDRnoPY"></iframe>
|
||||
|
||||
行业老大们喜欢创建自己的 “藩篱花园”,Box 的用户只能和其它的 Box 用户协作;假如你想从 Google Drive 分享你的文件,你的同伴也必须要有一个 Google 账号才可以访问的分享。通过 ownCloud 的外部存储功能,你可以轻松打破这些。
|
||||
|
||||
最有创意的就是把 Google Drive 和 Dropbox 添加为外部存储。这样你就可以无缝连接它们,通过一个简单的链接即可分享给其它人——并不需要账户。
|
||||
|
||||
### 4. 获取上传的文件 ###
|
||||
|
||||
由于 ownCloud 是开源开,人们可以不受公司需求的制约而向它贡献感兴趣的功能。我们的贡献者总是很在意安全和隐私,所以 ownCloud 引入的通过密码保护公共链接并[设置失效期限][12]的功能要比其它人早很多。
|
||||
|
||||
现在,ownCloud 可以配置分享链接的读写权限了,这就是说链接的访问者可以无缝的编辑你分享给他们的文件(可以有密码保护,也可以没有),或者将文件上传到服务器前不用强制他们提供私人信息来注册服务。
|
||||
|
||||
注:youtube 视频
|
||||
<iframe width="520" height="315" frameborder="0" allowfullscreen="" src="https://www.youtube.com/embed/3GSppxEhmZY"></iframe>
|
||||
|
||||
对于有人想给你分享大体积的文件时,这个特性就非常有用了。相比于上传到第三方站点、然后给你发送一个连接、你再去下载文件(通常需要登录),ownCloud 仅需要上传文件到你提供的分享文件夹,你就可以马上获取到文件了。
|
||||
|
||||
### 5. 免费却又安全的存储空间 ###
|
||||
|
||||
之前就强调过,我们的代码贡献者最关注的就是安全和隐私,这就是 ownCloud 中有用于加密和解密存储数据的应用的原因。
|
||||
|
||||
通过使用 ownCloud 将你的文件存储到 Dropbox 或者 Google Drive,则会违背夺回数据的控制权并保持数据隐私的初衷。但是加密应用则可以改变这个状况。在发送数据给这些提供商前进行数据加密,并在取回数据的时候进行解密,你的数据就会变得很安全。
|
||||
|
||||
### 6. 在你的可控范围内分享文件 ###
|
||||
|
||||
作为开源项目,ownCloud 没有必要自建 “藩篱花园”。通过“联邦云共享(Federated Cloud Sharing)”:这个[由 ownCloud 开发和发布的][13]协议使不同的文件同步和共享服务器可以彼此之间进行通信,并能够安全地传输文件。联邦云共享本身来自一个有趣的事情:有 [22 所德国大学][14] 想要为自身的 50 万名学生建立一个庞大的云服务,但是每个大学都想控制自己学生的数据。于是乎,我们需要一个创造性的解决方案:也就是联邦云服务。该解决方案可以连接全部的大学,使得学生们可以无缝的协同工作。同时,每个大学的系统管理员保持着对自己学生创建的文件的控制权,并可采用自己的策略,如限制限额,或者限制什么人、什么文件以及如何共享。
|
||||
|
||||
注:youtube 视频
|
||||
<iframe width="520" height="315" frameborder="0" allowfullscreen="" src="https://www.youtube.com/embed/9-JEmlH2DEg"></iframe>
|
||||
|
||||
并且,这项神奇的技术并没有限制于德国的大学之间,每个 ownCloud 用户都能在自己的用户设置中找到自己的[联邦云 ID][15],并将之分享给同伴。
|
||||
|
||||
现在你明白了吧。通过这六个方式,ownCloud 就能让人们做一些特殊而独特的事。而使这一切成为可能的,就是 ownCloud 是开源的,其设计目标就是让你的数据自由。
|
||||
|
||||
你有其它的 ownCloud 的创意用法吗?请发表评论让我们知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/life/15/12/6-creative-ways-use-owncloud
|
||||
|
||||
作者:[Jos Poortvliet][a]
|
||||
译者:[GHLandy](https://github.com/GHLandy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/jospoortvliet
|
||||
[1]:https://owncloud.com/
|
||||
[2]:https://blogs.fsfe.org/mk/new-stickers-and-leaflets-no-cloud-and-e-mail-self-defense/
|
||||
[3]:https://owncloud.org/providers
|
||||
[4]:https://owncloud.org/install/#instructions-server
|
||||
[5]:https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]:http://www.owncluster.de/
|
||||
[7]:https://christopherjcoleman.wordpress.com/2013/01/05/host-your-owncloud-on-a-raspberry-pi-cluster/
|
||||
[8]:https://apps.owncloud.com/
|
||||
[9]:https://apps.owncloud.com/content/show.php/Passwords?content=170480
|
||||
[10]:https://apps.owncloud.com/content/show.php/Secure+Container?content=167268
|
||||
[11]:https://apps.owncloud.com/content/show.php/Passman?content=166285
|
||||
[12]:https://owncloud.com/owncloud45-community/
|
||||
[13]:http://karlitschek.de/2015/08/announcing-the-draft-federated-cloud-sharing-api/
|
||||
[14]:https://owncloud.com/customer/sciebo/
|
||||
[15]:https://owncloud.org/federation/
|
498
published/201608/20151220 GCC-Inline-Assembly-HOWTO.md
Normal file
498
published/201608/20151220 GCC-Inline-Assembly-HOWTO.md
Normal file
@ -0,0 +1,498 @@
|
||||
* * *
|
||||
|
||||
# GCC 内联汇编 HOWTO
|
||||
|
||||
v0.1, 01 March 2003.
|
||||
* * *
|
||||
|
||||
_本 HOWTO 文档将讲解 GCC 提供的内联汇编特性的用途和用法。对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 汇编语言和 C 语言的基本认识。_
|
||||
|
||||
* * *
|
||||
|
||||
## 1. 简介
|
||||
|
||||
### 1.1 版权许可
|
||||
|
||||
Copyright (C)2003 Sandeep S.
|
||||
|
||||
本文档自由共享;你可以重新发布它,并且/或者在遵循自由软件基金会发布的 GNU 通用公共许可证下修改它;也可以是该许可证的版本 2 或者(按照你的需求)更晚的版本。
|
||||
|
||||
发布这篇文档是希望它能够帮助别人,但是没有任何担保;甚至不包括可售性和适用于任何特定目的的担保。关于更详细的信息,可以查看 GNU 通用许可证。
|
||||
|
||||
### 1.2 反馈校正
|
||||
|
||||
请将反馈和批评一起提交给 [Sandeep.S](mailto:busybox@sancharnet.in) 。我将感谢任何一个指出本文档中错误和不准确之处的人;一被告知,我会马上改正它们。
|
||||
|
||||
### 1.3 致谢
|
||||
|
||||
我对提供如此棒的特性的 GNU 人们表示真诚的感谢。感谢 Mr.Pramode C E 所做的所有帮助。感谢在 Govt Engineering College 和 Trichur 的朋友们的精神支持和合作,尤其是 Nisha Kurur 和 Sakeeb S 。 感谢在 Gvot Engineering College 和 Trichur 的老师们的合作。
|
||||
|
||||
另外,感谢 Phillip , Brennan Underwood 和 colin@nyx.net ;这里的许多东西都厚颜地直接取自他们的工作成果。
|
||||
|
||||
* * *
|
||||
|
||||
## 2. 概览
|
||||
|
||||
在这里,我们将学习 GCC 内联汇编。这里内联(inline)表示的是什么呢?
|
||||
|
||||
我们可以要求编译器将一个函数的代码插入到调用者代码中函数被实际调用的地方。这样的函数就是内联函数。这听起来和宏差不多?这两者确实有相似之处。
|
||||
|
||||
内联函数的优点是什么呢?
|
||||
|
||||
这种内联方法可以减少函数调用开销。同时如果所有实参的值为常量,它们的已知值可以在编译期允许简化,因此并非所有的内联函数代码都需要被包含进去。代码大小的影响是不可预测的,这取决于特定的情况。为了声明一个内联函数,我们必须在函数声明中使用 `inline` 关键字。
|
||||
|
||||
现在我们正处于一个猜测内联汇编到底是什么的点上。它只不过是一些写为内联函数的汇编程序。在系统编程上,它们方便、快速并且极其有用。我们主要集中学习(GCC)内联汇编函数的基本格式和用法。为了声明内联汇编函数,我们使用 `asm` 关键词。
|
||||
|
||||
内联汇编之所以重要,主要是因为它可以操作并且使其输出通过 C 变量显示出来。正是因为此能力, "asm" 可以用作汇编指令和包含它的 C 程序之间的接口。
|
||||
|
||||
* * *
|
||||
|
||||
## 3. GCC 汇编语法
|
||||
|
||||
Linux上的 GNU C 编译器 GCC ,使用 **AT&T** / **UNIX** 汇编语法。在这里,我们将使用 AT&T 语法 进行汇编编码。如果你对 AT&T 语法不熟悉的话,请不要紧张,我会教你的。AT&T 语法和 Intel 语法的差别很大。我会给出主要的区别。
|
||||
|
||||
1. 源操作数和目的操作数顺序
|
||||
|
||||
AT&T 语法的操作数方向和 Intel 语法的刚好相反。在Intel 语法中,第一操作数为目的操作数,第二操作数为源操作数,然而在 AT&T 语法中,第一操作数为源操作数,第二操作数为目的操作数。也就是说,
|
||||
|
||||
Intel 语法中的 `Op-code dst src` 变为
|
||||
|
||||
AT&T 语法中的 `Op-code src dst`。
|
||||
|
||||
2. 寄存器命名
|
||||
|
||||
寄存器名称有 `%` 前缀,即如果必须使用 `eax`,它应该用作 `%eax`。
|
||||
|
||||
3. 立即数
|
||||
|
||||
AT&T 立即数以 `$` 为前缀。静态 "C" 变量也使用 `$` 前缀。在 Intel 语法中,十六进制常量以 `h` 为后缀,然而 AT&T 不使用这种语法,这里我们给常量添加前缀 `0x`。所以,对于十六进制,我们首先看到一个 `$`,然后是 `0x`,最后才是常量。
|
||||
|
||||
4. 操作数大小
|
||||
|
||||
在 AT&T 语法中,存储器操作数的大小取决于操作码名字的最后一个字符。操作码后缀 ’b’ 、’w’、’l’ 分别指明了字节(byte)(8位)、字(word)(16位)、长型(long)(32位)存储器引用。Intel 语法通过给存储器操作数添加 `byte ptr`、 `word ptr` 和 `dword ptr` 前缀来实现这一功能。
|
||||
|
||||
因此,Intel的 `mov al, byte ptr foo` 在 AT&T 语法中为 `movb foo, %al`。
|
||||
|
||||
5. 存储器操作数
|
||||
|
||||
在 Intel 语法中,基址寄存器包含在 `[` 和 `]` 中,然而在 AT&T 中,它们变为 `(` 和 `)`。另外,在 Intel 语法中, 间接内存引用为
|
||||
|
||||
`section:[base + index*scale + disp]`,在 AT&T中变为 `section:disp(base, index, scale)`。
|
||||
|
||||
需要牢记的一点是,当一个常量用于 disp 或 scale,不能添加 `$` 前缀。
|
||||
|
||||
现在我们看到了 Intel 语法和 AT&T 语法之间的一些主要差别。我仅仅写了它们差别的一部分而已。关于更完整的信息,请参考 GNU 汇编文档。现在为了更好地理解,我们可以看一些示例。
|
||||
|
||||
```
|
||||
+------------------------------+------------------------------------+
|
||||
| Intel Code | AT&T Code |
|
||||
+------------------------------+------------------------------------+
|
||||
| mov eax,1 | movl $1,%eax |
|
||||
| mov ebx,0ffh | movl $0xff,%ebx |
|
||||
| int 80h | int $0x80 |
|
||||
| mov ebx, eax | movl %eax, %ebx |
|
||||
| mov eax,[ecx] | movl (%ecx),%eax |
|
||||
| mov eax,[ebx+3] | movl 3(%ebx),%eax |
|
||||
| mov eax,[ebx+20h] | movl 0x20(%ebx),%eax |
|
||||
| add eax,[ebx+ecx*2h] | addl (%ebx,%ecx,0x2),%eax |
|
||||
| lea eax,[ebx+ecx] | leal (%ebx,%ecx),%eax |
|
||||
| sub eax,[ebx+ecx*4h-20h] | subl -0x20(%ebx,%ecx,0x4),%eax |
|
||||
+------------------------------+------------------------------------+
|
||||
```
|
||||
* * *
|
||||
|
||||
## 4. 基本内联
|
||||
|
||||
基本内联汇编的格式非常直接了当。它的基本格式为
|
||||
|
||||
`asm("汇编代码");`
|
||||
|
||||
示例
|
||||
|
||||
```
|
||||
asm("movl %ecx %eax"); /* 将 ecx 寄存器的内容移至 eax */
|
||||
__asm__("movb %bh (%eax)"); /* 将 bh 的一个字节数据 移至 eax 寄存器指向的内存 */
|
||||
```
|
||||
|
||||
你可能注意到了这里我使用了 `asm ` 和 `__asm__`。这两者都是有效的。如果关键词 `asm` 和我们程序的一些标识符冲突了,我们可以使用 `__asm__`。如果我们的指令多于一条,我们可以每个一行,并用双引号圈起,同时为每条指令添加 ’\n’ 和 ’\t’ 后缀。这是因为 gcc 将每一条当作字符串发送给 **as**(GAS)(LCTT 译注: GAS 即 GNU 汇编器),并且通过使用换行符/制表符发送正确格式化后的行给汇编器。
|
||||
|
||||
示例
|
||||
|
||||
```
|
||||
__asm__ ("movl %eax, %ebx\n\t"
|
||||
"movl $56, %esi\n\t"
|
||||
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
|
||||
"movb %ah, (%ebx)");
|
||||
```
|
||||
|
||||
如果在代码中,我们涉及到一些寄存器(即改变其内容),但在没有恢复这些变化的情况下从汇编中返回,这将会导致一些意想不到的事情。这是因为 GCC 并不知道寄存器内容的变化,这会导致问题,特别是当编译器做了某些优化。在没有告知 GCC 的情况下,它将会假设一些寄存器存储了一些值——而我们可能已经改变却没有告知 GCC——它会像什么事都没发生一样继续运行(LCTT 译注:什么事都没发生一样是指GCC不会假设寄存器装入的值是有效的,当退出改变了寄存器值的内联汇编后,寄存器的值不会保存到相应的变量或内存空间)。我们所可以做的是使用那些没有副作用的指令,或者当我们退出时恢复这些寄存器,要不就等着程序崩溃吧。这是为什么我们需要一些扩展功能,扩展汇编给我们提供了那些功能。
|
||||
|
||||
* * *
|
||||
|
||||
## 5. 扩展汇编
|
||||
|
||||
在基本内联汇编中,我们只有指令。然而在扩展汇编中,我们可以同时指定操作数。它允许我们指定输入寄存器、输出寄存器以及修饰寄存器列表。GCC 不强制用户必须指定使用的寄存器。我们可以把头疼的事留给 GCC ,这可能可以更好地适应 GCC 的优化。不管怎么说,基本格式为:
|
||||
|
||||
```
|
||||
asm ( 汇编程序模板
|
||||
: 输出操作数 /* 可选的 */
|
||||
: 输入操作数 /* 可选的 */
|
||||
: 修饰寄存器列表 /* 可选的 */
|
||||
);
|
||||
```
|
||||
|
||||
汇编程序模板由汇编指令组成。每一个操作数由一个操作数约束字符串所描述,其后紧接一个括弧括起的 C 表达式。冒号用于将汇编程序模板和第一个输出操作数分开,另一个(冒号)用于将最后一个输出操作数和第一个输入操作数分开(如果存在的话)。逗号用于分离每一个组内的操作数。总操作数的数目限制在 10 个,或者机器描述中的任何指令格式中的最大操作数数目,以较大者为准。
|
||||
|
||||
如果没有输出操作数但存在输入操作数,你必须将两个连续的冒号放置于输出操作数原本会放置的地方周围。
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
asm ("cld\n\t"
|
||||
"rep\n\t"
|
||||
"stosl"
|
||||
: /* 无输出寄存器 */
|
||||
: "c" (count), "a" (fill_value), "D" (dest)
|
||||
: "%ecx", "%edi"
|
||||
);
|
||||
```
|
||||
|
||||
现在来看看这段代码是干什么的?以上的内联汇编是将 `fill_value` 值连续 `count` 次拷贝到寄存器 `edi` 所指位置(LCTT 译注:每执行 stosl 一次,寄存器 edi 的值会递增或递减,这取决于是否设置了 direction 标志,因此以上代码实则初始化一个内存块)。 它也告诉 gcc 寄存器 `ecx` 和 `edi` 一直无效(LCTT 译注:原文为 eax ,但代码修饰寄存器列表中为 ecx,因此这可能为作者的纰漏。)。为了更加清晰地说明,让我们再看一个示例。
|
||||
|
||||
```
|
||||
int a=10, b;
|
||||
asm ("movl %1, %%eax;
|
||||
movl %%eax, %0;"
|
||||
:"=r"(b) /* 输出 */
|
||||
:"r"(a) /* 输入 */
|
||||
:"%eax" /* 修饰寄存器 */
|
||||
);
|
||||
```
|
||||
|
||||
这里我们所做的是使用汇编指令使 ’b’ 变量的值等于 ’a’ 变量的值。一些有意思的地方是:
|
||||
|
||||
* "b" 为输出操作数,用 %0 引用,并且 "a" 为输入操作数,用 %1 引用。
|
||||
* "r" 为操作数约束。之后我们会更详细地了解约束(字符串)。目前,"r" 告诉 GCC 可以使用任一寄存器存储操作数。输出操作数约束应该有一个约束修饰符 "=" 。这修饰符表明它是一个只读的输出操作数。
|
||||
* 寄存器名字以两个 % 为前缀。这有利于 GCC 区分操作数和寄存器。操作数以一个 % 为前缀。
|
||||
* 第三个冒号之后的修饰寄存器 %eax 用于告诉 GCC %eax 的值将会在 "asm" 内部被修改,所以 GCC 将不会使用此寄存器存储任何其他值。
|
||||
|
||||
当 “asm” 执行完毕, "b" 变量会映射到更新的值,因为它被指定为输出操作数。换句话说, “asm” 内 "b" 变量的修改应该会被映射到 “asm” 外部。
|
||||
|
||||
现在,我们可以更详细地看看每一个域。
|
||||
|
||||
### 5.1 汇编程序模板
|
||||
|
||||
汇编程序模板包含了被插入到 C 程序的汇编指令集。其格式为:每条指令用双引号圈起,或者整个指令组用双引号圈起。同时每条指令应以分界符结尾。有效的分界符有换行符(`\n`)和分号(`;`)。`\n` 可以紧随一个制表符(`\t`)。我们应该都明白使用换行符或制表符的原因了吧(LCTT 译注:就是为了排版和分隔)?和 C 表达式对应的操作数使用 %0、%1 ... 等等表示。
|
||||
|
||||
### 5.2 操作数
|
||||
|
||||
C 表达式用作 “asm” 内的汇编指令操作数。每个操作数前面是以双引号圈起的操作数约束。对于输出操作数,在引号内还有一个约束修饰符,其后紧随一个用于表示操作数的 C 表达式。即,“操作数约束”(C 表达式)是一个通用格式。对于输出操作数,还有一个额外的修饰符。约束字符串主要用于决定操作数的寻址方式,同时也用于指定使用的寄存器。
|
||||
|
||||
如果我们使用的操作数多于一个,那么每一个操作数用逗号隔开。
|
||||
|
||||
在汇编程序模板中,每个操作数用数字引用。编号方式如下。如果总共有 n 个操作数(包括输入和输出操作数),那么第一个输出操作数编号为 0 ,逐项递增,并且最后一个输入操作数编号为 n - 1 。操作数的最大数目在前一节我们讲过。
|
||||
|
||||
输出操作数表达式必须为左值。输入操作数的要求不像这样严格。它们可以为表达式。扩展汇编特性常常用于编译器所不知道的机器指令 ;-)。如果输出表达式无法直接寻址(即,它是一个位域),我们的约束字符串必须给定一个寄存器。在这种情况下,GCC 将会使用该寄存器作为汇编的输出,然后存储该寄存器的内容到输出。
|
||||
|
||||
正如前面所陈述的一样,普通的输出操作数必须为只写的; GCC 将会假设指令前的操作数值是死的,并且不需要被(提前)生成。扩展汇编也支持输入-输出或者读-写操作数。
|
||||
|
||||
所以现在我们来关注一些示例。我们想要求一个数的5次方结果。为了计算该值,我们使用 `lea` 指令。
|
||||
|
||||
```
|
||||
asm ("leal (%1,%1,4), %0"
|
||||
: "=r" (five_times_x)
|
||||
: "r" (x)
|
||||
);
|
||||
```
|
||||
|
||||
这里我们的输入为 x。我们不指定使用的寄存器。 GCC 将会选择一些输入寄存器,一个输出寄存器,来做我们预期的工作。如果我们想要输入和输出放在同一个寄存器里,我们也可以要求 GCC 这样做。这里我们使用那些读-写操作数类型。这里我们通过指定合适的约束来实现它。
|
||||
|
||||
```
|
||||
asm ("leal (%0,%0,4), %0"
|
||||
: "=r" (five_times_x)
|
||||
: "0" (x)
|
||||
);
|
||||
```
|
||||
|
||||
现在输出和输出操作数位于同一个寄存器。但是我们无法得知是哪一个寄存器。现在假如我们也想要指定操作数所在的寄存器,这里有一种方法。
|
||||
|
||||
```
|
||||
asm ("leal (%%ecx,%%ecx,4), %%ecx"
|
||||
: "=c" (x)
|
||||
: "c" (x)
|
||||
);
|
||||
```
|
||||
|
||||
在以上三个示例中,我们并没有在修饰寄存器列表里添加任何寄存器,为什么?在头两个示例, GCC 决定了寄存器并且它知道发生了什么改变。在最后一个示例,我们不必将 'ecx' 添加到修饰寄存器列表(LCTT 译注: 原文修饰寄存器列表这个单词拼写有错,这里已修正),gcc 知道它表示 x。因此,因为它可以知道 `ecx` 的值,它就不被当作修饰的(寄存器)了。
|
||||
|
||||
### 5.3 修饰寄存器列表
|
||||
|
||||
一些指令会破坏一些硬件寄存器内容。我们不得不在修饰寄存器中列出这些寄存器,即汇编函数内第三个 ’**:**’ 之后的域。这可以通知 gcc 我们将会自己使用和修改这些寄存器,这样 gcc 就不会假设存入这些寄存器的值是有效的。我们不用在这个列表里列出输入、输出寄存器。因为 gcc 知道 “asm” 使用了它们(因为它们被显式地指定为约束了)。如果指令隐式或显式地使用了任何其他寄存器,(并且寄存器没有出现在输出或者输出约束列表里),那么就需要在修饰寄存器列表中指定这些寄存器。
|
||||
|
||||
如果我们的指令可以修改条件码寄存器(cc),我们必须将 "cc" 添加进修饰寄存器列表。
|
||||
|
||||
如果我们的指令以不可预测的方式修改了内存,那么需要将 "memory" 添加进修饰寄存器列表。这可以使 GCC 不会在汇编指令间保持缓存于寄存器的内存值。如果被影响的内存不在汇编的输入或输出列表中,我们也必须添加 **volatile** 关键词。
|
||||
|
||||
我们可以按我们的需求多次读写修饰寄存器。参考一下模板内的多指令示例;它假设子例程 _foo 接受寄存器 `eax` 和 `ecx` 里的参数。
|
||||
|
||||
```
|
||||
asm ("movl %0,%%eax;
|
||||
movl %1,%%ecx;
|
||||
call _foo"
|
||||
: /* no outputs */
|
||||
: "g" (from), "g" (to)
|
||||
: "eax", "ecx"
|
||||
);
|
||||
```
|
||||
|
||||
### 5.4 Volatile ...?
|
||||
|
||||
如果你熟悉内核源码或者类似漂亮的代码,你一定见过许多声明为 `volatile` 或者 `__volatile__`的函数,其跟着一个 `asm` 或者 `__asm__`。我之前提到过关键词 `asm` 和 `__asm__`。那么什么是 `volatile` 呢?
|
||||
|
||||
如果我们的汇编语句必须在我们放置它的地方执行(例如,不能为了优化而被移出循环语句),将关键词 `volatile` 放置在 asm 后面、()的前面。以防止它被移动、删除或者其他操作,我们将其声明为 `asm volatile ( ... : ... : ... : ...);`
|
||||
|
||||
如果担心发生冲突,请使用 `__volatile__`。
|
||||
|
||||
如果我们的汇编只是用于一些计算并且没有任何副作用,不使用 `volatile` 关键词会更好。不使用 `volatile` 可以帮助 gcc 优化代码并使代码更漂亮。
|
||||
|
||||
|
||||
在“一些实用的诀窍”一节中,我提供了多个内联汇编函数的例子。那里我们可以了解到修饰寄存器列表的细节。
|
||||
|
||||
* * *
|
||||
|
||||
## 6. 更多关于约束
|
||||
|
||||
到这个时候,你可能已经了解到约束和内联汇编有很大的关联。但我们对约束讲的还不多。约束用于表明一个操作数是否可以位于寄存器和位于哪种寄存器;操作数是否可以为一个内存引用和哪种地址;操作数是否可以为一个立即数和它可能的取值范围(即值的范围),等等。
|
||||
|
||||
### 6.1 常用约束
|
||||
|
||||
在许多约束中,只有小部分是常用的。我们来看看这些约束。
|
||||
|
||||
1. **寄存器操作数约束(r)**
|
||||
|
||||
当使用这种约束指定操作数时,它们存储在通用寄存器(GPR)中。请看下面示例:
|
||||
|
||||
`asm ("movl %%eax, %0\n" :"=r"(myval));`
|
||||
|
||||
这里,变量 myval 保存在寄存器中,寄存器 eax 的值被复制到该寄存器中,并且 myval 的值从寄存器更新到了内存。当指定 "r" 约束时, gcc 可以将变量保存在任何可用的 GPR 中。要指定寄存器,你必须使用特定寄存器约束直接地指定寄存器的名字。它们为:
|
||||
|
||||
```
|
||||
+---+--------------------+
|
||||
| r | Register(s) |
|
||||
+---+--------------------+
|
||||
| a | %eax, %ax, %al |
|
||||
| b | %ebx, %bx, %bl |
|
||||
| c | %ecx, %cx, %cl |
|
||||
| d | %edx, %dx, %dl |
|
||||
| S | %esi, %si |
|
||||
| D | %edi, %di |
|
||||
+---+--------------------+
|
||||
```
|
||||
|
||||
2. **内存操作数约束(m)**
|
||||
|
||||
当操作数位于内存时,任何对它们的操作将直接发生在内存位置,这与寄存器约束相反,后者首先将值存储在要修改的寄存器中,然后将它写回到内存位置。但寄存器约束通常用于一个指令必须使用它们或者它们可以大大提高处理速度的地方。当需要在 “asm” 内更新一个 C 变量,而又不想使用寄存器去保存它的值,使用内存最为有效。例如,IDTR 寄存器的值存储于内存位置 loc 处:
|
||||
|
||||
`asm("sidt %0\n" : :"m"(loc));`
|
||||
|
||||
3. **匹配(数字)约束**
|
||||
|
||||
在某些情况下,一个变量可能既充当输入操作数,也充当输出操作数。可以通过使用匹配约束在 "asm" 中指定这种情况。
|
||||
|
||||
`asm ("incl %0" :"=a"(var):"0"(var));`
|
||||
|
||||
在操作数那一节中,我们也看到了一些类似的示例。在这个匹配约束的示例中,寄存器 "%eax" 既用作输入变量,也用作输出变量。 var 输入被读进 %eax,并且等递增后更新的 %eax 再次被存储进 var。这里的 "0" 用于指定与第 0 个输出变量相同的约束。也就是,它指定 var 输出实例应只被存储在 "%eax" 中。该约束可用于:
|
||||
- 在输入从变量读取或变量修改后且修改被写回同一变量的情况
|
||||
- 在不需要将输入操作数实例和输出操作数实例分开的情况
|
||||
|
||||
使用匹配约束最重要的意义在于它们可以有效地使用可用寄存器。
|
||||
|
||||
其他一些约束:
|
||||
|
||||
1. "m" : 允许一个内存操作数,可以使用机器普遍支持的任一种地址。
|
||||
2. "o" : 允许一个内存操作数,但只有当地址是可偏移的。即,该地址加上一个小的偏移量可以得到一个有效地址。
|
||||
3. "V" : 一个不允许偏移的内存操作数。换言之,任何适合 "m" 约束而不适合 "o" 约束的操作数。
|
||||
4. "i" : 允许一个(带有常量)的立即整形操作数。这包括其值仅在汇编时期知道的符号常量。
|
||||
5. "n" : 允许一个带有已知数字的立即整形操作数。许多系统不支持汇编时期的常量,因为操作数少于一个字宽。对于此种操作数,约束应该使用 'n' 而不是'i'。
|
||||
6. "g" : 允许任一寄存器、内存或者立即整形操作数,不包括通用寄存器之外的寄存器。
|
||||
|
||||
以下约束为 x86 特有。
|
||||
|
||||
1. "r" : 寄存器操作数约束,查看上面给定的表格。
|
||||
2. "q" : 寄存器 a、b、c 或者 d。
|
||||
3. "I" : 范围从 0 到 31 的常量(对于 32 位移位)。
|
||||
4. "J" : 范围从 0 到 63 的常量(对于 64 位移位)。
|
||||
5. "K" : 0xff。
|
||||
6. "L" : 0xffff。
|
||||
7. "M" : 0、1、2 或 3 (lea 指令的移位)。
|
||||
8. "N" : 范围从 0 到 255 的常量(对于 out 指令)。
|
||||
9. "f" : 浮点寄存器
|
||||
10. "t" : 第一个(栈顶)浮点寄存器
|
||||
11. "u" : 第二个浮点寄存器
|
||||
12. "A" : 指定 `a` 或 `d` 寄存器。这主要用于想要返回 64 位整形数,使用 `d` 寄存器保存最高有效位和 `a` 寄存器保存最低有效位。
|
||||
|
||||
### 6.2 约束修饰符
|
||||
|
||||
当使用约束时,对于更精确的控制超过了对约束作用的需求,GCC 给我们提供了约束修饰符。最常用的约束修饰符为:
|
||||
|
||||
1. "=" : 意味着对于这条指令,操作数为只写的;旧值会被忽略并被输出数据所替换。
|
||||
2. "&" : 意味着这个操作数为一个早期改动的操作数,其在该指令完成前通过使用输入操作数被修改了。因此,这个操作数不可以位于一个被用作输出操作数或任何内存地址部分的寄存器。如果在旧值被写入之前它仅用作输入而已,一个输入操作数可以为一个早期改动操作数。
|
||||
|
||||
上述的约束列表和解释并不完整。示例可以让我们对内联汇编的用途和用法更好的理解。在下一节,我们会看到一些示例,在那里我们会发现更多关于修饰寄存器列表的东西。
|
||||
|
||||
* * *
|
||||
|
||||
## 7. 一些实用的诀窍
|
||||
|
||||
现在我们已经介绍了关于 GCC 内联汇编的基础理论,现在我们将专注于一些简单的例子。将内联汇编函数写成宏的形式总是非常方便的。我们可以在 Linux 内核代码里看到许多汇编函数。(usr/src/linux/include/asm/*.h)。
|
||||
|
||||
1. 首先我们从一个简单的例子入手。我们将写一个两个数相加的程序。
|
||||
|
||||
```
|
||||
int main(void)
|
||||
{
|
||||
int foo = 10, bar = 15;
|
||||
__asm__ __volatile__("addl %%ebx,%%eax"
|
||||
:"=a"(foo)
|
||||
:"a"(foo), "b"(bar)
|
||||
);
|
||||
printf("foo+bar=%d\n", foo);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
这里我们要求 GCC 将 foo 存放于 %eax,将 bar 存放于 %ebx,同时我们也想要在 %eax 中存放结果。'=' 符号表示它是一个输出寄存器。现在我们可以以其他方式将一个整数加到一个变量。
|
||||
|
||||
```
|
||||
__asm__ __volatile__(
|
||||
" lock ;\n"
|
||||
" addl %1,%0 ;\n"
|
||||
: "=m" (my_var)
|
||||
: "ir" (my_int), "m" (my_var)
|
||||
: /* 无修饰寄存器列表 */
|
||||
);
|
||||
```
|
||||
|
||||
这是一个原子加法。为了移除原子性,我们可以移除指令 'lock'。在输出域中,"=m" 表明 my_var 是一个输出且位于内存。类似地,"ir" 表明 my_int 是一个整型,并应该存在于其他寄存器(回想我们上面看到的表格)。没有寄存器位于修饰寄存器列表中。
|
||||
|
||||
2. 现在我们将在一些寄存器/变量上展示一些操作,并比较值。
|
||||
|
||||
```
|
||||
__asm__ __volatile__( "decl %0; sete %1"
|
||||
: "=m" (my_var), "=q" (cond)
|
||||
: "m" (my_var)
|
||||
: "memory"
|
||||
);
|
||||
```
|
||||
|
||||
这里,my_var 的值减 1 ,并且如果结果的值为 0,则变量 cond 置 1。我们可以通过将指令 "lock;\n\t" 添加为汇编模板的第一条指令以增加原子性。
|
||||
|
||||
以类似的方式,为了增加 my_var,我们可以使用 "incl %0" 而不是 "decl %0"。
|
||||
|
||||
这里需要注意的地方是(i)my_var 是一个存储于内存的变量。(ii)cond 位于寄存器 eax、ebx、ecx、edx 中的任何一个。约束 "=q" 保证了这一点。(iii)同时我们可以看到 memory 位于修饰寄存器列表中。也就是说,代码将改变内存中的内容。
|
||||
|
||||
3. 如何置 1 或清 0 寄存器中的一个比特位。作为下一个诀窍,我们将会看到它。
|
||||
|
||||
```
|
||||
__asm__ __volatile__( "btsl %1,%0"
|
||||
: "=m" (ADDR)
|
||||
: "Ir" (pos)
|
||||
: "cc"
|
||||
);
|
||||
```
|
||||
|
||||
这里,ADDR 变量(一个内存变量)的 'pos' 位置上的比特被设置为 1。我们可以使用 'btrl' 来清除由 'btsl' 设置的比特位。pos 的约束 "Ir" 表明 pos 位于寄存器,并且它的值为 0-31(x86 相关约束)。也就是说,我们可以设置/清除 ADDR 变量上第 0 到 31 位的任一比特位。因为条件码会被改变,所以我们将 "cc" 添加进修饰寄存器列表。
|
||||
|
||||
4. 现在我们看看一些更为复杂而有用的函数。字符串拷贝。
|
||||
|
||||
```
|
||||
static inline char * strcpy(char * dest,const char *src)
|
||||
{
|
||||
int d0, d1, d2;
|
||||
__asm__ __volatile__( "1:\tlodsb\n\t"
|
||||
"stosb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b"
|
||||
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
|
||||
: "0" (src),"1" (dest)
|
||||
: "memory");
|
||||
return dest;
|
||||
}
|
||||
```
|
||||
|
||||
源地址存放于 esi,目标地址存放于 edi,同时开始拷贝,当我们到达 **0** 时,拷贝完成。约束 "&S"、"&D"、"&a" 表明寄存器 esi、edi 和 eax 早期修饰寄存器,也就是说,它们的内容在函数完成前会被改变。这里很明显可以知道为什么 "memory" 会放在修饰寄存器列表。
|
||||
|
||||
我们可以看到一个类似的函数,它能移动双字块数据。注意函数被声明为一个宏。
|
||||
|
||||
```
|
||||
#define mov_blk(src, dest, numwords) \
|
||||
__asm__ __volatile__ ( \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"movsl" \
|
||||
: \
|
||||
: "S" (src), "D" (dest), "c" (numwords) \
|
||||
: "%ecx", "%esi", "%edi" \
|
||||
)
|
||||
```
|
||||
|
||||
这里我们没有输出,寄存器 ecx、esi和 edi 的内容发生了改变,这是块移动的副作用。因此我们必须将它们添加进修饰寄存器列表。
|
||||
|
||||
5. 在 Linux 中,系统调用使用 GCC 内联汇编实现。让我们看看如何实现一个系统调用。所有的系统调用被写成宏(linux/unistd.h)。例如,带有三个参数的系统调用被定义为如下所示的宏。
|
||||
|
||||
```
|
||||
type name(type1 arg1,type2 arg2,type3 arg3) \
|
||||
{ \
|
||||
long __res; \
|
||||
__asm__ volatile ( "int $0x80" \
|
||||
: "=a" (__res) \
|
||||
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
|
||||
"d" ((long)(arg3))); \
|
||||
__syscall_return(type,__res); \
|
||||
}
|
||||
```
|
||||
|
||||
无论何时调用带有三个参数的系统调用,以上展示的宏就会用于执行调用。系统调用号位于 eax 中,每个参数位于 ebx、ecx、edx 中。最后 "int 0x80" 是一条用于执行系统调用的指令。返回值被存储于 eax 中。
|
||||
|
||||
每个系统调用都以类似的方式实现。Exit 是一个单一参数的系统调用,让我们看看它的代码看起来会是怎样。它如下所示。
|
||||
|
||||
```
|
||||
{
|
||||
asm("movl $1,%%eax; /* SYS_exit is 1 */
|
||||
xorl %%ebx,%%ebx; /* Argument is in ebx, it is 0 */
|
||||
int $0x80" /* Enter kernel mode */
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Exit 的系统调用号是 1,同时它的参数是 0。因此我们分配 eax 包含 1,ebx 包含 0,同时通过 `int $0x80` 执行 `exit(0)`。这就是 exit 的工作原理。
|
||||
|
||||
* * *
|
||||
|
||||
## 8. 结束语
|
||||
|
||||
这篇文档已经将 GCC 内联汇编过了一遍。一旦你理解了基本概念,你就可以按照自己的需求去使用它们了。我们看了许多例子,它们有助于理解 GCC 内联汇编的常用特性。
|
||||
|
||||
GCC 内联是一个极大的主题,这篇文章是不完整的。更多关于我们讨论过的语法细节可以在 GNU 汇编器的官方文档上获取。类似地,要获取完整的约束列表,可以参考 GCC 的官方文档。
|
||||
|
||||
当然,Linux 内核大量地使用了 GCC 内联。因此我们可以在内核源码中发现许多各种各样的例子。它们可以帮助我们很多。
|
||||
|
||||
如果你发现任何的错别字,或者本文中的信息已经过时,请告诉我们。
|
||||
|
||||
* * *
|
||||
|
||||
## 9. 参考
|
||||
|
||||
1. [Brennan’s Guide to Inline Assembly](http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html)
|
||||
2. [Using Assembly Language in Linux](http://linuxassembly.org/articles/linasm.html)
|
||||
3. [Using as, The GNU Assembler](http://www.gnu.org/manual/gas-2.9.1/html_mono/as.html)
|
||||
4. [Using and Porting the GNU Compiler Collection (GCC)](http://gcc.gnu.org/onlinedocs/gcc_toc.html)
|
||||
5. [Linux Kernel Source](http://ftp.kernel.org/)
|
||||
|
||||
* * *
|
||||
|
||||
via: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
|
||||
|
||||
作者:[Sandeep.S](mailto:busybox@sancharnet.in) 译者:[cposture](https://github.com/cposture) 校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](http://linux.cn/) 荣誉推出
|
@ -0,0 +1,161 @@
|
||||
5 个最受人喜爱的开源 Django 包
|
||||
================================================================================
|
||||
|
||||
![Yearbook cover 2015](https://opensource.com/sites/default/files/styles/image-full-size/public/u23316/osdc-open-source-yearbook-lead8.png?itok=0_5-hdFE)
|
||||
|
||||
图片来源:Opensource.com
|
||||
|
||||
_Jacob Kaplan-Moss 和 Frank Wiles 也参与了本文的写作。_
|
||||
|
||||
Django 围绕“[可重用应用][1]”的思想建立:自包含的包提供了可重复使用的特性。你可以将这些可重用应用组装起来,在加上适用于你的网站的特定代码,来搭建你自己的网站。Django 具有一个丰富多样的、由可供你使用的可重用应用组建起来的生态系统——PyPI 列出了[超过 8000个 Django 应用][2]——可你该如何知道哪些是最好的呢?
|
||||
|
||||
为了节省你的时间,我们总结了五个最受喜爱的 Django 应用。它们是:
|
||||
|
||||
- [Cookiecutter][3]: 建立 Django 网站的最佳方式。
|
||||
- [Whitenoise][4]: 最棒的静态资源服务器。
|
||||
- [Django Rest Framework][5]: 使用 Django 开发 REST API 的最佳方式。
|
||||
- [Wagtail][6]: 基于 Django 的最佳内容管理系统(CMS)。
|
||||
- [django-allauth][7]: 提供社交账户登录的最佳应用(如 Twitter, Facebook, GitHub 等)。
|
||||
|
||||
我们同样推荐你看看 [Django Packages][8],这是一个可重用 Django 应用的目录。Django Packages 将 Django 应用组织成“表格”,你可以在功能相似的不同应用之间进行比较并做出选择。你可以查看每个包中提供的特性和使用统计情况。(比如:这是[ REST 工具的表格][9],也许可以帮助你理解我们为何推荐 Django REST Framework。
|
||||
|
||||
### 为什么你应该相信我们?
|
||||
|
||||
我们使用 Django 的时间几乎比任何人都长。在 Django 发布之前,我们当中的两个人(Frank 和 Jacob)就在 [Lawrence Journal-World][10] (Django 的发源地)工作(事实上,是他们两人推动了 Django 开源发布的进程)。我们在过去的八年当中运行着一个咨询公司,来建议公司怎样最好地应用 Django。
|
||||
|
||||
所以,我们见证了 Django 项目和社群的完整历史,我们见证了那些流行的软件包的兴起和没落。在我们三个之中,我们个人可能试用了 8000 个应用中至少一半以上,或者我们知道谁试用过这些。我们对如何使应用变得坚实可靠有着深刻的理解,并且我们对给予这些应用持久力量的来源也有着深入的了解。
|
||||
|
||||
### 建立 Django 网站的最佳方式:[Cookiecutter][3]
|
||||
|
||||
建立一个新项目或应用总是有些痛苦。你可以用 Django 内建的 `startproject`。不过,如果你像我们一样,对如何做事比较挑剔。Cookiecutter 为你提供了一个快捷简单的方式来构建项目或易于重用的应用模板,从而解决了这个问题。一个简单的例子:键入 `pip install cookiecutter`,然后在命令行中运行以下命令:
|
||||
|
||||
```bash
|
||||
$ cookiecutter https://github.com/marcofucci/cookiecutter-simple-django
|
||||
```
|
||||
|
||||
接下来你需要回答几个简单的问题,比如你的项目名称、目录(repo)、作者名字、E-Mail 和其他几个关于配置的小问题。这些能够帮你补充项目相关的细节。我们使用最最原始的 “_foo_” 作为我们的目录名称。所以 cokkiecutter 在子目录 “_foo_” 下建立了一个简单的 Django 项目。
|
||||
|
||||
如果你在 “_foo_” 项目中闲逛,你会看见你刚刚选择的其它设置已通过模板,连同所需的子目录一同嵌入到文件当中。这个“模板”在我们刚刚在执行 `cookiecutter` 命令时输入的唯一一个参数 Github 仓库 URL 中定义。这个样例工程使用了一个 Github 远程仓库作为模板;不过你也可以使用本地的模板,这在建立非重用项目时非常有用。
|
||||
|
||||
我们认为 cookiecutter 是一个极棒的 Django 包,但是,事实上其实它在面对纯 Python 甚至非 Python 相关需求时也极为有用。你能够将所有文件以一种可重复的方式精确地摆放在任何位置上,使得 cookiecutter 成为了一个简化(DRY)工作流程的极佳工具。
|
||||
|
||||
### 最棒的静态资源服务器:[Whitenoise][4]
|
||||
|
||||
多年来,托管网站的静态资源——图片、Javascript、CSS——都是一件很痛苦的事情。Django 内建的 [django.views.static.serve][11] 视图,就像 Django 文章所述的那样,“在生产环境中不可靠,所以只应为开发环境的提供辅助功能。”但使用一个“真正的” Web 服务器,如 NGINX 或者借助 CDN 来托管媒体资源,配置起来会比较困难。
|
||||
|
||||
Whitenoice 很简洁地解决了这个问题。它可以像在开发环境那样轻易地在生产环境中设置静态服务器,并且针对生产环境进行了加固和优化。它的设置方法极为简单:
|
||||
|
||||
1. 确保你在使用 Django 的 [contrib.staticfiles][12] 应用,并确认你在配置文件中正确设置了 `STATIC_ROOT` 变量。
|
||||
|
||||
2. 在 `wsgi.py` 文件中启用 Whitenoise:
|
||||
|
||||
```python
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
from whitenoise.django import DjangoWhiteNoise
|
||||
|
||||
application = get_wsgi_application()
|
||||
application = DjangoWhiteNoise(application)
|
||||
```
|
||||
|
||||
配置它真的就这么简单!对于大型应用,你可能想要使用一个专用的媒体服务器和/或一个 CDN,但对于大多数小型或中型 Django 网站,Whitenoise 已经足够强大。
|
||||
|
||||
如需查看更多关于 Whitenoise 的信息,[请查看文档][13]。
|
||||
|
||||
### 开发 REST API 的最佳工具:[Django REST Framework][5]
|
||||
|
||||
REST API 正在迅速成为现代 Web 应用的标准功能。 API 就是简单的使用 JSON 对话而不是 HTML,当然你可以只用 Django 做到这些。你可以制作自己的视图,设置合适的 `Content-Type`,然后返回 JSON 而不是渲染后的 HTML 响应。这是在像 [Django Rest Framework][14](下称 DRF)这样的 API 框架发布之前,大多数人所做的。
|
||||
|
||||
如果你对 Django 的视图类很熟悉,你会觉得使用 DRF 构建 REST API 与使用它们很相似,不过 DRF 只针对特定 API 使用场景而设计。一般的 API 设置只需要一点代码,所以我们没有提供一份让你兴奋的示例代码,而是强调了一些可以让你生活的更舒适的 DRF 特性:
|
||||
|
||||
* 可自动预览的 API 可以使你的开发和人工测试轻而易举。你可以查看 DRF 的[示例代码][15]。你可以查看 API 响应,并且不需要你做任何事就可以支持 POST/PUT/DELETE 类型的操作。
|
||||
* 便于集成各种认证方式,如 OAuth, Basic Auth, 或API Tokens。
|
||||
* 内建请求速率限制。
|
||||
* 当与 [django-rest-swagger][16] 组合使用时,API 文档几乎可以自动生成。
|
||||
* 广泛的第三方库生态。
|
||||
|
||||
当然,你可以不依赖 DRF 来构建 API,但我们无法想象你不去使用 DRF 的原因。就算你不使用 DRF 的全部特性,使用一个成熟的视图库来构建你自己的 API 也会使你的 API 更加一致、完全,更能提高你的开发速度。如果你还没有开始使用 DRF, 你应该找点时间去体验一下。
|
||||
|
||||
### 基于 Django 的最佳 CMS:[Wagtail][6]
|
||||
|
||||
Wagtail 是当下 Django CMS(内容管理系统)世界中最受人青睐的应用,并且它的热门有足够的理由。就像大多数的 CMS 一样,它具有极佳的灵活性,可以通过简单的 Django 模型来定义不同类型的页面及其内容。使用它,你可以从零开始在几个小时而不是几天之内来和建造一个基本可以运行的内容管理系统。举一个小例子,为你公司的员工定义一个员工页面类型可以像下面一样简单:
|
||||
|
||||
```python
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailcore.fields import RichTextField
|
||||
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel
|
||||
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
|
||||
|
||||
class StaffPage(Page):
|
||||
name = models.CharField(max_length=100)
|
||||
hire_date = models.DateField()
|
||||
bio = models.RichTextField()
|
||||
email = models.EmailField()
|
||||
headshot = models.ForeignKey('wagtailimages.Image', null=True, blank=True)
|
||||
content_panels = Page.content_panels + [
|
||||
FieldPanel('name'),
|
||||
FieldPanel('hire_date'),
|
||||
FieldPanel('email'),
|
||||
FieldPanel('bio',classname="full"),
|
||||
ImageChoosePanel('headshot'),
|
||||
]
|
||||
```
|
||||
|
||||
然而,Wagtail 真正出彩的地方在于它的灵活性及其易于使用的现代化管理页面。你可以控制不同类型的页面在哪网站的哪些区域可以访问,为页面添加复杂的附加逻辑,还天生就支持标准的适应/审批工作流。在大多数 CMS 系统中,你会在开发时在某些点上遇到困难。而使用 Wagtail 时,我们经过不懈努力找到了一个突破口,使得让我们轻易地开发出一套简洁稳定的系统,使得程序完全依照我们的想法运行。如果你对此感兴趣,我们写了一篇[深入理解 Wagtail][17。
|
||||
|
||||
### 提供社交账户登录的最佳工具:[django-allauth][7]
|
||||
|
||||
django-allauth 是一个能够解决你的注册和认证需求的、可重用的 Django 应用。无论你需要构建本地注册系统还是社交账户注册系统,django-allauth 都能够帮你做到。
|
||||
|
||||
这个应用支持多种认证体系,比如用户名或电子邮件。一旦用户注册成功,它还可以提供从无需认证到电子邮件认证的多种账户验证的策略。同时,它也支持多种社交账户和电子邮件账户。它还支持插拔式注册表单,可让用户在注册时回答一些附加问题。
|
||||
|
||||
django-allauth 支持多于 20 种认证提供者,包括 Facebook、Github、Google 和 Twitter。如果你发现了一个它不支持的社交网站,很有可能通过第三方插件提供该网站的接入支持。这个项目还支持自定义后端,可以支持自定义的认证方式,对每个有定制认证需求的人来说这都很棒。
|
||||
|
||||
django-allauth 易于配置,且有[完善的文档][18]。该项目通过了很多测试,所以你可以相信它的所有部件都会正常运作。
|
||||
|
||||
你有最喜爱的 Django 包吗?请在评论中告诉我们。
|
||||
|
||||
### 关于作者
|
||||
|
||||
![Photo](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/main-one-i-use-everywhere.png?itok=66GC-D1q)
|
||||
|
||||
*Jeff Triplett 劳伦斯,堪萨斯州 <http://www.jefftriplett.com/>*
|
||||
|
||||
我在 2007 年搬到了堪萨斯州的劳伦斯,在 Django 的发源地—— Lawrence Journal-World 工作。我现在在劳伦斯市的 [Revolution Systems (Revsys)][19] 工作,做一位开发者兼顾问。
|
||||
|
||||
我是[北美 Django 运动基金会(DEFNA)][20]的联合创始人,2015 和 2016 年 [DjangoCon US][21] 的会议主席,而且我在 Django 的发源地劳伦斯参与组织了 [Django Birthday][22] 来庆祝 Django 的 10 岁生日。
|
||||
|
||||
我是当地越野跑小组的成员,我喜欢篮球,我还喜欢梦见自己随着一道气流游遍美国。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/15/12/5-favorite-open-source-django-packages
|
||||
|
||||
作者:[Jeff Triplett][a]
|
||||
译者:[StdioA](https://github.com/StdioA)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/jefftriplett
|
||||
[1]:https://docs.djangoproject.com/en/1.8/intro/reusable-apps/
|
||||
[2]:https://pypi.python.org/pypi?:action=browse&c=523
|
||||
[3]:https://github.com/audreyr/cookiecutter
|
||||
[4]:http://whitenoise.evans.io/en/latest/base.html
|
||||
[5]:http://www.django-rest-framework.org/
|
||||
[6]:https://wagtail.io/
|
||||
[7]:http://www.intenct.nl/projects/django-allauth/
|
||||
[8]:https://www.djangopackages.com/
|
||||
[9]:https://www.djangopackages.com/grids/g/rest/
|
||||
[10]:http://www2.ljworld.com/news/2015/jul/09/happy-birthday-django/
|
||||
[11]:https://docs.djangoproject.com/en/1.8/ref/views/#django.views.static.serve
|
||||
[12]:https://docs.djangoproject.com/en/1.8/ref/contrib/staticfiles/
|
||||
[13]:http://whitenoise.evans.io/en/latest/index.html
|
||||
[14]:http://www.django-rest-framework.org/
|
||||
[15]:http://restframework.herokuapp.com/
|
||||
[16]:http://django-rest-swagger.readthedocs.org/en/latest/index.html
|
||||
[17]:https://opensource.com/business/15/5/wagtail-cms
|
||||
[18]:http://django-allauth.readthedocs.org/en/latest/
|
||||
[19]:http://www.revsys.com/
|
||||
[20]:http://defna.org/
|
||||
[21]:https://2015.djangocon.us/
|
||||
[22]:https://djangobirthday.com/
|
150
published/201608/20160309 Let’s Build A Web Server. Part 1.md
Normal file
150
published/201608/20160309 Let’s Build A Web Server. Part 1.md
Normal file
@ -0,0 +1,150 @@
|
||||
搭个 Web 服务器(一)
|
||||
=====================================
|
||||
|
||||
一天,有一个正在散步的妇人恰好路过一个建筑工地,看到三个正在工作的工人。她问第一个人:“你在做什么?”第一个人没好气地喊道:“你没看到我在砌砖吗?”妇人对这个答案不满意,于是问第二个人:“你在做什么?”第二个人回答说:“我在建一堵砖墙。”说完,他转向第一个人,跟他说:“嗨,你把墙砌过头了。去把刚刚那块砖弄下来!”然而,妇人对这个答案依然不满意,于是又问了第三个人相同的问题。第三个人仰头看着天,对她说:“我在建造世界上最大的教堂。”当他回答时,第一个人和第二个人在为刚刚砌错的砖而争吵。他转向那两个人,说:“不用管那块砖了。这堵墙在室内,它会被水泥填平,没人会看见它的。去砌下一层吧。”
|
||||
|
||||
这个故事告诉我们:如果你能够理解整个系统的构造,了解系统的各个部件如何相互结合(如砖、墙还有整个教堂),你就能够更快地定位及修复问题(那块砌错的砖)。
|
||||
|
||||
如果你想从头开始创造一个 Web 服务器,那么你需要做些什么呢?
|
||||
|
||||
我相信,如果你想成为一个更好的开发者,你**必须**对日常使用的软件系统的内部结构有更深的理解,包括编程语言、编译器与解释器、数据库及操作系统、Web 服务器及 Web 框架。而且,为了更好更深入地理解这些系统,你**必须**从头开始,用一砖一瓦来重新构建这个系统。
|
||||
|
||||
荀子曾经用这几句话来表达这种思想:
|
||||
|
||||
>“不闻不若闻之。(I hear and I forget.)”
|
||||
|
||||
![](https://ruslanspivak.com/lsbasi-part4/LSBAWS_confucius_hear.png)
|
||||
|
||||
>“闻之不若见之。(I see and I remember.)”
|
||||
|
||||
![](https://ruslanspivak.com/lsbasi-part4/LSBAWS_confucius_see.png)
|
||||
|
||||
>“知之不若行之。(I do and I understand.)”
|
||||
|
||||
![](https://ruslanspivak.com/lsbasi-part4/LSBAWS_confucius_do.png)
|
||||
|
||||
我希望你现在能够意识到,重新建造一个软件系统来了解它的工作方式是一个好主意。
|
||||
|
||||
在这个由三篇文章组成的系列中,我将会教你构建你自己的 Web 服务器。我们开始吧~
|
||||
|
||||
先说首要问题:Web 服务器是什么?
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/LSBAWS_HTTP_request_response.png)
|
||||
|
||||
简而言之,它是一个运行在一个物理服务器上的网络服务器(啊呀,服务器套服务器),等待客户端向其发送请求。当它接收请求后,会生成一个响应,并回送至客户端。客户端和服务端之间通过 HTTP 协议来实现相互交流。客户端可以是你的浏览器,也可以是使用 HTTP 协议的其它任何软件。
|
||||
|
||||
最简单的 Web 服务器实现应该是什么样的呢?这里我给出我的实现。这个例子由 Python 写成,即使你没听说过 Python(它是一门超级容易上手的语言,快去试试看!),你也应该能够从代码及注释中理解其中的理念:
|
||||
|
||||
```
|
||||
import socket
|
||||
|
||||
HOST, PORT = '', 8888
|
||||
|
||||
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
listen_socket.bind((HOST, PORT))
|
||||
listen_socket.listen(1)
|
||||
print 'Serving HTTP on port %s ...' % PORT
|
||||
while True:
|
||||
client_connection, client_address = listen_socket.accept()
|
||||
request = client_connection.recv(1024)
|
||||
print request
|
||||
|
||||
http_response = """\
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
Hello, World!
|
||||
"""
|
||||
client_connection.sendall(http_response)
|
||||
client_connection.close()
|
||||
```
|
||||
|
||||
将以上代码保存为 webserver1.py,或者直接从 [GitHub][1] 上下载这个文件。然后,在命令行中运行这个程序。像这样:
|
||||
|
||||
```
|
||||
$ python webserver1.py
|
||||
Serving HTTP on port 8888 …
|
||||
```
|
||||
|
||||
现在,在你的网页浏览器的地址栏中输入 URL:http://localhost:8888/hello ,敲一下回车,然后来见证奇迹。你应该看到“Hello, World!”显示在你的浏览器中,就像下图那样:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/browser_hello_world.png)
|
||||
|
||||
说真的,快去试一试。你做实验的时候,我会等着你的。
|
||||
|
||||
完成了?不错!现在我们来讨论一下它实际上是怎么工作的。
|
||||
|
||||
首先我们从你刚刚输入的 Web 地址开始。它叫 [URL][2],这是它的基本结构:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/LSBAWS_URL_Web_address.png)
|
||||
|
||||
URL 是一个 Web 服务器的地址,浏览器用这个地址来寻找并连接 Web 服务器,并将上面的内容返回给你。在你的浏览器能够发送 HTTP 请求之前,它需要与 Web 服务器建立一个 TCP 连接。然后会在 TCP 连接中发送 HTTP 请求,并等待服务器返回 HTTP 响应。当你的浏览器收到响应后,就会显示其内容,在上面的例子中,它显示了“Hello, World!”。
|
||||
|
||||
我们来进一步探索在发送 HTTP 请求之前,客户端与服务器建立 TCP 连接的过程。为了建立链接,它们使用了所谓“套接字(socket)”。我们现在不直接使用浏览器发送请求,而在命令行中使用 `telnet` 来人工模拟这个过程。
|
||||
|
||||
在你运行 Web 服务器的电脑上,在命令行中建立一个 telnet 会话,指定一个本地域名,使用端口 8888,然后按下回车:
|
||||
|
||||
```
|
||||
$ telnet localhost 8888
|
||||
Trying 127.0.0.1 …
|
||||
Connected to localhost.
|
||||
```
|
||||
|
||||
这个时候,你已经与运行在你本地主机的服务器建立了一个 TCP 连接。在下图中,你可以看到一个服务器从头开始,到能够建立 TCP 连接的基本过程。
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/LSBAWS_socket.png)
|
||||
|
||||
在同一个 telnet 会话中,输入 `GET /hello HTTP/1.1`,然后输入回车:
|
||||
|
||||
```
|
||||
$ telnet localhost 8888
|
||||
Trying 127.0.0.1 …
|
||||
Connected to localhost.
|
||||
GET /hello HTTP/1.1
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Hello, World!
|
||||
```
|
||||
|
||||
你刚刚手动模拟了你的浏览器(的工作)!你发送了 HTTP 请求,并且收到了一个 HTTP 应答。下面是一个 HTTP 请求的基本结构:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/LSBAWS_HTTP_request_anatomy.png)
|
||||
|
||||
HTTP 请求的第一行由三部分组成:HTTP 方法(`GET`,因为我们想让我们的服务器返回一些内容),以及标明所需页面的路径 `/hello`,还有协议版本。
|
||||
|
||||
为了简单一些,我们刚刚构建的 Web 服务器完全忽略了上面的请求内容。你也可以试着输入一些无用内容而不是“GET /hello HTTP/1.1”,但你仍然会收到一个“Hello, World!”响应。
|
||||
|
||||
一旦你输入了请求行并敲了回车,客户端就会将请求发送至服务器;服务器读取请求行,就会返回相应的 HTTP 响应。
|
||||
|
||||
下面是服务器返回客户端(在上面的例子里是 telnet)的响应内容:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part1/LSBAWS_HTTP_response_anatomy.png)
|
||||
|
||||
我们来解析它。这个响应由三部分组成:一个状态行 `HTTP/1.1 200 OK`,后面跟着一个空行,再下面是响应正文。
|
||||
|
||||
HTTP 响应的状态行 HTTP/1.1 200 OK 包含了 HTTP 版本号,HTTP 状态码以及 HTTP 状态短语“OK”。当浏览器收到响应后,它会将响应正文显示出来,这也就是为什么你会在浏览器中看到“Hello, World!”。
|
||||
|
||||
以上就是 Web 服务器的基本工作模型。总结一下:Web 服务器创建一个处于监听状态的套接字,循环接收新的连接。客户端建立 TCP 连接成功后,会向服务器发送 HTTP 请求,然后服务器会以一个 HTTP 响应做应答,客户端会将 HTTP 的响应内容显示给用户。为了建立 TCP 连接,客户端和服务端均会使用套接字。
|
||||
|
||||
现在,你应该了解了 Web 服务器的基本工作方式,你可以使用浏览器或其它 HTTP 客户端进行试验。如果你尝试过、观察过,你应该也能够使用 telnet,人工编写 HTTP 请求,成为一个“人形” HTTP 客户端。
|
||||
|
||||
现在留一个小问题:“你要如何在不对程序做任何改动的情况下,在你刚刚搭建起来的 Web 服务器上适配 Django, Flask 或 Pyramid 应用呢?”
|
||||
|
||||
我会在本系列的第二部分中来详细讲解。敬请期待。
|
||||
|
||||
顺便,我在撰写一本名为《搭个 Web 服务器:从头开始》的书。这本书讲解了如何从头开始编写一个基本的 Web 服务器,里面包含本文中没有的更多细节。订阅邮件列表,你就可以获取到这本书的最新进展,以及发布日期。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://ruslanspivak.com/lsbaws-part1/
|
||||
|
||||
作者:[Ruslan][a]
|
||||
译者:[StdioA](https://github.com/StdioA)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://linkedin.com/in/ruslanspivak/
|
||||
[1]: https://github.com/rspivak/lsbaws/blob/master/part1/webserver1.py
|
||||
[2]: http://en.wikipedia.org/wiki/Uniform_resource_locator
|
||||
|
@ -0,0 +1,49 @@
|
||||
伴随 Linux 成长的职业生涯
|
||||
==================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/OPENHERE_blue.png?itok=3eqp-7gT)
|
||||
|
||||
我与 Linux 的故事开始于 1998 年,一直延续到今天。 当时我在 Gap 公司工作,管理着成千台运行着 [OS/2][1] 系统的台式机 ( 在随后的几年里变成了 [Warp 3.0][2])。 作为一个 OS/2 的粉丝,那时我非常喜欢那个时候。 随着这些台式机的嗡鸣,我们使用 Gap 开发的工具轻而易举地就能支撑起对成千的用户的服务支持。 然而,一切都将改变了。
|
||||
|
||||
在 1998 年的 11 月, 我收到邀请加入一个新成立的公司,这家公司将专注于企业级 Linux 上。 这就是后来非常出名的 [Linuxcare][2]。
|
||||
|
||||
### 我在 Linuxcare 的时光
|
||||
|
||||
我曾经接触过一些 Linux , 但我从未想过要把它提供给企业客户。仅仅几个月后 ( 从这里开始成为了空间和时间上的转折点 ), 我就在管理一整条线的业务,让企业获得他们的软件,硬件,甚至是证书认证等各种在当时非常盛行的 Linux 服务。
|
||||
|
||||
我支持的客户包括像 IBM ,Dell ,HP 这样的厂商以确保他们的硬件能够成功的运行 Linux 。 今天你们应该都听过许多关于在硬件上预装 Linux 的事, 但当时 Dell 邀请我去讨论为即将到来的贸易展上将 Linux 运行在认证的笔记本电脑上。 这是多么激动人心的时刻 !同时我们在之后几年内也支持了 IBM 和 HP 等多项认证工作。
|
||||
|
||||
Linux 变化得非常快,并且它总是这样。 它也获得了更多的关键设备的支持,比如声音,网络和图形。在这段时间, 我把个人使用的系统从基于 RPM 的系统换成了 [Debian][3] 。
|
||||
|
||||
### 使用 Linux 的这些年
|
||||
|
||||
几年前我在一些做 Linux 硬件设备、Linux 定制软件以及 Linux 数据中心的公司工作。而在二十世纪中期的时候,那时我正在忙为那些在雷蒙德附近(微软公司所在地)的大一些的软件公司做咨询工作,为他们对比 Linux 解决方案及其自己的解决方案做分析和验证。 我个人使用的系统一直没有改变,我仍会在尽可能的情况下运行 Debian 测试系统。
|
||||
|
||||
我真的非常欣赏发行版的灵活性和永久更新状态。 Debian 是我所使用过的最有趣且拥有良好支持的发行版,并且它拥有最好的社区,而我是社区的一份子。
|
||||
|
||||
当我回首我使用 Linux 的这几年,我仍记得大约在二十世纪前期和中期的时候在圣何塞,旧金山,波士顿和纽约召开的那些 Linux Expo 大会。在 Linuxcare 时我们总是会摆一些有趣而且时髦的展位,在那边逛的时候总会碰到一些老朋友。这一切工作都是需要付出代价的,所有的这一切都是在努力地强调使用 Linux 的乐趣。
|
||||
|
||||
随着虚拟化和云的崛起也让 Linux 变得更加有趣。 当我在 Linuxcare 的时候, 我们常和斯坦福大学附近的帕洛阿尔托的一个约 30 人左右的小公司在一块。我们会开车到他们的办公处,然后帮他们准备和我们一起参加展览的东西。 谁会想得到这个小小的初创公司会成就后来的 VMware ?
|
||||
|
||||
我还有许多的故事,能认识这些人并和他们一起工作我感到很幸运。 Linux 在各方面都不断发展且变得尤为重要。 并且甚至随着它重要性的提升,它使用起来仍然非常有趣。 我认为它的开放性和可定制能力给它带来了大量的新用户,这也是让我感到非常震惊的一点。
|
||||
|
||||
### 现在
|
||||
|
||||
在过去的五年里我的工作重心逐渐离开 Linux。 我所管理的大规模基础设施项目中包含着许多不同的操作系统 ( 包括非开源的和开源的 ), 但我的心一直以来都是和 Linux 在一起的。
|
||||
|
||||
在使用 Linux 过程中的乐趣和不断进步是在过去的 18 年里一直驱动我的动力。我从 Linux 2.0 内核开始看着它变成现在的这样。 Linux 是一个卓越的、生机勃勃的且非常酷的东西。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/life/16/3/my-linux-story-michael-perry
|
||||
|
||||
作者:[Michael Perry][a]
|
||||
译者:[chenxinlong](https://github.com/chenxinlong)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
[a]: https://opensource.com/users/mpmilestogo
|
||||
[1]: https://en.wikipedia.org/wiki/OS/2
|
||||
[2]: https://archive.org/details/IBMOS2Warp3Collection
|
||||
[3]: https://en.wikipedia.org/wiki/Linuxcare
|
||||
[4]: https://www.debian.org/
|
||||
[5]:
|
430
published/201608/20160406 Let’s Build A Web Server. Part 2.md
Normal file
430
published/201608/20160406 Let’s Build A Web Server. Part 2.md
Normal file
@ -0,0 +1,430 @@
|
||||
搭个 Web 服务器(二)
|
||||
===================================
|
||||
|
||||
在[第一部分][1]中,我提出了一个问题:“如何在你刚刚搭建起来的 Web 服务器上适配 Django, Flask 或 Pyramid 应用,而不用单独对 Web 服务器做做出改动以适应各种不同的 Web 框架呢?”我们可以从这一篇中找到答案。
|
||||
|
||||
曾几何时,你所选择的 Python Web 框架会限制你所可选择的 Web 服务器,反之亦然。如果某个框架及服务器设计用来协同工作的,那么一切正常:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_before_wsgi.png)
|
||||
|
||||
但你可能正面对着(或者曾经面对过)尝试将一对无法适配的框架和服务器搭配在一起的问题:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_after_wsgi.png)
|
||||
|
||||
基本上,你需要选择那些能够一起工作的框架和服务器,而不能选择你想用的那些。
|
||||
|
||||
所以,你该如何确保在不对 Web 服务器或框架的代码做任何更改的情况下,让你的 Web 服务器和多个不同的 Web 框架一同工作呢?这个问题的答案,就是 Python Web 服务器网关接口(Web Server Gateway Interface )(缩写为 [WSGI][2],念做“wizgy”)。
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_wsgi_idea.png)
|
||||
|
||||
WSGI 允许开发者互不干扰地选择 Web 框架及 Web 服务器的类型。现在,你可以真正将 Web 服务器及框架任意搭配,然后选出你最中意的那对组合。比如,你可以使用 [Django][3],[Flask][4] 或者 [Pyramid][5],与 [Gunicorn][6],[Nginx/uWSGI][7] 或 [Waitress][8] 进行结合。感谢 WSGI 同时对服务器与框架的支持,我们可以真正随意选择它们的搭配了。
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_wsgi_interop.png)
|
||||
|
||||
所以,WSGI 就是我在第一部分中提出,又在本文开头重复了一遍的那个问题的答案。你的 Web 服务器必须实现 WSGI 接口的服务器部分,而现代的 Python Web 框架均已实现了 WSGI 接口的框架部分,这使得你可以直接在 Web 服务器中使用任意框架,而不需要更改任何服务器代码,以对特定的 Web 框架实现兼容。
|
||||
|
||||
现在,你已经知道 Web 服务器及 Web 框架对 WSGI 的支持使得你可以选择最合适的一对来使用,而且它也有利于服务器和框架的开发者,这样他们只需专注于其擅长的部分来进行开发,而不需要触及另一部分的代码。其它语言也拥有类似的接口,比如:Java 拥有 Servlet API,而 Ruby 拥有 Rack。
|
||||
|
||||
这些理论都不错,但是我打赌你在说:“Show me the code!” 那好,我们来看看下面这个很小的 WSGI 服务器实现:
|
||||
|
||||
```
|
||||
### 使用 Python 2.7.9,在 Linux 及 Mac OS X 下测试通过
|
||||
import socket
|
||||
import StringIO
|
||||
import sys
|
||||
|
||||
|
||||
class WSGIServer(object):
|
||||
|
||||
address_family = socket.AF_INET
|
||||
socket_type = socket.SOCK_STREAM
|
||||
request_queue_size = 1
|
||||
|
||||
def __init__(self, server_address):
|
||||
### 创建一个监听的套接字
|
||||
self.listen_socket = listen_socket = socket.socket(
|
||||
self.address_family,
|
||||
self.socket_type
|
||||
)
|
||||
### 允许复用同一地址
|
||||
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
### 绑定地址
|
||||
listen_socket.bind(server_address)
|
||||
### 激活套接字
|
||||
listen_socket.listen(self.request_queue_size)
|
||||
### 获取主机的名称及端口
|
||||
host, port = self.listen_socket.getsockname()[:2]
|
||||
self.server_name = socket.getfqdn(host)
|
||||
self.server_port = port
|
||||
### 返回由 Web 框架/应用设定的响应头部字段
|
||||
self.headers_set = []
|
||||
|
||||
def set_app(self, application):
|
||||
self.application = application
|
||||
|
||||
def serve_forever(self):
|
||||
listen_socket = self.listen_socket
|
||||
while True:
|
||||
### 获取新的客户端连接
|
||||
self.client_connection, client_address = listen_socket.accept()
|
||||
### 处理一条请求后关闭连接,然后循环等待另一个连接建立
|
||||
self.handle_one_request()
|
||||
|
||||
def handle_one_request(self):
|
||||
self.request_data = request_data = self.client_connection.recv(1024)
|
||||
### 以 'curl -v' 的风格输出格式化请求数据
|
||||
print(''.join(
|
||||
'< {line}\n'.format(line=line)
|
||||
for line in request_data.splitlines()
|
||||
))
|
||||
|
||||
self.parse_request(request_data)
|
||||
|
||||
### 根据请求数据构建环境变量字典
|
||||
env = self.get_environ()
|
||||
|
||||
### 此时需要调用 Web 应用来获取结果,
|
||||
### 取回的结果将成为 HTTP 响应体
|
||||
result = self.application(env, self.start_response)
|
||||
|
||||
### 构造一个响应,回送至客户端
|
||||
self.finish_response(result)
|
||||
|
||||
def parse_request(self, text):
|
||||
request_line = text.splitlines()[0]
|
||||
request_line = request_line.rstrip('\r\n')
|
||||
### 将请求行分成几个部分
|
||||
(self.request_method, # GET
|
||||
self.path, # /hello
|
||||
self.request_version # HTTP/1.1
|
||||
) = request_line.split()
|
||||
|
||||
def get_environ(self):
|
||||
env = {}
|
||||
### 以下代码段没有遵循 PEP8 规则,但这样排版,是为了通过强调
|
||||
### 所需变量及它们的值,来达到其展示目的。
|
||||
###
|
||||
### WSGI 必需变量
|
||||
env['wsgi.version'] = (1, 0)
|
||||
env['wsgi.url_scheme'] = 'http'
|
||||
env['wsgi.input'] = StringIO.StringIO(self.request_data)
|
||||
env['wsgi.errors'] = sys.stderr
|
||||
env['wsgi.multithread'] = False
|
||||
env['wsgi.multiprocess'] = False
|
||||
env['wsgi.run_once'] = False
|
||||
### CGI 必需变量
|
||||
env['REQUEST_METHOD'] = self.request_method # GET
|
||||
env['PATH_INFO'] = self.path # /hello
|
||||
env['SERVER_NAME'] = self.server_name # localhost
|
||||
env['SERVER_PORT'] = str(self.server_port) # 8888
|
||||
return env
|
||||
|
||||
def start_response(self, status, response_headers, exc_info=None):
|
||||
### 添加必要的服务器头部字段
|
||||
server_headers = [
|
||||
('Date', 'Tue, 31 Mar 2015 12:54:48 GMT'),
|
||||
('Server', 'WSGIServer 0.2'),
|
||||
]
|
||||
self.headers_set = [status, response_headers + server_headers]
|
||||
### 为了遵循 WSGI 协议,start_response 函数必须返回一个 'write'
|
||||
### 可调用对象(返回值.write 可以作为函数调用)。为了简便,我们
|
||||
### 在这里无视这个细节。
|
||||
### return self.finish_response
|
||||
|
||||
def finish_response(self, result):
|
||||
try:
|
||||
status, response_headers = self.headers_set
|
||||
response = 'HTTP/1.1 {status}\r\n'.format(status=status)
|
||||
for header in response_headers:
|
||||
response += '{0}: {1}\r\n'.format(*header)
|
||||
response += '\r\n'
|
||||
for data in result:
|
||||
response += data
|
||||
### 以 'curl -v' 的风格输出格式化请求数据
|
||||
print(''.join(
|
||||
'> {line}\n'.format(line=line)
|
||||
for line in response.splitlines()
|
||||
))
|
||||
self.client_connection.sendall(response)
|
||||
finally:
|
||||
self.client_connection.close()
|
||||
|
||||
SERVER_ADDRESS = (HOST, PORT) = '', 8888
|
||||
|
||||
def make_server(server_address, application):
|
||||
server = WSGIServer(server_address)
|
||||
server.set_app(application)
|
||||
return server
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit('Provide a WSGI application object as module:callable')
|
||||
app_path = sys.argv[1]
|
||||
module, application = app_path.split(':')
|
||||
module = __import__(module)
|
||||
application = getattr(module, application)
|
||||
httpd = make_server(SERVER_ADDRESS, application)
|
||||
print('WSGIServer: Serving HTTP on port {port} ...\n'.format(port=PORT))
|
||||
httpd.serve_forever()
|
||||
```
|
||||
|
||||
当然,这段代码要比第一部分的服务器代码长不少,但它仍然很短(只有不到 150 行),你可以轻松理解它,而不需要深究细节。上面的服务器代码还可以做更多——它可以用来运行一些你喜欢的框架写出的 Web 应用,可以是 Pyramid,Flask,Django 或其它 Python WSGI 框架。
|
||||
|
||||
不相信吗?自己来试试看吧。把以上的代码保存为 `webserver2.py`,或直接从 [Github][9] 上下载它。如果你打算不加任何参数而直接运行它,它会抱怨一句,然后退出。
|
||||
|
||||
```
|
||||
$ python webserver2.py
|
||||
Provide a WSGI application object as module:callable
|
||||
```
|
||||
|
||||
它想做的其实是为你的 Web 应用服务,而这才是重头戏。为了运行这个服务器,你唯一需要的就是安装好 Python。不过,如果你希望运行 Pyramid,Flask 或 Django 应用,你还需要先安装那些框架。那我们把这三个都装上吧。我推荐的安装方式是通过 `virtualenv` 安装。按照以下几步来做,你就可以创建并激活一个虚拟环境,并在其中安装以上三个 Web 框架。
|
||||
|
||||
```
|
||||
$ [sudo] pip install virtualenv
|
||||
$ mkdir ~/envs
|
||||
$ virtualenv ~/envs/lsbaws/
|
||||
$ cd ~/envs/lsbaws/
|
||||
$ ls
|
||||
bin include lib
|
||||
$ source bin/activate
|
||||
(lsbaws) $ pip install pyramid
|
||||
(lsbaws) $ pip install flask
|
||||
(lsbaws) $ pip install django
|
||||
```
|
||||
|
||||
现在,你需要创建一个 Web 应用。我们先从 Pyramid 开始吧。把以下代码保存为 `pyramidapp.py`,并与刚刚的 `webserver2.py` 放置在同一目录,或直接从 [Github][10] 下载该文件:
|
||||
|
||||
```
|
||||
from pyramid.config import Configurator
|
||||
from pyramid.response import Response
|
||||
|
||||
|
||||
def hello_world(request):
|
||||
return Response(
|
||||
'Hello world from Pyramid!\n',
|
||||
content_type='text/plain',
|
||||
)
|
||||
|
||||
config = Configurator()
|
||||
config.add_route('hello', '/hello')
|
||||
config.add_view(hello_world, route_name='hello')
|
||||
app = config.make_wsgi_app()
|
||||
```
|
||||
|
||||
现在,你可以用你自己的 Web 服务器来运行你的 Pyramid 应用了:
|
||||
|
||||
```
|
||||
(lsbaws) $ python webserver2.py pyramidapp:app
|
||||
WSGIServer: Serving HTTP on port 8888 ...
|
||||
```
|
||||
|
||||
你刚刚让你的服务器去加载 Python 模块 `pyramidapp` 中的可执行对象 `app`。现在你的服务器可以接收请求,并将它们转发到你的 Pyramid 应用中了。在浏览器中输入 http://localhost:8888/hello ,敲一下回车,然后看看结果:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_browser_pyramid.png)
|
||||
|
||||
你也可以使用命令行工具 `curl` 来测试服务器:
|
||||
|
||||
```
|
||||
$ curl -v http://localhost:8888/hello
|
||||
...
|
||||
```
|
||||
|
||||
看看服务器和 `curl` 向标准输出流打印的内容吧。
|
||||
|
||||
现在来试试 `Flask`。运行步骤跟上面的一样。
|
||||
|
||||
```
|
||||
from flask import Flask
|
||||
from flask import Response
|
||||
flask_app = Flask('flaskapp')
|
||||
|
||||
|
||||
@flask_app.route('/hello')
|
||||
def hello_world():
|
||||
return Response(
|
||||
'Hello world from Flask!\n',
|
||||
mimetype='text/plain'
|
||||
)
|
||||
|
||||
app = flask_app.wsgi_app
|
||||
```
|
||||
|
||||
将以上代码保存为 `flaskapp.py`,或者直接从 [Github][11] 下载,然后输入以下命令运行服务器:
|
||||
|
||||
```
|
||||
(lsbaws) $ python webserver2.py flaskapp:app
|
||||
WSGIServer: Serving HTTP on port 8888 ...
|
||||
```
|
||||
|
||||
现在在浏览器中输入 http://localhost:8888/hello ,敲一下回车:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_browser_flask.png)
|
||||
|
||||
同样,尝试一下 `curl`,然后你会看到服务器返回了一条 `Flask` 应用生成的信息:
|
||||
|
||||
```
|
||||
$ curl -v http://localhost:8888/hello
|
||||
...
|
||||
```
|
||||
|
||||
这个服务器能处理 Django 应用吗?试试看吧!不过这个任务可能有点复杂,所以我建议你将整个仓库克隆下来,然后使用 [Github][13] 仓库中的 [djangoapp.py][12] 来完成这个实验。这里的源代码主要是将 Django 的 helloworld 工程(已使用 `Django` 的 `django-admin.py startproject` 命令创建完毕)添加到了当前的 Python 路径中,然后导入了这个工程的 WSGI 应用。(LCTT 译注:除了这里展示的代码,还需要一个配合的 helloworld 工程才能工作,代码可以参见 [Github][13] 仓库。)
|
||||
|
||||
```
|
||||
import sys
|
||||
sys.path.insert(0, './helloworld')
|
||||
from helloworld import wsgi
|
||||
|
||||
|
||||
app = wsgi.application
|
||||
```
|
||||
|
||||
将以上代码保存为 `djangoapp.py`,然后用你的 Web 服务器运行这个 Django 应用:
|
||||
|
||||
```
|
||||
(lsbaws) $ python webserver2.py djangoapp:app
|
||||
WSGIServer: Serving HTTP on port 8888 ...
|
||||
```
|
||||
|
||||
输入以下链接,敲回车:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_browser_django.png)
|
||||
|
||||
你这次也可以在命令行中测试——你之前应该已经做过两次了——来确认 Django 应用处理了你的请求:
|
||||
|
||||
```
|
||||
$ curl -v http://localhost:8888/hello
|
||||
...
|
||||
```
|
||||
|
||||
你试过了吗?你确定这个服务器可以与那三个框架搭配工作吗?如果没试,请去试一下。阅读固然重要,但这个系列的内容是**重新搭建**,这意味着你需要亲自动手干点活。去试一下吧。别担心,我等着你呢。不开玩笑,你真的需要试一下,亲自尝试每一步,并确保它像预期的那样工作。
|
||||
|
||||
好,你已经体验到了 WSGI 的威力:它可以使 Web 服务器及 Web 框架随意搭配。WSGI 在 Python Web 服务器及框架之间提供了一个微型接口。它非常简单,而且在服务器和框架端均可以轻易实现。下面的代码片段展示了 WSGI 接口的服务器及框架端实现:
|
||||
|
||||
```
|
||||
def run_application(application):
|
||||
"""服务器端代码。"""
|
||||
### Web 应用/框架在这里存储 HTTP 状态码以及 HTTP 响应头部,
|
||||
### 服务器会将这些信息传递给客户端
|
||||
headers_set = []
|
||||
### 用于存储 WSGI/CGI 环境变量的字典
|
||||
environ = {}
|
||||
|
||||
def start_response(status, response_headers, exc_info=None):
|
||||
headers_set[:] = [status, response_headers]
|
||||
|
||||
### 服务器唤醒可执行变量“application”,获得响应头部
|
||||
result = application(environ, start_response)
|
||||
### 服务器组装一个 HTTP 响应,将其传送至客户端
|
||||
…
|
||||
|
||||
def app(environ, start_response):
|
||||
"""一个空的 WSGI 应用"""
|
||||
start_response('200 OK', [('Content-Type', 'text/plain')])
|
||||
return ['Hello world!']
|
||||
|
||||
run_application(app)
|
||||
```
|
||||
|
||||
这是它的工作原理:
|
||||
|
||||
1. Web 框架提供一个可调用对象 `application` (WSGI 规范没有规定它的实现方式)。
|
||||
2. Web 服务器每次收到来自客户端的 HTTP 请求后,会唤醒可调用对象 `applition`。它会向该对象传递一个包含 WSGI/CGI 变量的环境变量字典 `environ`,以及一个可调用对象 `start_response`。
|
||||
3. Web 框架或应用生成 HTTP 状态码和 HTTP 响应头部,然后将它传给 `start_response` 函数,服务器会将其存储起来。同时,Web 框架或应用也会返回 HTTP 响应正文。
|
||||
4. 服务器将状态码、响应头部及响应正文组装成一个 HTTP 响应,然后将其传送至客户端(这一步并不在 WSGI 规范中,但从逻辑上讲,这一步应该包含在工作流程之中。所以为了明确这个过程,我把它写了出来)
|
||||
|
||||
这是这个接口规范的图形化表达:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_wsgi_interface.png)
|
||||
|
||||
到现在为止,你已经看过了用 Pyramid、Flask 和 Django 写出的 Web 应用的代码,你也看到了一个 Web 服务器如何用代码来实现另一半(服务器端的) WSGI 规范。你甚至还看到了我们如何在不使用任何框架的情况下,使用一段代码来实现一个最简单的 WSGI Web 应用。
|
||||
|
||||
其实,当你使用上面的框架编写一个 Web 应用时,你只是在较高的层面工作,而不需要直接与 WSGI 打交道。但是我知道你一定也对 WSGI 接口的框架部分感兴趣,因为你在看这篇文章呀。所以,我们不用 Pyramid、Flask 或 Django,而是自己动手来创造一个最朴素的 WSGI Web 应用(或 Web 框架),然后将它和你的服务器一起运行:
|
||||
|
||||
```
|
||||
def app(environ, start_response):
|
||||
"""一个最简单的 WSGI 应用。
|
||||
|
||||
这是你自己的 Web 框架的起点 ^_^
|
||||
"""
|
||||
status = '200 OK'
|
||||
response_headers = [('Content-Type', 'text/plain')]
|
||||
start_response(status, response_headers)
|
||||
return ['Hello world from a simple WSGI application!\n']
|
||||
```
|
||||
|
||||
同样,将上面的代码保存为 `wsgiapp.py` 或直接从 [Github][14] 上下载该文件,然后在 Web 服务器上运行这个应用,像这样:
|
||||
|
||||
```
|
||||
(lsbaws) $ python webserver2.py wsgiapp:app
|
||||
WSGIServer: Serving HTTP on port 8888 ...
|
||||
```
|
||||
|
||||
在浏览器中输入下面的地址,然后按下回车。这是你应该看到的结果:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_browser_simple_wsgi_app.png)
|
||||
|
||||
你刚刚在学习如何创建一个 Web 服务器的过程中自己编写了一个最朴素的 WSGI Web 框架!棒极了!
|
||||
|
||||
现在,我们再回来看看服务器传给客户端的那些东西。这是在使用 HTTP 客户端调用你的 Pyramid 应用时,服务器生成的 HTTP 响应内容:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_http_response.png)
|
||||
|
||||
这个响应和你在本系列第一部分中看到的 HTTP 响应有一部分共同点,但它还多出来了一些内容。比如说,它拥有四个你曾经没见过的 [HTTP 头部][15]:`Content-Type`, `Content-Length`, `Date` 以及 `Server`。这些头部内容基本上在每个 Web 服务器返回的响应中都会出现。不过,它们都不是被严格要求出现的。这些 HTTP 请求/响应头部字段的目的在于它可以向你传递一些关于 HTTP 请求/响应的额外信息。
|
||||
|
||||
既然你对 WSGI 接口了解的更深了一些,那我再来展示一下上面那个 HTTP 响应中的各个部分的信息来源:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_http_response_explanation.png)
|
||||
|
||||
我现在还没有对上面那个 `environ` 字典做任何解释,不过基本上这个字典必须包含那些被 WSGI 规范事先定义好的 WSGI 及 CGI 变量值。服务器在解析 HTTP 请求时,会从请求中获取这些变量的值。这是 `environ` 字典应该有的样子:
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_environ.png)
|
||||
|
||||
Web 框架会利用以上字典中包含的信息,通过字典中的请求路径、请求动作等等来决定使用哪个视图来处理响应、在哪里读取请求正文、在哪里输出错误信息(如果有的话)。
|
||||
|
||||
现在,你已经创造了属于你自己的 WSGI Web 服务器,你也使用不同 Web 框架做了几个 Web 应用。而且,你在这个过程中也自己创造出了一个朴素的 Web 应用及框架。这个过程真是累人。现在我们来回顾一下,你的 WSGI Web 服务器在服务请求时,需要针对 WSGI 应用做些什么:
|
||||
|
||||
- 首先,服务器开始工作,然后会加载一个可调用对象 `application`,这个对象由你的 Web 框架或应用提供
|
||||
- 然后,服务器读取一个请求
|
||||
- 然后,服务器会解析这个请求
|
||||
- 然后,服务器会使用请求数据来构建一个 `environ` 字典
|
||||
- 然后,它会用 `environ` 字典及一个可调用对象 `start_response` 作为参数,来调用 `application`,并获取响应体内容。
|
||||
- 然后,服务器会使用 `application` 返回的响应体,和 `start_response` 函数设置的状态码及响应头部内容,来构建一个 HTTP 响应。
|
||||
- 最终,服务器将 HTTP 响应回送给客户端。
|
||||
|
||||
![](https://ruslanspivak.com/lsbaws-part2/lsbaws_part2_server_summary.png)
|
||||
|
||||
这基本上是服务器要做的全部内容了。你现在有了一个可以正常工作的 WSGI 服务器,它可以为使用任何遵循 WSGI 规范的 Web 框架(如 Django、Flask、Pyramid,还有你刚刚自己写的那个框架)构建出的 Web 应用服务。最棒的部分在于,它可以在不用更改任何服务器代码的情况下,与多个不同的 Web 框架一起工作。真不错。
|
||||
|
||||
在结束之前,你可以想想这个问题:“你该如何让你的服务器在同一时间处理多个请求呢?”
|
||||
|
||||
敬请期待,我会在第三部分向你展示一种解决这个问题的方法。干杯!
|
||||
|
||||
顺便,我在撰写一本名为《搭个 Web 服务器:从头开始》的书。这本书讲解了如何从头开始编写一个基本的 Web 服务器,里面包含本文中没有的更多细节。[订阅邮件列表][16],你就可以获取到这本书的最新进展,以及发布日期。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://ruslanspivak.com/lsbaws-part2/
|
||||
|
||||
作者:[Ruslan][a]
|
||||
译者:[StdioA](https://github.com/StdioA)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://github.com/rspivak/
|
||||
[1]: https://linux.cn/article-7662-1.html
|
||||
[2]: https://www.python.org/dev/peps/pep-0333/
|
||||
[3]: https://www.djangoproject.com/
|
||||
[4]: http://flask.pocoo.org/
|
||||
[5]: http://trypyramid.com/
|
||||
[6]: http://gunicorn.org/
|
||||
[7]: http://uwsgi-docs.readthedocs.org/
|
||||
[8]: http://waitress.readthedocs.org/
|
||||
[9]: https://github.com/rspivak/lsbaws/blob/master/part2/webserver2.py
|
||||
[10]: https://github.com/rspivak/lsbaws/blob/master/part2/pyramidapp.py
|
||||
[11]: https://github.com/rspivak/lsbaws/blob/master/part2/flaskapp.py
|
||||
[12]: https://github.com/rspivak/lsbaws/blob/master/part2/flaskapp.py
|
||||
[13]: https://github.com/rspivak/lsbaws/
|
||||
[14]: https://github.com/rspivak/lsbaws/blob/master/part2/wsgiapp.py
|
||||
[15]: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
|
||||
[16]: https://ruslanspivak.com/lsbaws-part2/
|
@ -0,0 +1,94 @@
|
||||
给学习 OpenStack 架构的新手入门指南
|
||||
===========================================================
|
||||
|
||||
OpenStack 欢迎新成员的到来,但是,对于这个发展趋近成熟并且快速迭代的开源社区而言,能够拥有一个新手指南并不是件坏事。在奥斯汀举办的 OpenStack 峰会上,[Paul Belanger][1] (来自红帽公司)、 [Elizabeth K. Joseph][2] (来自 HPE 公司)和 [Christopher Aedo][3] (来自 IBM 公司)就[针对新人的 OpenStack 架构][4]作了一场专门的讲演。在这次采访中,他们提供了一些建议和资源来帮助新人成为 OpenStack 贡献者中的一员。
|
||||
|
||||
![](https://opensource.com/sites/default/files/images/life/Interview%20banner%20Q%26A.png)
|
||||
|
||||
**你的讲演介绍中说你将“深入架构核心,并解释你需要知道的关于让 OpenStack 工作起来的每一件事情”。这对于 40 分钟的讲演来说是一个艰巨的任务。那么,对于学习 OpenStack 架构的新手来说最需要知道那些事情呢?**
|
||||
|
||||
**Elizabeth K. Joseph (EKJ)**: 我们没有为 OpenStack 使用 GitHub 这种提交补丁的方式,这是因为这样做会对新手造成巨大的困扰,尽管由于历史原因我们还是在 GitHub 上维护了所有库的一个镜像。相反,我们使用了一种完全开源的评审形式,而且持续集成(CI)是由 OpenStack 架构团队维护的。与之有关的,自从我们使用了 CI 系统,每一个提交给 OpenStack 的改变都会在被合并之前进行测试。
|
||||
|
||||
**Paul Belanger (PB)**: 这个项目中的大多数都是富有激情的人,因此当你提交的补丁被某个人否定时不要感到沮丧。
|
||||
|
||||
**Christopher Aedo (CA)**:社区会帮助你取得成功,因此不要害怕提问或者寻求更多的那些能够促进你理解某些事物的引导者。
|
||||
|
||||
**在你的讲话中,对于一些你无法涉及到的方面,你会向新手推荐哪些在线资源来让他们更加容易入门?**
|
||||
|
||||
**PB**:当然是我们的 [OpenStack 项目架构文档][5]。我们已经花了足够大的努力来尽可能让这些文档能够随时保持最新状态。在 OpenStack 运行中使用的每个系统都作为一个项目,都制作了专门的页面来进行说明。甚至于连 OpenStack 云这种架构团队也会放到线上。
|
||||
|
||||
**EKJ**:我对于架构文档这件事上的观点和 Paul 是一致的,另外,我们十分乐意看到来自那些正在学习项目的人们提交上来的补丁。我们通常不会意识到我们忽略了文档中的某些内容,除非它们恰好被人问起。因此,阅读、学习,会帮助我们修补这些知识上的漏洞。你可以在 [OpenStack 架构邮件清单]提出你的问题,或者在我们位于 FreeNode 上的 #OpenStack-infra 的 IRC 专栏发起你的提问。
|
||||
|
||||
**CA**:我喜欢[这个详细的帖子][7],它是由 Ian Wienand 写的一篇关于构建镜像的文章。
|
||||
|
||||
**"gotchas" 会是 OpenStack 新的贡献者们所寻找的吗?**
|
||||
|
||||
**EKJ**:向项目作出贡献并不仅仅是提交新的代码和新的特性;OpenStack 社区高度重视代码评审。如果你想要别人查看你的补丁,那你最好先看看其他人是如何做的,然后参考他们的风格,最后一步步做到你也能够向其他人一样提交清晰且结构分明的代码补丁。你越是能让你的同伴了解你的工作并知道你正在做的评审,那他们也就越有可能及时评审你的代码。
|
||||
|
||||
**CA**:我看到过大量的新手在面对 [Gerrit][8] 时受挫,阅读开发者引导中的[开发者工作步骤][9],有可能的话多读几遍。如果你没有用过 Gerrit,那你最初对它的感觉可能是困惑和无力的。但是,如果你随后做了一些代码评审的工作,那么你就能轻松应对它。此外,我是 IRC 的忠实粉丝,它可能是一个获得帮助的好地方,但是,你最好保持一个长期在线的状态,这样,尽管你在某个时候没有出现,人们也可以回答你的问题。(阅读 [IRC,开源成功的秘诀][10])你不必总是在线,但是你最好能够轻松的在一个频道中回溯之前信息,以此来跟上最新的动态,这种能力非常重要。
|
||||
|
||||
**PB**:我同意 Elizabeth 和 Chris 的观点, Gerrit 是需要花点精力的,它将汇聚你的开发方面的努力。你不仅仅要提交代码给别人去评审,同时,你也要能够评审其他人的代码。看到 Gerrit 的界面,你可能一时会变的很困惑。我推荐新手去尝试 [Gertty][11],它是一个基于控制台的终端界面,用于 Gerrit 代码评审系统,而它恰好也是 OpenStack 架构所驱动的一个项目。
|
||||
|
||||
**你对于 OpenStack 新手如何通过网络与其他贡献者交流方面有什么好的建议?**
|
||||
|
||||
**PB**:对我来说,是通过 IRC 并在 Freenode 上参加 #OpenStack-infra 频道([IRC 日志][12])。这频道上面有很多对新手来说很有价值的资源。你可以看到 OpenStack 项目日复一日的运作情况,同时,一旦你知道了 OpenStack 项目的工作原理,你将更好的知道如何为 OpenStack 的未来发展作出贡献。
|
||||
|
||||
**CA**:我想要为 IRC 再次说明一点,在 IRC 上保持全天在线记录对我来说有非常重大的意义,因为我会时刻保持连接并随时接到提醒。这也是一种非常好的获得帮助的方式,特别是当你和某人卡在了项目中出现的某一个难题的时候,而在一个活跃的 IRC 频道中,总会有一些人很乐意为你解决问题。
|
||||
|
||||
**EKJ**:[OpenStack 开发邮件列表][13]对于能够时刻查看到你所致力于的 OpenStack 项目的最新情况是非常重要的。因此,我推荐一定要订阅它。邮件列表使用主题标签来区分项目,因此你可以设置你的邮件客户端来使用它来专注于你所关心的项目。除了在线资源之外,全世界范围内也成立了一些 OpenStack 小组,他们被用来为 OpenStack 的用户和贡献者提供服务。这些小组可能会定期要求 OpenStack 主要贡献者们举办座谈和活动。你可以在 MeetUp.com 上搜素你所在地域的贡献者活动聚会,或者在 [groups.openstack.org][14] 上查看你所在的地域是否存在 OpenStack 小组。最后,还有一个每六个月举办一次的 [OpenStack 峰会][15],这个峰会上会作一些关于架构的演说。当前状态下,这个峰会包含了用户会议和开发者会议,会议内容都是和 OpenStack 相关的东西,包括它的过去,现在和未来。
|
||||
|
||||
**OpenStack 需要在那些方面得到提升来让新手更加容易学会并掌握?**
|
||||
|
||||
**PB**: 我认为我们的 [account-setup][16] 环节对于新的贡献者已经做的比较容易了,特别是教他们如何提交他们的第一个补丁。真正参与到 OpenStack 开发者模式中是需要花费很大的努力的,相比贡献者来说已经显得非常多了;然而,一旦融入进去了,这个模式将会运转的十分高效和令人满意。
|
||||
|
||||
**CA**: 我们拥有一个由专业开发者组成的社区,而且我们的关注点都是发展 OpenStack 本身,同时,我们致力于让用户付出更小的代价去使用 OpenStack 云架构平台。我们需要发掘更多的应用开发者,并且鼓励更多的人去开发能在 OpenStack 云上完美运行的云应用程序,我们还鼓励他们在[社区 App 目录][17]上去贡献那些由他们开发的应用。我们可以通过不断提升我们的 API 标准和保证我们不同的库(比如 libcloud,phpopencloud 以及其他一些库)持续地为开发者提供可信赖的支持来实现这一目标。还有一点就是通过举办更多的 OpenStack 黑客比赛。所有的这些事情都可以降低新人的学习门槛,这样也能引导他们与这个社区之间的关系更加紧密。
|
||||
|
||||
**EKJ**: 我已经致力于开源软件很多年了。但是,对于大量的 OpenStack 开发者而言,这是一个他们自己所从事的第一个开源项目。我发现他们之前使用私有软件的背景并没有为他们塑造开源的观念、方法论,以及在开源项目中需要具备的合作技巧。我乐于看到我们能够让那些曾经一直在使用私有软件工作的人能够真正的明白他们在开源如软件社区所从事的事情的巨大价值。
|
||||
|
||||
**我想把 2016 年打造成开源俳句之年。请用俳句来向新手解释 OpenStack 一下。**
|
||||
|
||||
(LCTT 译注:俳句(Haiku)是一种日本古典短诗,以5-7-5音节为三句,校对者不揣浅陋,诌了几句歪诗,勿笑 :D,另外 OpenStack 本身音节太长,就捏造了一个中文译名“开栈”——明白就好。)
|
||||
|
||||
**PB**: 开栈在云上//倘钟情自由软件//先当造补丁(OpenStack runs clouds
|
||||
If you enjoy free software
|
||||
Submit your first patch)
|
||||
|
||||
**CA**:时光不必久//开栈将支配世界//协力早来到(In the near future
|
||||
OpenStack will rule the world
|
||||
Help make it happen!)
|
||||
|
||||
**EKJ**:开栈有自由//放在自家服务器//运行你的云(OpenStack is free
|
||||
Deploy on your own servers
|
||||
And run your own cloud!)
|
||||
|
||||
*Paul、Elizabeth 和 Christopher 在 4 月 25 号星期一上午 11:15 于奥斯汀举办的 OpenStack 峰会发表了[演说][18]。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/16/4/interview-openstack-infrastructure-beginners
|
||||
|
||||
作者:[Rikki Endsley][a]
|
||||
译者:[kylepeng93](https://github.com/kylepeng93)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://rikkiendsley.com/
|
||||
[1]: https://twitter.com/pabelanger
|
||||
[2]: https://twitter.com/pleia2
|
||||
[3]: https://twitter.com/docaedo
|
||||
[4]: https://www.openstack.org/summit/austin-2016/summit-schedule/events/7337
|
||||
[5]: http://docs.openstack.org/infra/system-config/
|
||||
[6]: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-infra
|
||||
[7]: https://www.technovelty.org/openstack/image-building-in-openstack-ci.html
|
||||
[8]: https://code.google.com/p/gerrit/
|
||||
[9]: http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
[10]: https://developer.ibm.com/opentech/2015/12/20/irc-the-secret-to-success-in-open-source/
|
||||
[11]: https://pypi.python.org/pypi/gertty
|
||||
[12]: http://eavesdrop.openstack.org/irclogs/%23openstack-infra/
|
||||
[13]: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
|
||||
[14]: https://groups.openstack.org/
|
||||
[15]: https://www.openstack.org/summit/
|
||||
[16]: http://docs.openstack.org/infra/manual/developers.html#account-setup
|
||||
[17]: https://apps.openstack.org/
|
||||
[18]: https://www.openstack.org/summit/austin-2016/summit-schedule/events/7337
|
@ -0,0 +1,61 @@
|
||||
Drupal、IoT 和开源硬件之间的交集
|
||||
=======================================================
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/drupal_blue_gray_lead.jpeg?itok=t7W_KD-D)
|
||||
|
||||
|
||||
来认识一下 [Amber Matz][1],她是来自 Lullabot Education 旗下的 [Drupalize.Me][3] 的产品经理以及培训师。当她没有倒腾 Arduino、Raspberry Pi 以及电子穿戴设备时,通常会在波特兰 Drupal 用户组里担任辩论主持人。
|
||||
|
||||
在即将举行的 [DrupalCon NOLA][3] 大会上,Amber 将主持一个关于 Drupal 和 IoT 的主题。如果你会去参加,也想了解下开源硬件,IoT 和 Drupal 之间的交集,那这个将很合适。如果你去不了新奥尔良的现场也没关系,Amber 还分享了许多很酷的事情。在这次采访中,她讲述了自己参与 Drupal 的原因,一些她自己喜欢的开源硬件项目,以及 IoT 和 Drupal 的未来。
|
||||
|
||||
![](https://opensource.com/sites/default/files/images/life/Interview%20banner%20Q%26A.png)
|
||||
|
||||
**你是怎么加入 Drupal 社区的?**
|
||||
|
||||
在这之前,我在一家大型非盈利性机构市场部的“网站管理部”工作,飞快地批量生产出各种定制 PHP/MySQL 表单。最终我厌烦了这一切,并开始在网上寻找更好的方式。然后我找到了 Drupal 6 并开始沉迷进去。过了几年,在一次跳槽之后,我发现了波特兰 Drupal 用户组,然后在里面找了一份全职的 Drupal 开发者工作。我一直经常参加在波特兰的聚会,在那里我找到了大量的社区、朋友和专业方面的发展。一个偶然的机会,我在 Lullabot 找了一份培训师的工作,为 Drupalize.Me 提供内容。现在,我管理着 Drupalize.Me 的内容输出,负责编撰 Drupal 8 相关的内容,还很大程度地参与到波特兰 Drupal 社区中。我是今年的协调员,寻找并安排演讲者们。
|
||||
|
||||
**我们想知道:什么是 Arduino 原型,你是怎么找到它的,以及你用 Arduino 做过的最酷的事是什么?**
|
||||
|
||||
Arduino,Raspberry Pi,以及可穿戴电子设备,这些年到处都能听到这些术语。我在几年前通过 Becky Stern 的 YouTube 秀(最近由 Becky 继续主持,每周三播出)发现了 [Adafruit 的可穿戴电子设备][4]。我被那些可穿戴设备迷住了,还订了一套 LED 缝制工具,不过没做出任何东西。我不太适合它。我没有任何电子相关的背景,而且在我被那些项目吸引的时候,我根本不知道怎么做出那样的东西,它似乎看上去太遥远了。
|
||||
|
||||
后来,我在 Coursera 上找到了一个“物联网”专题。(很时髦,对吧?)我很快就喜欢上了。我最终找到了 Arduino 是什么的解释,以及所有这些其他的重要术语和概念。我订了一套推荐的 Arduino 初学者套件,还附带了一本如何上手的小册子。当我第一次让 LED 闪烁的时候,开心极了。我在圣诞节以及之后有两个星期的假期,然而我什么都没干,就一直根据初学者小册子给 Arduino 电路编程。很奇怪我觉得很放松!我太喜欢了。
|
||||
|
||||
在一月份的时候,我开始构思我自己的原型设备。在知道我需要主持公司培训的开场白时,我用五个 LED 灯和 Arduino 搭建了一个开场白视觉计时器的原型。
|
||||
|
||||
![](https://opensource.com/sites/default/files/resize/amber-arduino-lightning-talk-timer-400x400.jpg)
|
||||
|
||||
这是一次巨大的成功。我还做了我的第一个可穿戴项目,一件会发光的连帽衫,使用了和 Arduino IDE 兼容的 Gemma 微控制器,一个小的圆形可缝制部件,然后用可导电的线缝起来,将一个滑动可变电阻和衣服帽口的收缩绳连在一起,用来控制缝到帽子里的五个 NeoPixel 灯的颜色。这就是我对原型设计的看法:做一些很好玩也可能会有点实际用途的疯狂项目。
|
||||
|
||||
**Drupal 和 IoT 带来的最大机遇是什么??**
|
||||
|
||||
IoT 与 Web Service 以及 Drupal 分层趋势实际并没有太大差别。就是将数据从一个东西传送到另一个东西,然后将数据转换成一些有用的东西。但数据是如何送达?能用来做点什么?你觉得现在就有一大堆现成的解决方案、应用、中间层,以及 API 吗?采用 IoT,这只会继续成几何指数级的增长。我觉得,给我任何一个设备或“东西”,总有办法来将它连接到互联网上,有很多办法。而且有大量现成的代码库来帮助创客们将他们的数据从一个东西传到另一个东西。
|
||||
|
||||
那么 Drupal 在这里处于什么位置?首先,Web services 将是第一个明显的地方。但作为一个创客,我不希望将时间花在编写 Drupal 的订制模块上。我想要的是即插即用!所以我很高兴出现这样的模块能连接 IoT 云端 API 和服务,比如 ThingSpeak,Adafruit.io,IFTTT,以及其他的。我觉得也有一个很好的商业机会,在 Drupal 里构建一套 IoT 云服务,允许用户发送和存储他们的传感器数据,并可以制成表格和图像,还可以写一些插件可以响应特定数据或阙值。每一个 IoT 云 API 服务都是一个细分的机会,所以能留下很大空间给其他人。
|
||||
|
||||
**这次 DrupalCon 你有哪些期待?**
|
||||
|
||||
我喜欢与 Drupal 上的朋友重逢,认识一些新的人,还能见到 Lullabot 和 Drupalize.Me 的同事(我们是分布式的公司)!Drupal 8 有太多东西可以去探索了,我们给我们的客户们提供了海量的培训资料。所以,我很期待参与一些 Drupal 8 相关的主题,以及跟上最新的开发进度。最后,我对新奥尔良也很感兴趣!我曾经在 2004 年去过,很期待将这次将看到哪些改变。
|
||||
|
||||
**谈一谈你这次 DrupalCon 上的演讲:“超越闪烁:将 Drupal 加到你的 IoT 游乐场中”。别人为什么要参加?他们最重要的收获会是什么?**
|
||||
|
||||
我的主题的标题是,“超越闪烁:将 Drupal 加到你的 IoT 游乐场中”,假设我们所有人都处在同一进度和层次,你不需要了解任何关于 Arduino、物联网、甚至是 Drupal,都能跟上。我将从用 Arduino 让 LED 灯闪烁开始,然后我会谈一下我自己在这里面的最大收获:玩、学、教和做。我会列出一些曾经激励过我的例子,它们也很有希望能激发和鼓励其他听众去尝试一下。然后,就是展示时间!
|
||||
|
||||
首先,第一个东西。它是一个建筑提醒信号灯。在这个展示里,我会说明如何将信号灯连到互联网上,以及如何响应从云 API 服务收到的数据。然后,第二个东西。它是一个蒸汽朋克风格 iPhone 外壳形式的“天气手表”。有一个小型 LED 矩阵用来显示我的天气的图标,一个气压和温度传感器,一个 GPS 模块,以及一个 Bluetooth LE 模块,都连接到一个 Adafruit Flora 微控制器上。第二个东西能通过蓝牙连接到我的 iPhone 上的一个应用,并将天气和位置数据通过 MQTT 协议发到 Adafruit.io 的服务器!然后,在 Drupal 这边,我会从云端下载这些数据,更新天气信息,然后更新地图。所以大家也能体验一下通过web service、地图和 Drupal 8 的功能块所能做的事情。
|
||||
|
||||
学习和制作这些展示原型是一次烧脑的探险,我也希望有人能参与这个主题并感染一点我对这种技术交叉的传染性热情!我很兴奋能分享一些我的发现。
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/16/5/drupalcon-interview-amber-matz
|
||||
|
||||
作者:[Jason Hibbets][a]
|
||||
译者:[zpl1025](https://github.com/zpl1025)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jhibbets
|
||||
[1]: https://www.drupal.org/u/amber-himes-matz
|
||||
[2]: https://drupalize.me/
|
||||
[3]: https://events.drupal.org/neworleans2016/
|
||||
[4]: https://www.adafruit.com/beckystern
|
@ -0,0 +1,49 @@
|
||||
Linus Torvalds 谈及物联网、智能设备、安全连接等问题
|
||||
===========================================================================
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/elc-linus-b.jpg?itok=6WwnCSjL)
|
||||
|
||||
*Dirk Hohndel 在嵌入式大会上采访 Linus Torvalds 。*
|
||||
|
||||
|
||||
4 月 4 日到 6 日,在圣迭戈召开的[嵌入式 Linux 大会(Embedded Linux Conference)][0](ELC) 从首次举办到现在已经有 11 年了,该会议包括了与 Linus Torvalds 的主题讨论。作为 Linux 内核的缔造者和最高决策者——用采访他的英特尔 Linux 和开源技术总监 Dirk Hohndel 的话说,“(他是)我们聚在一起的理由”——他对 Linux 在嵌入式和物联网应用程序领域的发展表示乐观。Torvalds 很明确地力挺了嵌入式 Linux,它被 Linux 桌面、服务器和云技术这些掩去光芒已经很多年了。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/elc-linus_0.jpg?itok=FNPIDe8k)
|
||||
|
||||
*Linus Torvalds 在嵌入式 Linux 大会上的演讲。*
|
||||
|
||||
物联网是嵌入式大会的主题,在 OpenIoT 峰会讲演中谈到了,在 Torvalds 的访谈中也是主要话题。
|
||||
|
||||
Torvalds 对 Hohndel 说到,“或许你不会在物联网末端设备上看到 Linux 的影子,但是在你有一个中心设备的时候,你就会需要它。尤其是物联网标准都有 23 个的时候,你就更需要智能设备了。如果你全部使用的是低级设备,它们没必要一定运行 Linux;如果它们采用的标准稍有差异,你就需要很多的智能设备。我们将来也不会有一个完全开放的标准来将这些物联网设备统一到一起,但是我们会有 3/4 的主要协议是一样的,然后那些智能的中心设备就可以对它们进行互相转换。”
|
||||
|
||||
当 Hohndel 问及在物联网的巨大安全漏洞的时候,Torvalds 神情如常。他说:“我不担心安全问题因为我们能做的不是很多,物联网(设备)是不能更新的,这是我们面对的事实。"
|
||||
|
||||
Linux 缔造者看起来更关心的是一次性嵌入式项目缺少对上游的及时贡献,尽管他注意到近年来这些有了一些显著改善,特别是在硬件整合方面。
|
||||
|
||||
“嵌入式领域历来就很难与开源开发者有所联系,但是我认为这些都在发生改变。”Torvalds 说:“ARM 社区变得越来越好了。内核维护者实际上现在也能跟上了一些硬件的更新换代。一切都在变好,但是还不够。”
|
||||
|
||||
Torvalds 承认他在家经常使用桌面系统而不是嵌入式系统,并且对硬件不是很熟悉。
|
||||
|
||||
“我已经用电烙铁弄坏了很多东西。”他说到。“我真的不适合搞硬件开发。”另一方面,Torvalds 设想如果他现在是个年轻人,他可能也在摆弄 Raspberry Pi 和 BeagleBone(猎兔犬板)。“最棒的是你不需要精通焊接,你只需要买个新的板子就行。”
|
||||
|
||||
同时,Torvalds 也承诺他要为 Linux 桌面再奋斗一个 25 年。他笑着说:“我要为它工作一生。”
|
||||
|
||||
下面,请看完整[视频](https://youtu.be/tQKUWkR-wtM)。
|
||||
|
||||
|
||||
要获取关于嵌入式 Linux 和物联网的最新信息,请访问 2016 年嵌入式 Linux 大会 150+ 分钟的会议全程。[现在观看][1]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/linus-torvalds-talks-iot-smart-devices-security-concerns-and-more-video
|
||||
|
||||
作者:[ERIC BROWN][a]
|
||||
译者:[vim-kakali](https://github.com/vim-kakali)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/ericstephenbrown
|
||||
[0]: http://events.linuxfoundation.org/events/embedded-linux-conference
|
||||
[1]: http://go.linuxfoundation.org/elc-openiot-summit-2016-videos?utm_source=lf&utm_medium=blog&utm_campaign=linuxcom
|
||||
|
399
published/201608/20160512 Bitmap in Linux Kernel.md
Normal file
399
published/201608/20160512 Bitmap in Linux Kernel.md
Normal file
@ -0,0 +1,399 @@
|
||||
Linux 内核里的数据结构——位数组
|
||||
================================================================================
|
||||
|
||||
Linux 内核中的位数组和位操作
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
除了不同的基于[链式](https://en.wikipedia.org/wiki/Linked_data_structure)和[树](https://en.wikipedia.org/wiki/Tree_%28data_structure%29)的数据结构以外,Linux 内核也为[位数组](https://en.wikipedia.org/wiki/Bit_array)(或称为位图(bitmap))提供了 [API](https://en.wikipedia.org/wiki/Application_programming_interface)。位数组在 Linux 内核里被广泛使用,并且在以下的源代码文件中包含了与这样的结构搭配使用的通用 `API`:
|
||||
|
||||
* [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c)
|
||||
* [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h)
|
||||
|
||||
除了这两个文件之外,还有体系结构特定的头文件,它们为特定的体系结构提供优化的位操作。我们将探讨 [x86_64](https://en.wikipedia.org/wiki/X86-64) 体系结构,因此在我们的例子里,它会是
|
||||
|
||||
* [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h)
|
||||
|
||||
头文件。正如我上面所写的,`位图`在 Linux 内核中被广泛地使用。例如,`位数组`常常用于保存一组在线/离线处理器,以便系统支持[热插拔](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt)的 CPU(你可以在 [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) 部分阅读更多相关知识 ),一个位数组(bit array)可以在 Linux 内核初始化等期间保存一组已分配的[中断处理](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29)。
|
||||
|
||||
因此,本部分的主要目的是了解位数组(bit array)是如何在 Linux 内核中实现的。让我们现在开始吧。
|
||||
|
||||
位数组声明
|
||||
================================================================================
|
||||
|
||||
在我们开始查看`位图`操作的 `API` 之前,我们必须知道如何在 Linux 内核中声明它。有两种声明位数组的通用方法。第一种简单的声明一个位数组的方法是,定义一个 `unsigned long` 的数组,例如:
|
||||
|
||||
```C
|
||||
unsigned long my_bitmap[8]
|
||||
```
|
||||
|
||||
第二种方法,是使用 `DECLARE_BITMAP` 宏,它定义于 [include/linux/types.h](https://github.com/torvalds/linux/blob/master/include/linux/types.h) 头文件:
|
||||
|
||||
```C
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
```
|
||||
|
||||
我们可以看到 `DECLARE_BITMAP` 宏使用两个参数:
|
||||
|
||||
* `name` - 位图名称;
|
||||
* `bits` - 位图中位数;
|
||||
|
||||
并且只是使用 `BITS_TO_LONGS(bits)` 元素展开 `unsigned long` 数组的定义。 `BITS_TO_LONGS` 宏将一个给定的位数转换为 `long` 的个数,换言之,就是计算 `bits` 中有多少个 `8` 字节元素:
|
||||
|
||||
```C
|
||||
#define BITS_PER_BYTE 8
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
||||
```
|
||||
|
||||
因此,例如 `DECLARE_BITMAP(my_bitmap, 64)` 将产生:
|
||||
|
||||
```python
|
||||
>>> (((64) + (64) - 1) / (64))
|
||||
1
|
||||
```
|
||||
|
||||
与:
|
||||
|
||||
```C
|
||||
unsigned long my_bitmap[1];
|
||||
```
|
||||
|
||||
在能够声明一个位数组之后,我们便可以使用它了。
|
||||
|
||||
体系结构特定的位操作
|
||||
================================================================================
|
||||
|
||||
我们已经看了上面提及的一对源文件和头文件,它们提供了位数组操作的 [API](https://en.wikipedia.org/wiki/Application_programming_interface)。其中重要且广泛使用的位数组 API 是体系结构特定的且位于已提及的头文件中 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h)。
|
||||
|
||||
首先让我们查看两个最重要的函数:
|
||||
|
||||
* `set_bit`;
|
||||
* `clear_bit`.
|
||||
|
||||
我认为没有必要解释这些函数的作用。从它们的名字来看,这已经很清楚了。让我们直接查看它们的实现。如果你浏览 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,你将会注意到这些函数中的每一个都有[原子性](https://en.wikipedia.org/wiki/Linearizability)和非原子性两种变体。在我们开始深入这些函数的实现之前,首先,我们必须了解一些有关原子(atomic)操作的知识。
|
||||
|
||||
简而言之,原子操作保证两个或以上的操作不会并发地执行同一数据。`x86` 体系结构提供了一系列原子指令,例如, [xchg](http://x86.renejeschke.de/html/file_module_x86_id_328.html)、[cmpxchg](http://x86.renejeschke.de/html/file_module_x86_id_41.html) 等指令。除了原子指令,一些非原子指令可以在 [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) 指令的帮助下具有原子性。现在你已经对原子操作有了足够的了解,我们可以接着探讨 `set_bit` 和 `clear_bit` 函数的实现。
|
||||
|
||||
我们先考虑函数的非原子性(non-atomic)变体。非原子性的 `set_bit` 和 `clear_bit` 的名字以双下划线开始。正如我们所知道的,所有这些函数都定义于 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,并且第一个函数就是 `__set_bit`:
|
||||
|
||||
```C
|
||||
static inline void __set_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
|
||||
}
|
||||
```
|
||||
|
||||
正如我们所看到的,它使用了两个参数:
|
||||
|
||||
* `nr` - 位数组中的位号(LCTT 译注:从 0开始)
|
||||
* `addr` - 我们需要置位的位数组地址
|
||||
|
||||
注意,`addr` 参数使用 `volatile` 关键字定义,以告诉编译器给定地址指向的变量可能会被修改。 `__set_bit` 的实现相当简单。正如我们所看到的,它仅包含一行[内联汇编代码](https://en.wikipedia.org/wiki/Inline_assembler)。在我们的例子中,我们使用 [bts](http://x86.renejeschke.de/html/file_module_x86_id_25.html) 指令,从位数组中选出一个第一操作数(我们的例子中的 `nr`)所指定的位,存储选出的位的值到 [CF](https://en.wikipedia.org/wiki/FLAGS_register) 标志寄存器并设置该位(LCTT 译注:即 `nr` 指定的位置为 1)。
|
||||
|
||||
注意,我们了解了 `nr` 的用法,但这里还有一个参数 `addr` 呢!你或许已经猜到秘密就在 `ADDR`。 `ADDR` 是一个定义在同一个头文件中的宏,它展开为一个包含给定地址和 `+m` 约束的字符串:
|
||||
|
||||
```C
|
||||
#define ADDR BITOP_ADDR(addr)
|
||||
#define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
|
||||
```
|
||||
|
||||
除了 `+m` 之外,在 `__set_bit` 函数中我们可以看到其他约束。让我们查看并试着理解它们所表示的意义:
|
||||
|
||||
* `+m` - 表示内存操作数,这里的 `+` 表明给定的操作数为输入输出操作数;
|
||||
* `I` - 表示整型常量;
|
||||
* `r` - 表示寄存器操作数
|
||||
|
||||
除了这些约束之外,我们也能看到 `memory` 关键字,其告诉编译器这段代码会修改内存中的变量。到此为止,现在我们看看相同的原子性(atomic)变体函数。它看起来比非原子性(non-atomic)变体更加复杂:
|
||||
|
||||
```C
|
||||
static __always_inline void
|
||||
set_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (IS_IMMEDIATE(nr)) {
|
||||
asm volatile(LOCK_PREFIX "orb %1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" ((u8)CONST_MASK(nr))
|
||||
: "memory");
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX "bts %1,%0"
|
||||
: BITOP_ADDR(addr) : "Ir" (nr) : "memory");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(LCTT 译注:BITOP_ADDR 的定义为:`#define BITOP_ADDR(x) "=m" (*(volatile long *) (x))`,ORB 为字节按位或。)
|
||||
|
||||
首先注意,这个函数使用了与 `__set_bit` 相同的参数集合,但额外地使用了 `__always_inline` 属性标记。 `__always_inline` 是一个定义于 [include/linux/compiler-gcc.h](https://github.com/torvalds/linux/blob/master/include/linux/compiler-gcc.h) 的宏,并且只是展开为 `always_inline` 属性:
|
||||
|
||||
```C
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
```
|
||||
|
||||
其意味着这个函数总是内联的,以减少 Linux 内核映像的大小。现在让我们试着了解下 `set_bit` 函数的实现。首先我们在 `set_bit` 函数的开头检查给定的位的数量。`IS_IMMEDIATE` 宏定义于相同的[头文件](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h),并展开为 [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection) 内置函数的调用:
|
||||
|
||||
```C
|
||||
#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr))
|
||||
```
|
||||
|
||||
如果给定的参数是编译期已知的常量,`__builtin_constant_p` 内置函数则返回 `1`,其他情况返回 `0`。假若给定的位数是编译期已知的常量,我们便无须使用效率低下的 `bts` 指令去设置位。我们可以只需在给定地址指向的字节上执行 [按位或](https://en.wikipedia.org/wiki/Bitwise_operation#OR) 操作,其字节包含给定的位,掩码位数表示高位为 `1`,其他位为 0 的掩码。在其他情况下,如果给定的位号不是编译期已知常量,我们便做和 `__set_bit` 函数一样的事。`CONST_MASK_ADDR` 宏:
|
||||
|
||||
```C
|
||||
#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3))
|
||||
```
|
||||
|
||||
展开为带有到包含给定位的字节偏移的给定地址,例如,我们拥有地址 `0x1000` 和位号 `0x9`。因为 `0x9` 代表 `一个字节 + 一位`,所以我们的地址是 `addr + 1`:
|
||||
|
||||
```python
|
||||
>>> hex(0x1000 + (0x9 >> 3))
|
||||
'0x1001'
|
||||
```
|
||||
|
||||
`CONST_MASK` 宏将我们给定的位号表示为字节,位号对应位为高位 `1`,其他位为 `0`:
|
||||
|
||||
```C
|
||||
#define CONST_MASK(nr) (1 << ((nr) & 7))
|
||||
```
|
||||
|
||||
```python
|
||||
>>> bin(1 << (0x9 & 7))
|
||||
'0b10'
|
||||
```
|
||||
|
||||
最后,我们应用 `按位或` 运算到这些变量上面,因此,假如我们的地址是 `0x4097` ,并且我们需要置位号为 `9` 的位为 1:
|
||||
|
||||
```python
|
||||
>>> bin(0x4097)
|
||||
'0b100000010010111'
|
||||
>>> bin((0x4097 >> 0x9) | (1 << (0x9 & 7)))
|
||||
'0b100010'
|
||||
```
|
||||
|
||||
`第 9 位` 将会被置位。(LCTT 译注:这里的 9 是从 0 开始计数的,比如0010,按照作者的意思,其中的 1 是第 1 位)
|
||||
|
||||
注意,所有这些操作使用 `LOCK_PREFIX` 标记,其展开为 [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) 指令,保证该操作的原子性。
|
||||
|
||||
正如我们所知,除了 `set_bit` 和 `__set_bit` 操作之外,Linux 内核还提供了两个功能相反的函数,在原子性和非原子性的上下文中清位。它们是 `clear_bit` 和 `__clear_bit`。这两个函数都定义于同一个[头文件](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 并且使用相同的参数集合。不仅参数相似,一般而言,这些函数与 `set_bit` 和 `__set_bit` 也非常相似。让我们查看非原子性 `__clear_bit` 的实现吧:
|
||||
|
||||
```C
|
||||
static inline void __clear_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
|
||||
}
|
||||
```
|
||||
|
||||
没错,正如我们所见,`__clear_bit` 使用相同的参数集合,并包含极其相似的内联汇编代码块。它只是使用 [btr](http://x86.renejeschke.de/html/file_module_x86_id_24.html) 指令替换了 `bts`。正如我们从函数名所理解的一样,通过给定地址,它清除了给定的位。`btr` 指令表现得像 `bts`(LCTT 译注:原文这里为 btr,可能为笔误,修正为 bts)。该指令选出第一操作数所指定的位,存储它的值到 `CF` 标志寄存器,并且清除第二操作数指定的位数组中的对应位。
|
||||
|
||||
`__clear_bit` 的原子性变体为 `clear_bit`:
|
||||
|
||||
```C
|
||||
static __always_inline void
|
||||
clear_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (IS_IMMEDIATE(nr)) {
|
||||
asm volatile(LOCK_PREFIX "andb %1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" ((u8)~CONST_MASK(nr)));
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX "btr %1,%0"
|
||||
: BITOP_ADDR(addr)
|
||||
: "Ir" (nr));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
并且正如我们所看到的,它与 `set_bit` 非常相似,只有两处不同。第一处差异为 `clear_bit` 使用 `btr` 指令来清位,而 `set_bit` 使用 `bts` 指令来置位。第二处差异为 `clear_bit` 使用否定的位掩码和 `按位与` 在给定的字节上置位,而 `set_bit` 使用 `按位或` 指令。
|
||||
|
||||
到此为止,我们可以在任意位数组置位和清位了,我们将看看位掩码上的其他操作。
|
||||
|
||||
在 Linux 内核中对位数组最广泛使用的操作是设置和清除位,但是除了这两个操作外,位数组上其他操作也是非常有用的。Linux 内核里另一种广泛使用的操作是知晓位数组中一个给定的位是否被置位。我们能够通过 `test_bit` 宏的帮助实现这一功能。这个宏定义于 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,并根据位号分别展开为 `constant_test_bit` 或 `variable_test_bit` 调用。
|
||||
|
||||
```C
|
||||
#define test_bit(nr, addr) \
|
||||
(__builtin_constant_p((nr)) \
|
||||
? constant_test_bit((nr), (addr)) \
|
||||
: variable_test_bit((nr), (addr)))
|
||||
```
|
||||
|
||||
因此,如果 `nr` 是编译期已知常量,`test_bit` 将展开为 `constant_test_bit` 函数的调用,而其他情况则为 `variable_test_bit`。现在让我们看看这些函数的实现,让我们从 `variable_test_bit` 开始看起:
|
||||
|
||||
```C
|
||||
static inline int variable_test_bit(long nr, volatile const unsigned long *addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
asm volatile("bt %2,%1\n\t"
|
||||
"sbb %0,%0"
|
||||
: "=r" (oldbit)
|
||||
: "m" (*(unsigned long *)addr), "Ir" (nr));
|
||||
|
||||
return oldbit;
|
||||
}
|
||||
```
|
||||
|
||||
`variable_test_bit` 函数使用了与 `set_bit` 及其他函数使用的相似的参数集合。我们也可以看到执行 [bt](http://x86.renejeschke.de/html/file_module_x86_id_22.html) 和 [sbb](http://x86.renejeschke.de/html/file_module_x86_id_286.html) 指令的内联汇编代码。`bt` (或称 `bit test`)指令从第二操作数指定的位数组选出第一操作数指定的一个指定位,并且将该位的值存进标志寄存器的 [CF](https://en.wikipedia.org/wiki/FLAGS_register) 位。第二个指令 `sbb` 从第二操作数中减去第一操作数,再减去 `CF` 的值。因此,这里将一个从给定位数组中的给定位号的值写进标志寄存器的 `CF` 位,并且执行 `sbb` 指令计算: `00000000 - CF`,并将结果写进 `oldbit` 变量。
|
||||
|
||||
`constant_test_bit` 函数做了和我们在 `set_bit` 所看到的一样的事:
|
||||
|
||||
```C
|
||||
static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr)
|
||||
{
|
||||
return ((1UL << (nr & (BITS_PER_LONG-1))) &
|
||||
(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
|
||||
}
|
||||
```
|
||||
|
||||
它生成了一个位号对应位为高位 `1`,而其他位为 `0` 的字节(正如我们在 `CONST_MASK` 所看到的),并将 [按位与](https://en.wikipedia.org/wiki/Bitwise_operation#AND) 应用于包含给定位号的字节。
|
||||
|
||||
下一个被广泛使用的位数组相关操作是改变一个位数组中的位。为此,Linux 内核提供了两个辅助函数:
|
||||
|
||||
* `__change_bit`;
|
||||
* `change_bit`.
|
||||
|
||||
你可能已经猜测到,就拿 `set_bit` 和 `__set_bit` 例子说,这两个变体分别是原子和非原子版本。首先,让我们看看 `__change_bit` 函数的实现:
|
||||
|
||||
```C
|
||||
static inline void __change_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
|
||||
}
|
||||
```
|
||||
|
||||
相当简单,不是吗? `__change_bit` 的实现和 `__set_bit` 一样,只是我们使用 [btc](http://x86.renejeschke.de/html/file_module_x86_id_23.html) 替换 `bts` 指令而已。 该指令从一个给定位数组中选出一个给定位,将该为位的值存进 `CF` 并使用求反操作改变它的值,因此值为 `1` 的位将变为 `0`,反之亦然:
|
||||
|
||||
```python
|
||||
>>> int(not 1)
|
||||
0
|
||||
>>> int(not 0)
|
||||
1
|
||||
```
|
||||
|
||||
`__change_bit` 的原子版本为 `change_bit` 函数:
|
||||
|
||||
```C
|
||||
static inline void change_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (IS_IMMEDIATE(nr)) {
|
||||
asm volatile(LOCK_PREFIX "xorb %1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" ((u8)CONST_MASK(nr)));
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX "btc %1,%0"
|
||||
: BITOP_ADDR(addr)
|
||||
: "Ir" (nr));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
它和 `set_bit` 函数很相似,但也存在两点不同。第一处差异为 `xor` 操作而不是 `or`。第二处差异为 `btc`( LCTT 译注:原文为 `bts`,为作者笔误) 而不是 `bts`。
|
||||
|
||||
目前,我们了解了最重要的体系特定的位数组操作,是时候看看一般的位图 API 了。
|
||||
|
||||
通用位操作
|
||||
================================================================================
|
||||
|
||||
除了 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 中体系特定的 API 外,Linux 内核提供了操作位数组的通用 API。正如我们本部分开头所了解的一样,我们可以在 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件和 [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c) 源文件中找到它。但在查看这些源文件之前,我们先看看 [include/linux/bitops.h](https://github.com/torvalds/linux/blob/master/include/linux/bitops.h) 头文件,其提供了一系列有用的宏,让我们看看它们当中一部分。
|
||||
|
||||
首先我们看看以下 4 个 宏:
|
||||
|
||||
* `for_each_set_bit`
|
||||
* `for_each_set_bit_from`
|
||||
* `for_each_clear_bit`
|
||||
* `for_each_clear_bit_from`
|
||||
|
||||
所有这些宏都提供了遍历位数组中某些位集合的迭代器。第一个宏迭代那些被置位的位。第二个宏也是一样,但它是从某一个确定的位开始。最后两个宏做的一样,但是迭代那些被清位的位。让我们看看 `for_each_set_bit` 宏:
|
||||
|
||||
```C
|
||||
#define for_each_set_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
```
|
||||
|
||||
正如我们所看到的,它使用了三个参数,并展开为一个循环,该循环从作为 `find_first_bit` 函数返回结果的第一个置位开始,到小于给定大小的最后一个置位为止。
|
||||
|
||||
除了这四个宏, [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 也提供了 `64-bit` 或 `32-bit` 变量循环的 API 等等。
|
||||
|
||||
下一个 [头文件](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 提供了操作位数组的 API。例如,它提供了以下两个函数:
|
||||
|
||||
* `bitmap_zero`;
|
||||
* `bitmap_fill`.
|
||||
|
||||
它们分别可以清除一个位数组和用 `1` 填充位数组。让我们看看 `bitmap_zero` 函数的实现:
|
||||
|
||||
```C
|
||||
static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = 0UL;
|
||||
else {
|
||||
unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
首先我们可以看到对 `nbits` 的检查。 `small_const_nbits` 是一个定义在同一个[头文件](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 的宏:
|
||||
|
||||
```C
|
||||
#define small_const_nbits(nbits) \
|
||||
(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
|
||||
```
|
||||
|
||||
正如我们可以看到的,它检查 `nbits` 是否为编译期已知常量,并且其值不超过 `BITS_PER_LONG` 或 `64`。如果位数目没有超过一个 `long` 变量的位数,我们可以仅仅设置为 0。在其他情况,我们需要计算有多少个需要填充位数组的 `long` 变量并且使用 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 进行填充。
|
||||
|
||||
`bitmap_fill` 函数的实现和 `biramp_zero` 函数很相似,除了我们需要在给定的位数组中填写 `0xff` 或 `0b11111111`:
|
||||
|
||||
```C
|
||||
static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
|
||||
{
|
||||
unsigned int nlongs = BITS_TO_LONGS(nbits);
|
||||
if (!small_const_nbits(nbits)) {
|
||||
unsigned int len = (nlongs - 1) * sizeof(unsigned long);
|
||||
memset(dst, 0xff, len);
|
||||
}
|
||||
dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
|
||||
}
|
||||
```
|
||||
|
||||
除了 `bitmap_fill` 和 `bitmap_zero`,[include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件也提供了和 `bitmap_zero` 很相似的 `bitmap_copy`,只是仅仅使用 [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) 而不是 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 这点差异而已。它也提供了位数组的按位操作,像 `bitmap_and`, `bitmap_or`, `bitamp_xor`等等。我们不会探讨这些函数的实现了,因为如果你理解了本部分的所有内容,这些函数的实现是很容易理解的。无论如何,如果你对这些函数是如何实现的感兴趣,你可以打开并研究 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件。
|
||||
|
||||
本部分到此为止。
|
||||
|
||||
链接
|
||||
================================================================================
|
||||
|
||||
* [bitmap](https://en.wikipedia.org/wiki/Bit_array)
|
||||
* [linked data structures](https://en.wikipedia.org/wiki/Linked_data_structure)
|
||||
* [tree data structures](https://en.wikipedia.org/wiki/Tree_%28data_structure%29)
|
||||
* [hot-plug](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt)
|
||||
* [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html)
|
||||
* [IRQs](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29)
|
||||
* [API](https://en.wikipedia.org/wiki/Application_programming_interface)
|
||||
* [atomic operations](https://en.wikipedia.org/wiki/Linearizability)
|
||||
* [xchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_328.html)
|
||||
* [cmpxchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_41.html)
|
||||
* [lock instruction](http://x86.renejeschke.de/html/file_module_x86_id_159.html)
|
||||
* [bts instruction](http://x86.renejeschke.de/html/file_module_x86_id_25.html)
|
||||
* [btr instruction](http://x86.renejeschke.de/html/file_module_x86_id_24.html)
|
||||
* [bt instruction](http://x86.renejeschke.de/html/file_module_x86_id_22.html)
|
||||
* [sbb instruction](http://x86.renejeschke.de/html/file_module_x86_id_286.html)
|
||||
* [btc instruction](http://x86.renejeschke.de/html/file_module_x86_id_23.html)
|
||||
* [man memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html)
|
||||
* [man memset](http://man7.org/linux/man-pages/man3/memset.3.html)
|
||||
* [CF](https://en.wikipedia.org/wiki/FLAGS_register)
|
||||
* [inline assembler](https://en.wikipedia.org/wiki/Inline_assembler)
|
||||
* [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection)
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: https://github.com/0xAX/linux-insides/blob/master/DataStructures/bitmap.md
|
||||
|
||||
作者:[0xAX][a]
|
||||
译者:[cposture](https://github.com/cposture)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://twitter.com/0xAX
|
66
published/201608/20160516 Scaling Collaboration in DevOps.md
Normal file
66
published/201608/20160516 Scaling Collaboration in DevOps.md
Normal file
@ -0,0 +1,66 @@
|
||||
DevOps 的弹性合作
|
||||
=================================
|
||||
|
||||
![](http://devops.com/wp-content/uploads/2016/05/ScalingCollaboration.jpg)
|
||||
|
||||
那些熟悉 DevOps 的人通常认为与其说 DevOps 是一种技术不如说是一种文化。在 DevOps 的有效实践上需要一些特定的工具和经验,但是 DevOps 成功的基础在于企业内如何做好[团队和个体协作][1],从而可以让事情更快、更高效而有效的完成。
|
||||
|
||||
大多数的 DevOps 平台和工具都是以可扩展性为设计理念的。DevOps 环境通常运行在云端,并且容易发生变化。对于DevOps 软件来说,支持实时伸缩以解决冲突和摩擦是重要的。这同样对于人的因素也是一样的,但弹性合作却是完全不同的。
|
||||
|
||||
跨企业协同是 DevOps 成功的关键。好的代码和开发最终需要形成产品才能给用户带来价值。公司所面临的挑战是如何做到无缝衔接和尽可能的提高速度及自动化水平,而不是牺牲质量或性能。企业如何才能流水线化代码的开发和部署,同时保持维护工作的明晰、可控和合规?
|
||||
|
||||
### 新兴趋势
|
||||
|
||||
首先,我先提供一些背景,分享一些 [451 Research][2] 在 DevOps 及其常规应用方面获取的数据。云、敏捷和Devops 的能力在今天是非常重要的,不管是理念还是现实。451 研究公司发现采用这些东西以及容器技术的企业在不断增多,包括在生产环境中的大量使用。
|
||||
|
||||
拥抱这些技术和方式有许多优点,比如提高灵活性和速度,降低成本,提高适应能力和可靠性,适应新的或新兴的应用。据 451 Research 称,团队也面临着一些障碍,包括缺乏熟悉其中所需的技能的人、这些新兴技术的不成熟、成本和安全问题等。
|
||||
|
||||
在 “[Voice of the Enterprise: SDI Q4 2015 survey][2]” 报告中,451 Research 发现超过一半的受访者(57.1%)考虑他们稍晚些再采用,甚至会最后才采用这些新技术。另一方面,近半受访者(48.3 %)认为自己是率先或早期的采用者。
|
||||
|
||||
这些普遍性的情绪也表现在对其他问题的调查中。当问起容器的执行情况时,50.3% 的人表示这根本不在他们的计划中。剩下 49.7% 的人则是在计划、试点或积极使用容器技术。近 2/3(65.1%)的人表示,他们用敏捷开发方式来开发应用,但是只有 39.6% 的人回应称他们正在积极拥抱 DevOps。然而,敏捷软件开发已经在行业内存在了多年,451 Research 注意到容器和 Devops 的采用率显著提升,这是一个新的趋势。
|
||||
|
||||
当被问及首要的三个 IT 痛点是什么,被提及最多的是成本或预算、人员不足和遗留软件问题。随着企业向云、DevOps、和容器等转型,这些问题都需要加以解决,以及如何规划技术和有效协作。
|
||||
|
||||
### 当前状况
|
||||
|
||||
软件行业正处于急剧变化之中,这很大程度是由 DevOps 所推动的,它使得软件开发变得越来越横跨整个业务高度集成。软件的开发变得不再闭门造车,而越来越体现协作和社交化的功能。
|
||||
|
||||
几年还是在小说和展板中的理念和方法迅速成熟,成为了今天推动价值的主流技术和框架。企业依靠如敏捷、精益、虚拟化、云计算、自动化和微服务等概念来简化开发,同时使工作更加有效和高效。
|
||||
|
||||
为了适应和发展,企业需要完成一系列的关键任务。当今面临的挑战是如何加快发展的同时降低成本。团队需要消除 IT 和其他业务之间存在的障碍,并在一个由技术驱动的竞争环境中提供更多有效的战略合作。
|
||||
|
||||
敏捷、云计算、DevOps 和容器在这个过程中起着重要的作用,而将它们连接在一起的是有效的合作。每一种技术和方法都提供了独特的优势,但真正的价值来自于团队作为一个整体能够进行规模协同,以及团队所使用的工具和平台。成功的 DevOps 的实现也需要开发和 IT 运营团队之外其他利益相关者的参与,包括安全、数据库、存储和业务队伍。
|
||||
|
||||
### 合作即平台
|
||||
|
||||
有一些在线的服务和平台,比如 Github 促进和增进了协作。这个在线平台的功能是一个在线代码库,但是所产生的价值远超乎存储代码。
|
||||
|
||||
这样一个[协作平台][4]之所以有助于开发人员和团队合作,是因为它提供了一个可以分享和讨论代码和流程的社区。管理者可以监视进度和跟踪将要发布的代码。开发人员在将实验性的想法放到实际的产品环境中之前,可以在一个安全的环境中进行实验,新的想法和实验可以有效地与适当的团队进行沟通。
|
||||
|
||||
更加敏捷的开发和 DevOps 的关键之一是允许开发人员测试一些东西并快速收集相关的反馈。目标是生产高质量的代码和功能,而不是浪费时间建立和管理基础设施或者安排更多的会议来讨论这个问题。比如 GitHub 平台,能够更有效的和可扩展的协作是因为当参与者想要进行代码审查时很方便。不需要尝试协调和安排代码审查会议,所以开发人员可以继续工作而不被打断,从而产生更大的生产力和工作满意度。
|
||||
|
||||
Sendachi 的 Steven Anderson 指出,Github 是一个协作平台,但它也是一个和你一起工作的工具。这样意味着它不仅可以帮助协作和持续集成,还影响了代码质量。
|
||||
|
||||
合作平台的好处之一是,大型团队的开发人员可以分解成更小的团队,可以更有效地专注于特定的组件。它还提供了诸如文件共享这样的代码之外的功能,模糊了技术和非技术的贡献,增加了协作和可见性。
|
||||
|
||||
### 合作是关键
|
||||
|
||||
合作的重要性不言而喻。合作是 DevOps 文化的关键,也是在当今世界能够进行敏捷开发并保持竞争优势的决定因素。执行或管理支持以及内部传道是很重要的。团队还需要拥抱文化的转变---迈向共同目标的跨职能部门的技能融合。
|
||||
|
||||
要建立起来这样的文化,有效的合作是至关重要的。一个合作平台是弹性合作的必要组件,因为简化了生产活动,并且减少了冗余和尝试,同时还产生了更高质量的结果。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://devops.com/2016/05/16/scaling-collaboration-devops/
|
||||
|
||||
作者:[TONY BRADLEY][a]
|
||||
译者:[Bestony](https://github.com/Bestony)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://devops.com/author/tonybsg/
|
||||
[1]: http://devops.com/2014/12/15/four-strategies-supporting-devops-collaboration/
|
||||
[2]: https://451research.com/
|
||||
[3]: https://451research.com/customer-insight-voice-of-the-enterprise-overview
|
||||
[4]: http://devops.com/events/analytics-of-collaboration-on-github/
|
267
published/201608/20160518 Python 3 - An Intro to Encryption.md
Normal file
267
published/201608/20160518 Python 3 - An Intro to Encryption.md
Normal file
@ -0,0 +1,267 @@
|
||||
Python 3: 加密简介
|
||||
===================================
|
||||
|
||||
Python 3 的标准库中没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto 和 cryptography 上。我们将学习如何使用这两个库,来加密和解密字符串。
|
||||
|
||||
### 哈希
|
||||
|
||||
如果需要用到安全哈希算法或是消息摘要算法,那么你可以使用标准库中的 **hashlib** 模块。这个模块包含了符合 FIPS(美国联邦信息处理标准)的安全哈希算法,包括 SHA1,SHA224,SHA256,SHA384,SHA512 以及 RSA 的 MD5 算法。Python 也支持 adler32 以及 crc32 哈希函数,不过它们在 **zlib** 模块中。
|
||||
|
||||
哈希的一个最常见的用法是,存储密码的哈希值而非密码本身。当然了,使用的哈希函数需要稳健一点,否则容易被破解。另一个常见的用法是,计算一个文件的哈希值,然后将这个文件和它的哈希值分别发送。接收到文件的人可以计算文件的哈希值,检验是否与接受到的哈希值相符。如果两者相符,就说明文件在传送的过程中未经篡改。
|
||||
|
||||
让我们试着创建一个 md5 哈希:
|
||||
|
||||
```
|
||||
>>> import hashlib
|
||||
>>> md5 = hashlib.md5()
|
||||
>>> md5.update('Python rocks!')
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#5>", line 1, in <module>
|
||||
md5.update('Python rocks!')
|
||||
TypeError: Unicode-objects must be encoded before hashing
|
||||
>>> md5.update(b'Python rocks!')
|
||||
>>> md5.digest()
|
||||
b'\x14\x82\xec\x1b#d\xf6N}\x16*+[\x16\xf4w'
|
||||
```
|
||||
|
||||
让我们花点时间一行一行来讲解。首先,我们导入 **hashlib** ,然后创建一个 md5 哈希对象的实例。接着,我们向这个实例中添加一个字符串后,却得到了报错信息。原来,计算 md5 哈希时,需要使用字节形式的字符串而非普通字符串。正确添加字符串后,我们调用它的 **digest** 函数来得到哈希值。如果你想要十六进制的哈希值,也可以用以下方法:
|
||||
|
||||
```
|
||||
>>> md5.hexdigest()
|
||||
'1482ec1b2364f64e7d162a2b5b16f477'
|
||||
```
|
||||
|
||||
实际上,有一种精简的方法来创建哈希,下面我们看一下用这种方法创建一个 sha1 哈希:
|
||||
|
||||
```
|
||||
>>> sha = hashlib.sha1(b'Hello Python').hexdigest()
|
||||
>>> sha
|
||||
'422fbfbc67fe17c86642c5eaaa48f8b670cbed1b'
|
||||
```
|
||||
|
||||
可以看到,我们可以同时创建一个哈希实例并且调用其 digest 函数。然后,我们打印出这个哈希值看一下。这里我使用 sha1 哈希函数作为例子,但它不是特别安全,读者可以随意尝试其他的哈希函数。
|
||||
|
||||
### 密钥导出
|
||||
|
||||
Python 的标准库对密钥导出支持较弱。实际上,hashlib 函数库提供的唯一方法就是 **pbkdf2_hmac** 函数。它是 PKCS#5 的基于口令的第二个密钥导出函数,并使用 HMAC 作为伪随机函数。因为它支持“加盐(salt)”和迭代操作,你可以使用类似的方法来哈希你的密码。例如,如果你打算使用 SHA-256 加密方法,你将需要至少 16 个字节的“盐”,以及最少 100000 次的迭代操作。
|
||||
|
||||
简单来说,“盐”就是随机的数据,被用来加入到哈希的过程中,以加大破解的难度。这基本可以保护你的密码免受字典和彩虹表(rainbow table)的攻击。
|
||||
|
||||
让我们看一个简单的例子:
|
||||
|
||||
```
|
||||
>>> import binascii
|
||||
>>> dk = hashlib.pbkdf2_hmac(hash_name='sha256',
|
||||
password=b'bad_password34',
|
||||
salt=b'bad_salt',
|
||||
iterations=100000)
|
||||
>>> binascii.hexlify(dk)
|
||||
b'6e97bad21f6200f9087036a71e7ca9fa01a59e1d697f7e0284cd7f9b897d7c02'
|
||||
```
|
||||
|
||||
这里,我们用 SHA256 对一个密码进行哈希,使用了一个糟糕的盐,但经过了 100000 次迭代操作。当然,SHA 实际上并不被推荐用来创建密码的密钥。你应该使用类似 **scrypt** 的算法来替代。另一个不错的选择是使用一个叫 **bcrypt** 的第三方库,它是被专门设计出来哈希密码的。
|
||||
|
||||
### PyCryptodome
|
||||
|
||||
PyCrypto 可能是 Python 中密码学方面最有名的第三方软件包。可惜的是,它的开发工作于 2012 年就已停止。其他人还在继续发布最新版本的 PyCrypto,如果你不介意使用第三方的二进制包,仍可以取得 Python 3.5 的相应版本。比如,我在 Github (https://github.com/sfbahr/PyCrypto-Wheels) 上找到了对应 Python 3.5 的 PyCrypto 二进制包。
|
||||
|
||||
幸运的是,有一个该项目的分支 PyCrytodome 取代了 PyCrypto 。为了在 Linux 上安装它,你可以使用以下 pip 命令:
|
||||
|
||||
```
|
||||
pip install pycryptodome
|
||||
```
|
||||
|
||||
在 Windows 系统上安装则稍有不同:
|
||||
|
||||
```
|
||||
pip install pycryptodomex
|
||||
```
|
||||
|
||||
如果你遇到了问题,可能是因为你没有安装正确的依赖包(LCTT 译注:如 python-devel),或者你的 Windows 系统需要一个编译器。如果你需要安装上的帮助或技术支持,可以访问 PyCryptodome 的[网站][1]。
|
||||
|
||||
还值得注意的是,PyCryptodome 在 PyCrypto 最后版本的基础上有很多改进。非常值得去访问它们的主页,看看有什么新的特性。
|
||||
|
||||
#### 加密字符串
|
||||
|
||||
访问了他们的主页之后,我们可以看一些例子。在第一个例子中,我们将使用 DES 算法来加密一个字符串:
|
||||
|
||||
```
|
||||
>>> from Crypto.Cipher import DES
|
||||
>>> key = 'abcdefgh'
|
||||
>>> def pad(text):
|
||||
while len(text) % 8 != 0:
|
||||
text += ' '
|
||||
return text
|
||||
>>> des = DES.new(key, DES.MODE_ECB)
|
||||
>>> text = 'Python rocks!'
|
||||
>>> padded_text = pad(text)
|
||||
>>> encrypted_text = des.encrypt(text)
|
||||
Traceback (most recent call last):
|
||||
File "<pyshell#35>", line 1, in <module>
|
||||
encrypted_text = des.encrypt(text)
|
||||
File "C:\Programs\Python\Python35-32\lib\site-packages\Crypto\Cipher\blockalgo.py", line 244, in encrypt
|
||||
return self._cipher.encrypt(plaintext)
|
||||
ValueError: Input strings must be a multiple of 8 in length
|
||||
>>> encrypted_text = des.encrypt(padded_text)
|
||||
>>> encrypted_text
|
||||
b'>\xfc\x1f\x16x\x87\xb2\x93\x0e\xfcH\x02\xd59VQ'
|
||||
```
|
||||
|
||||
这段代码稍有些复杂,让我们一点点来看。首先需要注意的是,DES 加密使用的密钥长度为 8 个字节,这也是我们将密钥变量设置为 8 个字符的原因。而我们需要加密的字符串的长度必须是 8 的倍数,所以我们创建了一个名为 **pad** 的函数,来给一个字符串末尾填充空格,直到它的长度是 8 的倍数。然后,我们创建了一个 DES 的实例,以及我们需要加密的文本。我们还创建了一个经过填充处理的文本。我们尝试着对未经填充处理的文本进行加密,啊欧,报了一个 ValueError 错误!我们需要对经过填充处理的文本进行加密,然后得到加密的字符串。(LCTT 译注:encrypt 函数的参数应为 byte 类型字符串,代码为:`encrypted_text = des.encrypt(padded_text.encode('utf-8'))`)
|
||||
|
||||
知道了如何加密,还要知道如何解密:
|
||||
|
||||
```
|
||||
>>> des.decrypt(encrypted_text)
|
||||
b'Python rocks! '
|
||||
```
|
||||
|
||||
幸运的是,解密非常容易,我们只需要调用 des 对象的 **decrypt** 方法就可以得到我们原来的 byte 类型字符串了。下一个任务是学习如何用 RSA 算法加密和解密一个文件。首先,我们需要创建一些 RSA 密钥。
|
||||
|
||||
#### 创建 RSA 密钥
|
||||
|
||||
如果你希望使用 RSA 算法加密数据,那么你需要拥有访问 RAS 公钥和私钥的权限,否则你需要生成一组自己的密钥对。在这个例子中,我们将生成自己的密钥对。创建 RSA 密钥非常容易,所以我们将在 Python 解释器中完成。
|
||||
|
||||
```
|
||||
>>> from Crypto.PublicKey import RSA
|
||||
>>> code = 'nooneknows'
|
||||
>>> key = RSA.generate(2048)
|
||||
>>> encrypted_key = key.exportKey(passphrase=code, pkcs=8,
|
||||
protection="scryptAndAES128-CBC")
|
||||
>>> with open('/path_to_private_key/my_private_rsa_key.bin', 'wb') as f:
|
||||
f.write(encrypted_key)
|
||||
>>> with open('/path_to_public_key/my_rsa_public.pem', 'wb') as f:
|
||||
f.write(key.publickey().exportKey())
|
||||
```
|
||||
|
||||
首先我们从 **Crypto.PublicKey** 包中导入 **RSA**,然后创建一个傻傻的密码。接着我们生成 2048 位的 RSA 密钥。现在我们到了关键的部分。为了生成私钥,我们需要调用 RSA 密钥实例的 **exportKey** 方法,然后传入密码,使用的 PKCS 标准,以及加密方案这三个参数。之后,我们把私钥写入磁盘的文件中。
|
||||
|
||||
接下来,我们通过 RSA 密钥实例的 **publickey** 方法创建我们的公钥。我们使用方法链调用 publickey 和 exportKey 方法生成公钥,同样将它写入磁盘上的文件。
|
||||
|
||||
#### 加密文件
|
||||
|
||||
有了私钥和公钥之后,我们就可以加密一些数据,并写入文件了。这里有个比较标准的例子:
|
||||
|
||||
```
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Random import get_random_bytes
|
||||
from Crypto.Cipher import AES, PKCS1_OAEP
|
||||
|
||||
with open('/path/to/encrypted_data.bin', 'wb') as out_file:
|
||||
recipient_key = RSA.import_key(
|
||||
open('/path_to_public_key/my_rsa_public.pem').read())
|
||||
session_key = get_random_bytes(16)
|
||||
|
||||
cipher_rsa = PKCS1_OAEP.new(recipient_key)
|
||||
out_file.write(cipher_rsa.encrypt(session_key))
|
||||
|
||||
cipher_aes = AES.new(session_key, AES.MODE_EAX)
|
||||
data = b'blah blah blah Python blah blah'
|
||||
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
|
||||
|
||||
out_file.write(cipher_aes.nonce)
|
||||
out_file.write(tag)
|
||||
out_file.write(ciphertext)
|
||||
```
|
||||
|
||||
代码的前三行导入 PyCryptodome 包。然后我们打开一个文件用于写入数据。接着我们导入公钥赋给一个变量,创建一个 16 字节的会话密钥。在这个例子中,我们将使用混合加密方法,即 PKCS#1 OAEP ,也就是最优非对称加密填充。这允许我们向文件中写入任意长度的数据。接着我们创建 AES 加密,要加密的数据,然后加密数据。我们将得到加密的文本和消息认证码。最后,我们将随机数,消息认证码和加密的文本写入文件。
|
||||
|
||||
顺便提一下,随机数通常是真随机或伪随机数,只是用来进行密码通信的。对于 AES 加密,其密钥长度最少是 16 个字节。随意用一个你喜欢的编辑器试着打开这个被加密的文件,你应该只能看到乱码。
|
||||
|
||||
现在让我们学习如何解密我们的数据。
|
||||
|
||||
```
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Cipher import AES, PKCS1_OAEP
|
||||
|
||||
code = 'nooneknows'
|
||||
|
||||
with open('/path/to/encrypted_data.bin', 'rb') as fobj:
|
||||
private_key = RSA.import_key(
|
||||
open('/path_to_private_key/my_rsa_key.pem').read(),
|
||||
passphrase=code)
|
||||
|
||||
enc_session_key, nonce, tag, ciphertext = [ fobj.read(x)
|
||||
for x in (private_key.size_in_bytes(),
|
||||
16, 16, -1) ]
|
||||
|
||||
cipher_rsa = PKCS1_OAEP.new(private_key)
|
||||
session_key = cipher_rsa.decrypt(enc_session_key)
|
||||
|
||||
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
|
||||
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
|
||||
|
||||
print(data)
|
||||
```
|
||||
|
||||
如果你认真看了上一个例子,这段代码应该很容易解析。在这里,我们先以二进制模式读取我们的加密文件,然后导入私钥。注意,当你导入私钥时,需要提供一个密码,否则会出现错误。然后,我们文件中读取数据,首先是加密的会话密钥,然后是 16 字节的随机数和 16 字节的消息认证码,最后是剩下的加密的数据。
|
||||
|
||||
接下来我们需要解密出会话密钥,重新创建 AES 密钥,然后解密出数据。
|
||||
|
||||
你还可以用 PyCryptodome 库做更多的事。不过我们要接着讨论在 Python 中还可以用什么来满足我们加密解密的需求。
|
||||
|
||||
### cryptography 包
|
||||
|
||||
**cryptography** 的目标是成为“人类易于使用的密码学包(cryptography for humans)”,就像 **requests** 是“人类易于使用的 HTTP 库(HTTP for Humans)”一样。这个想法使你能够创建简单安全、易于使用的加密方案。如果有需要的话,你也可以使用一些底层的密码学基元,但这也需要你知道更多的细节,否则创建的东西将是不安全的。
|
||||
|
||||
如果你使用的 Python 版本是 3.5, 你可以使用 pip 安装,如下:
|
||||
|
||||
```
|
||||
pip install cryptography
|
||||
```
|
||||
|
||||
你会看到 cryptography 包还安装了一些依赖包(LCTT 译注:如 libopenssl-devel)。如果安装都顺利,我们就可以试着加密一些文本了。让我们使用 **Fernet** 对称加密算法,它保证了你加密的任何信息在不知道密码的情况下不能被篡改或读取。Fernet 还通过 **MultiFernet** 支持密钥轮换。下面让我们看一个简单的例子:
|
||||
|
||||
```
|
||||
>>> from cryptography.fernet import Fernet
|
||||
>>> cipher_key = Fernet.generate_key()
|
||||
>>> cipher_key
|
||||
b'APM1JDVgT8WDGOWBgQv6EIhvxl4vDYvUnVdg-Vjdt0o='
|
||||
>>> cipher = Fernet(cipher_key)
|
||||
>>> text = b'My super secret message'
|
||||
>>> encrypted_text = cipher.encrypt(text)
|
||||
>>> encrypted_text
|
||||
(b'gAAAAABXOnV86aeUGADA6mTe9xEL92y_m0_TlC9vcqaF6NzHqRKkjEqh4d21PInEP3C9HuiUkS9f'
|
||||
b'6bdHsSlRiCNWbSkPuRd_62zfEv3eaZjJvLAm3omnya8=')
|
||||
>>> decrypted_text = cipher.decrypt(encrypted_text)
|
||||
>>> decrypted_text
|
||||
b'My super secret message'
|
||||
```
|
||||
|
||||
首先我们需要导入 Fernet,然后生成一个密钥。我们输出密钥看看它是什么样儿。如你所见,它是一个随机的字节串。如果你愿意的话,可以试着多运行 **generate_key** 方法几次,生成的密钥会是不同的。然后我们使用这个密钥生成 Fernet 密码实例。
|
||||
|
||||
现在我们有了用来加密和解密消息的密码。下一步是创建一个需要加密的消息,然后使用 **encrypt** 方法对它加密。我打印出加密的文本,然后你可以看到你再也读不懂它了。为了解密出我们的秘密消息,我们只需调用 **decrypt** 方法,并传入加密的文本作为参数。结果就是我们得到了消息字节串形式的纯文本。
|
||||
|
||||
|
||||
### 小结
|
||||
|
||||
这一章仅仅浅显地介绍了 PyCryptodome 和 cryptography 这两个包的使用。不过这也确实给了你一个关于如何加密解密字符串和文件的简述。请务必阅读文档,做做实验,看看还能做些什么!
|
||||
|
||||
---
|
||||
|
||||
### 相关阅读
|
||||
|
||||
[Github][2] 上 Python 3 的 PyCrypto Wheels
|
||||
|
||||
PyCryptodome 的 [文档][3]
|
||||
|
||||
Python’s 加密 [服务][4]
|
||||
|
||||
Cryptography 包的 [官网][5]
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.blog.pythonlibrary.org/2016/05/18/python-3-an-intro-to-encryption/
|
||||
|
||||
作者:[Mike][a]
|
||||
译者:[Cathon](https://github.com/Cathon)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.blog.pythonlibrary.org/author/mld/
|
||||
[1]: http://pycryptodome.readthedocs.io/en/latest/
|
||||
[2]: https://github.com/sfbahr/PyCrypto-Wheels
|
||||
[3]: http://pycryptodome.readthedocs.io/en/latest/src/introduction.html
|
||||
[4]: https://docs.python.org/3/library/crypto.html
|
||||
[5]: https://cryptography.io/en/latest/
|
@ -1,21 +1,19 @@
|
||||
Linux 平台下 Python 脚本编程入门 – Part 1
|
||||
Linux 平台下 Python 脚本编程入门(一)
|
||||
===============================================================================
|
||||
|
||||
|
||||
众所周知,系统管理员需要精通一门脚本语言,而且招聘机构列出的职位需求上也会这么写。大多数人会认为 Bash (或者其他的 shell 语言)用起来很方便,但一些强大的语言(比如 Python)会给你带来一些其它的好处。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Learn-Python-Programming-Scripting-in-Linux.png)
|
||||
> 在 Linux 中学习 Python 脚本编程
|
||||
|
||||
*在 Linux 中学习 Python 脚本编程*
|
||||
|
||||
首先,我们会使用 Python 的命令行工具,还会接触到 Python 的面向对象特性(这篇文章的后半部分会谈到它)。
|
||||
|
||||
最后,学习 Python
|
||||
可以助力于你在[桌面应用开发][2]及[数据科学领域][3]的事业。
|
||||
学习 Python 可以助力于你在[桌面应用开发][2]及[数据科学领域][3]的职业发展。
|
||||
|
||||
容易上手,广泛使用,拥有海量“开箱即用”的模块(它是一组包含 Python 声明的外部文件),Python 理所当然地成为了美国计算机专业大学生在一年级时所上的程序设计课所用语言的不二之选。
|
||||
容易上手,广泛使用,拥有海量“开箱即用”的模块(它是一组包含 Python 语句的外部文件),Python 理所当然地成为了美国计算机专业大学生在一年级时所上的程序设计课所用语言的不二之选。
|
||||
|
||||
在这个由两篇文章构成的系列中,我们将回顾 Python
|
||||
的基础部分,希望初学编程的你能够将这篇实用的文章作为一个编程入门的跳板,和日后使用 Python 时的一篇快速指引。
|
||||
在这个由两篇文章构成的系列中,我们将回顾 Python 的基础部分,希望初学编程的你能够将这篇实用的文章作为一个编程入门的跳板,和日后使用 Python 时的一篇快速指引。
|
||||
|
||||
### Linux 中的 Python
|
||||
|
||||
@ -33,7 +31,8 @@ $ python3
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Running-Python-Commands-on-Linux.png)
|
||||
> 在 Linux 中运行 Python 命令
|
||||
|
||||
*在 Linux 中运行 Python 命令*
|
||||
|
||||
如果你希望在键入 `python` 时使用 Python 3.x 而不是 2.x,你可以像下面一样更改对应的符号链接:
|
||||
|
||||
@ -44,11 +43,12 @@ $ ln -s python3.2 python # Choose the Python 3.x binary here
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Remove-Python-2-and-Use-Python-3.png)
|
||||
> 删除 Python 2,使用 Python 3
|
||||
|
||||
*删除 Python 2,使用 Python 3*
|
||||
|
||||
顺便一提,有一点需要注意:尽管 Python 2.x 仍旧被使用,但它并不会被积极维护。因此,你可能要考虑像上面指示的那样来切换到 3.x。2.x 和 3.x 的语法有一些不同,我们会在这个系列文章中使用后者。
|
||||
|
||||
另一个在 Linux 中使用 Python 的方法是通过 IDLE (the Python Integrated Development Environment),一个为编写 Python 代码而生的图形用户界面。在安装它之前,你最好查看一下适用于你的 Linux 发行版的 IDLE 可用版本。
|
||||
另一个在 Linux 中使用 Python 的方法是通过 IDLE (the Python Integrated Development Environment),这是一个为编写 Python 代码而生的图形用户界面。在安装它之前,你最好查看一下适用于你的 Linux 发行版的 IDLE 可用版本。
|
||||
|
||||
```
|
||||
# aptitude search idle [Debian 及其衍生发行版]
|
||||
@ -69,22 +69,23 @@ $ sudo aptitude install idle-python3.2 # I'm using Linux Mint 13
|
||||
1. 轻松打开外部文件 (File → Open);
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Python-Shell.png)
|
||||
> Python Shell
|
||||
|
||||
*Python Shell*
|
||||
|
||||
2. 复制 (`Ctrl + C`) 和粘贴 (`Ctrl + V`) 文本;
|
||||
3. 查找和替换文本;
|
||||
4. 显示可能的代码补全(一个在其他 IDE 里可能叫做 Intellisense 或者 Autocompletion 的功能);
|
||||
4. 显示可能的代码补全(一个在其他 IDE 里可能叫做“智能感知”或者“自动补完”的功能);
|
||||
5. 更改字体和字号,等等。
|
||||
|
||||
最厉害的是,你可以用 IDLE 创建桌面工程。
|
||||
最厉害的是,你可以用 IDLE 创建桌面应用。
|
||||
|
||||
我们在这两篇文章中不会开发桌面应用,所以你可以根据喜好来选择 IDLE 或 Python shell 去运行下面的例子。
|
||||
|
||||
### Python 中的基本运算
|
||||
|
||||
就像你预料的那样,你能够直接进行算术操作(你可以在所有操作中使用足够多的括号!),还可以轻松地使用 Python 拼接字符串。
|
||||
就像你预料的那样,你能够直接进行算术操作(你可以在你的所有运算中使用足够多的括号!),还可以轻松地使用 Python 拼接字符串。
|
||||
|
||||
你还可以将运算结果赋给一个变量,然后在屏幕上显示它。Python 有一个叫做输出 (concatenation) 的实用功能——把一串变量和/或字符串用逗号分隔,然后在 print 函数中插入,它会返回一个由你刚才提供的变量依序构成的句子:
|
||||
你还可以将运算结果赋给一个变量,然后在屏幕上显示它。Python 有一个叫做拼接 (concatenation) 的实用功能——给 print 函数提供一串用逗号分隔的变量和/或字符串,它会返回一个由你刚才提供的变量依序构成的句子:
|
||||
|
||||
```
|
||||
>>> a = 5
|
||||
@ -100,15 +101,16 @@ $ sudo aptitude install idle-python3.2 # I'm using Linux Mint 13
|
||||
如果你尝试在静态类型语言中(如 Java 或 C#)做这件事,它将抛出一个错误。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Learn-Python-Basic-Operations.png)
|
||||
> 学习 Python 的基本操作
|
||||
|
||||
*学习 Python 的基本操作*
|
||||
|
||||
### 面向对象编程的简单介绍
|
||||
|
||||
在面向对象编程(OOP)中,程序中的所有实体都会由对象的形式呈现,所以它们可以与其他对象交互。因此,对象拥有属性,而且大多数对象可以完成动作(这被称为对象的方法)。
|
||||
在面向对象编程(OOP)中,程序中的所有实体都会由对象的形式呈现,并且它们可以与其他对象交互。因此,对象拥有属性,而且大多数对象可以执行动作(这被称为对象的方法)。
|
||||
|
||||
举个例子:我们来想象一下,创建一个对象“狗”。它可能拥有的一些属性有`颜色`、`品种`、`年龄`等等,而它可以完成的动作有 `叫()`、`吃()`、`睡觉()`,诸如此类。
|
||||
|
||||
你可以看到,方法名后面会跟着一对括号,他们当中可能会包含一个或多个参数(向方法中传递的值),也有可能什么都不包含。
|
||||
你可以看到,方法名后面会跟着一对括号,括号当中可能会包含一个或多个参数(向方法中传递的值),也有可能什么都不包含。
|
||||
|
||||
我们用 Python 的基本对象类型之一——列表来解释这些概念。
|
||||
|
||||
@ -139,19 +141,21 @@ $ sudo aptitude install idle-python3.2 # I'm using Linux Mint 13
|
||||
>>> rockBands.pop(0)
|
||||
```
|
||||
|
||||
如果你输入了对象的名字,然后在后面输入了一个点,你可以按 Ctrl + 空格来显示这个对象的可用方法列表。
|
||||
如果你输入了对象的名字,然后在后面输入了一个点,你可以按 `Ctrl + space` 来显示这个对象的可用方法列表。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/List-Available-Python-Methods.png)
|
||||
> 列出可用的 Python 方法
|
||||
|
||||
*列出可用的 Python 方法*
|
||||
|
||||
列表中含有的元素个数是它的一个属性。它通常被叫做“长度”,你可以通过向内建函数 `len` 传递一个列表作为它的参数来显示该列表的长度(顺便一提,之前的例子中提到的 print 语句,是 Python 的另一个内建函数)。
|
||||
|
||||
如果你在 IDLE 中输入 `len`,然后跟上一个不闭合的括号,你会看到这个函数的默认语法:
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Python-len-Function.png)
|
||||
> Python 的 len 函数
|
||||
|
||||
现在我们来看看列表中的特定条目。他们也有属性和方法吗?答案是肯定的。比如,你可以将一个字符串条目装换为大写形式,并获取这个字符串所包含的字符数量。像下面这样做:
|
||||
*Python 的 len 函数*
|
||||
|
||||
现在我们来看看列表中的特定条目。它们也有属性和方法吗?答案是肯定的。比如,你可以将一个字符串条目转换为大写形式,并获取这个字符串所包含的字符数量。像下面这样做:
|
||||
|
||||
```
|
||||
>>> rockBands[0].upper()
|
||||
@ -162,11 +166,11 @@ $ sudo aptitude install idle-python3.2 # I'm using Linux Mint 13
|
||||
|
||||
### 总结
|
||||
|
||||
在这篇文章中,我们简要介绍了 Python,它的命令行 shell,IDLE,展示了如何执行算术运算,如何在变量中存储数据,如何使用 `print` 函数在屏幕上重新显示那些数据(无论是它们本身还是它们的一部分),还通过一个实际的例子解释了对象的属性和方法。
|
||||
在这篇文章中,我们简要介绍了 Python、它的命令行 shell、IDLE,展示了如何执行算术运算,如何在变量中存储数据,如何使用 `print` 函数在屏幕上重新显示那些数据(无论是它们本身还是它们的一部分),还通过一个实际的例子解释了对象的属性和方法。
|
||||
|
||||
下一篇文章中,我们会展示如何使用条件语句和循环语句来实现流程控制。我们也会解释如何编写一个脚本来帮助我们完成系统管理任务。
|
||||
|
||||
你是不是想继续学习一些有关 Python 的知识呢?敬请期待本系列的第二部分(我们会将 Python 的慷慨、脚本中的命令行工具与其他部分结合在一起),你还可以考虑购买我们的《终极 Python 编程》系列教程([这里][4]有详细信息)。
|
||||
你是不是想继续学习一些有关 Python 的知识呢?敬请期待本系列的第二部分(我们会在脚本中将 Python 和命令行工具的优点结合在一起),你还可以考虑购买我们的《终极 Python 编程》系列教程([这里][4]有详细信息)。
|
||||
|
||||
像往常一样,如果你对这篇文章有什么问题,可以向我们寻求帮助。你可以使用下面的联系表单向我们发送留言,我们会尽快回复你。
|
||||
|
||||
@ -176,7 +180,7 @@ via: http://www.tecmint.com/learn-python-programming-and-scripting-in-linux/
|
||||
|
||||
作者:[Gabriel Cánepa][a]
|
||||
译者:[StdioA](https://github.com/StdioA)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
54
published/201608/20160531 The Anatomy of a Linux User.md
Normal file
54
published/201608/20160531 The Anatomy of a Linux User.md
Normal file
@ -0,0 +1,54 @@
|
||||
深入理解 Linux 用戶
|
||||
================================
|
||||
|
||||
**一些新的 GNU/Linux 用户很清楚 Linux 不是 Windows,但其他人对此则不甚了解,而最好的发行版设计者们则会谨记着这两种人的存在。**
|
||||
|
||||
### Linux 的核心
|
||||
|
||||
不管怎么说,Nicky 看起来都不太引人注目。她已经三十岁了,却决定在离开学校多年后回到学校学习。她在海军待了六年,后来接受了一份老友给她的新工作,想试试这份工作会不会比她在军队的工作更有前途。这种换工作的事情在战后的军事后勤处非常常见。我正是因此而认识的她。她那时是一个八个州的货车运输业中介组织的区域经理,而那会我在达拉斯跑肉品包装工具的运输。
|
||||
|
||||
![](http://i2.wp.com/fossforce.com/wp-content/uploads/2016/05/anatomy.jpg?w=525)
|
||||
|
||||
Nicky 和我在 2006 年成为了好朋友。她很外向,几乎每一个途经她负责的线路上的人她都乐于接触。我们经常星期五晚上相约去一家室内激光枪战中心打真人 CS。像这样一次就打三个的半小时战役对我们来说并不鲜见。或许这并不像彩弹游戏(LCTT 译注:一种军事游戏,双方以汽枪互射彩色染料弹丸,对方被击中后衣服上会留下彩色印渍即表示“被消灭”——必应词典)一样便宜,但是它很有临场感,还稍微有点恐怖游戏的感觉。某次活动的时候,她问我能否帮她维修电脑。
|
||||
|
||||
她知道我在为了让一些贫穷的孩子能拥有他们自己的电脑而奔走,当她抱怨她的电脑很慢的时候,我开玩笑地说她可以给比尔盖茨的 401k 计划交钱了(LCTT 译注:401k 计划始于20世纪80年代初,是一种由雇员、雇主共同缴费建立起来的完全基金式的养老保险制度。此处隐喻需要购买新电脑而向比尔盖茨的微软公司付费软件费用。)。Nicky 却说这是了解 Linux 的最佳时间。
|
||||
|
||||
她的电脑是品牌机,是个带有 Dell 19'' 显示器的 2005 年中款的华硕电脑。不幸的是,这台电脑没有好好照料,上面充斥着所能找到的各种关都关不掉的工具栏和弹窗软件。我们把电脑上的文件都做了备份之后就开始安装 Linux 了。我们一起完成了安装,并且确信她知道了如何分区。不到一个小时,她的电脑上就有了一个“金闪闪”的 PCLinuxOS 桌面。
|
||||
|
||||
在她操作新系统时,她经常评论这个系统看起来多么漂亮。她并非随口一说;她为眼前光鲜亮丽的桌面着了魔。她说她的桌面漂亮的就像化了“彩妆”一样。这是我在安装系统期间特意设置的,我每次安装 Linux 的时候都会把它打扮的漂漂亮亮的。我希望这些桌面让每个人看起来都觉得漂亮。
|
||||
|
||||
大概第一周左右,她通过电话和邮件问了我一些常规问题,而最主要的问题还是她想知道如何保存她 OpenOffice 文件才可以让她的同事也可以打开这些文件。教一个人使用 Linux 或者 Open/LibreOffice 的时候最重要的就是教她保存文件。大多数用户在弹出的对话框中直接点了保存,结果就用默认的开放文档格式(Open Document Format)保存了,这让他们吃了不少苦头。
|
||||
|
||||
曾经有过这么一件事,大约一年前或者更久,一个高中生说他没有通过期末考试,因为教授不能打开包含他的论文的文件。这引来了一些读者的激烈评论,大家都不知道这件事该怪谁,这孩子没错,而他的教授,似乎也没错。
|
||||
|
||||
我认识的一些大学教授他们每一个人都知道怎么打开 ODF 文件。另外,那个该死的微软在这方面做得真 XX 的不错,我觉得微软 Office 现在已经能打开 ODT 或者 ODF 文件了。不过我也不确定,毕竟我从 2005 年就没用过 Microsoft Office 了。
|
||||
|
||||
甚至在过去糟糕的日子里,微软公开而悍然地通过产品绑架的方式来在企业桌面领域推行他们的软件时,我和一些微软 Office 的用户在开展业务和洽谈合作时从来没有出现过问题,因为我会提前想到可能出现的问题并且不会有侥幸心理。我会发邮件给他们询问他们正在使用的 Office 版本。这样,我就可以确保以他们能够读写的格式保存文件。
|
||||
|
||||
说回 Nicky ,她花了很多时间学习她的 Linux 系统。我很惊奇于她的热情。
|
||||
|
||||
当人们意识到需要抛弃所有的 Windows 的使用习惯和工具的时候,学习 Linux 系统就会很容易。甚至在告诉那些淘气的孩子们如何使用之后,再次回来检查的时候,他们都不会试图把 .exe 文件下载到桌面上或某个下载文件夹。
|
||||
|
||||
在我们通常讨论这些文件的时候,我们也会提及关于更新的问题。长久以来我一直反对在一台机器上有多个软件安装系统和更新管理软件。以 Mint 来说,它完全禁用了 Synaptic 中的更新功能,这让我失去兴趣。但是即便对于我们这些仍然在使用 dpkg 和 apt 的老家伙们来说,睿智的脑袋也已经开始意识到命令行对新用户来说并不那么温馨而友好。
|
||||
|
||||
我曾严正抗议并强烈谴责 Synaptic 功能上的削弱,直到它说服了我。你记得什么时候第一次使用的新打造的 Linux 发行版,并拥有了最高管理权限吗? 你记得什么时候对 Synaptic 中列出的大量软件进行过梳理吗?你记得怎样开始安装每个你发现的很酷的程序吗?你记得有多少这样的程序都是以字母"lib"开头的吗?
|
||||
|
||||
我也曾做过那样的事。我安装又弄坏了好几次 Linux,后来我才发现那些库(lib)文件是应用程序的螺母和螺栓,而不是应用程序本身。这就是 Linux Mint 和 Ubuntu 幕后那些聪明的开发者创造了智能、漂亮和易用的应用安装器的原因。Synaptic 仍然是我们这些老玩家爱用的工具,但是对于那些在我们之后才来的新手来说,有太多的方式可以让他们安装库文件和其他类似的包。在新的安装程序中,这些文件的显示会被折叠起来,不会展示给用户。真的,这才是它应该做的。
|
||||
|
||||
除非你要准备好了打很多支持电话。
|
||||
|
||||
现在的 Linux 发行版中藏了很多智慧的结晶,我也很感谢这些开发者们,因为他们,我的工作变得更容易。不是每一个 Linux 新用户都像 Nicky 这样富有学习能力和热情。她对我来说就是一个“装好就行”的项目,只需要为她解答一些问题,其它的她会自己研究解决。像她这样极具学习能力和热情的用户的毕竟是少数。这样的 Linux 新人任何时候都是珍稀物种。
|
||||
|
||||
很不错,他们都是要教自己的孩子使用 Linux 的人。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://fossforce.com/2016/05/anatomy-linux-user/
|
||||
|
||||
作者:[Ken Starks][a]
|
||||
译者:[vim-kakali](https://github.com/vim-kakali)
|
||||
校对:[PurlingNayuki](https://github.com/PurlingNayuki), [wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://linuxlock.blogspot.com/
|
@ -0,0 +1,292 @@
|
||||
Linux 平台下 Python 脚本编程入门(二)
|
||||
======================================================================================
|
||||
|
||||
在“[Linux 平台下 Python 脚本编程入门][1]”系列之前的文章里,我们向你介绍了 Python 的简介,它的命令行 shell 和 IDLE(LCTT 译注:python 自带的一个 IDE)。我们也演示了如何进行算术运算、如何在变量中存储值、还有如何打印那些值到屏幕上。最后,我们通过一个练习示例讲解了面向对象编程中方法和属性概念。
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/06/Write-Shell-Scripts-in-Python-Programming.png)
|
||||
|
||||
*在 Python 编程中写 Linux Shell 脚本*
|
||||
|
||||
本篇中,我们会讨论控制流(根据用户输入的信息、计算的结果,或者一个变量的当前值选择不同的动作行为)和循环(自动重复执行任务),接着应用我们目前所学东西来编写一个简单的 shell 脚本,这个脚本会显示操作系统类型、主机名、内核版本、版本号和机器硬件架构。
|
||||
|
||||
这个例子尽管很基础,但是会帮助我们证明,比起使用一般的 bash 工具,我们通过发挥 Python 面向对象的特性来编写 shell 脚本会更简单些。
|
||||
|
||||
换句话说,我们想从这里出发:
|
||||
|
||||
```
|
||||
# uname -snrvm
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-Hostname-of-Linux.png)
|
||||
|
||||
*检查 Linux 的主机名*
|
||||
|
||||
到
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Check-Linux-Hostname-Using-Python-Script.png)
|
||||
|
||||
*用 Python 脚本来检查 Linux 的主机名*
|
||||
|
||||
或者
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Script-to-Check-Linux-System-Information.png)
|
||||
|
||||
*用脚本检查 Linux 系统信息*
|
||||
|
||||
看着不错,不是吗?那我们就挽起袖子,开干吧。
|
||||
|
||||
### Python 中的控制流
|
||||
|
||||
如我们刚说那样,控制流允许我们根据一个给定的条件,选择不同的输出结果。在 Python 中最简单的实现就是一个 `if`/`else` 语句。
|
||||
|
||||
基本语法是这样的:
|
||||
|
||||
```
|
||||
if 条件:
|
||||
# 动作 1
|
||||
else:
|
||||
# 动作 2
|
||||
```
|
||||
|
||||
当“条件”求值为真(true),下面的代码块就会被执行(`# 动作 1`代表的部分)。否则,else 下面的代码就会运行。
|
||||
“条件”可以是任何表达式,只要可以求得值为真或者假。
|
||||
|
||||
举个例子:
|
||||
|
||||
1. `1 < 3` # 真
|
||||
2. `firstName == "Gabriel"` # 对 firstName 为 Gabriel 的人是真,对其他不叫 Gabriel 的人为假
|
||||
|
||||
- 在第一个例子中,我们比较了两个值,判断 1 是否小于 3。
|
||||
- 在第二个例子中,我们比较了 firstName(一个变量)与字符串 “Gabriel”,看在当前执行的位置,firstName 的值是否等于该字符串。
|
||||
- 条件和 else 表达式都必须跟着一个冒号(`:`)。
|
||||
- **缩进在 Python 中非常重要**。同样缩进下的行被认为是相同的代码块。
|
||||
|
||||
请注意,`if`/`else` 表达式只是 Python 中许多控制流工具的一个而已。我们先在这里了解以下,后面会用在我们的脚本中。你可以在[官方文档][2]中学到更多工具。
|
||||
|
||||
### Python 中的循环
|
||||
|
||||
简单来说,一个循环就是一组指令或者表达式序列,可以按顺序一直执行,只要条件为真,或者对列表里每个项目执行一一次。
|
||||
|
||||
Python 中最简单的循环,就是用 for 循环迭代一个给定列表的元素,或者对一个字符串从第一个字符开始到执行到最后一个字符结束。
|
||||
|
||||
基本语句:
|
||||
|
||||
```
|
||||
for x in example:
|
||||
# do this
|
||||
```
|
||||
|
||||
这里的 example 可以是一个列表或者一个字符串。如果是列表,变量 x 就代表列表中每个元素;如果是字符串,x 就代表字符串中每个字符。
|
||||
|
||||
```
|
||||
>>> rockBands = []
|
||||
>>> rockBands.append("Roxette")
|
||||
>>> rockBands.append("Guns N' Roses")
|
||||
>>> rockBands.append("U2")
|
||||
>>> for x in rockBands:
|
||||
print(x)
|
||||
或
|
||||
>>> firstName = "Gabriel"
|
||||
>>> for x in firstName:
|
||||
print(x)
|
||||
```
|
||||
|
||||
上面例子的输出如下图所示:
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Learn-Loops-in-Python.png)
|
||||
|
||||
*学习 Python 中的循环*
|
||||
|
||||
### Python 模块
|
||||
|
||||
很明显,必须有个办法将一系列的 Python 指令和表达式保存到文件里,然后在需要的时候取出来。
|
||||
|
||||
准确来说模块就是这样的。比如,os 模块提供了一个到操作系统的底层的接口,可以允许我们做许多通常在命令行下执行的操作。
|
||||
|
||||
没错,os 模块包含了许多可以用来调用的方法和属性,就如我们之前文章里讲解的那样。不过,我们需要使用 `import` 关键词导入(或者叫包含)模块到运行环境里来:
|
||||
|
||||
```
|
||||
>>> import os
|
||||
```
|
||||
|
||||
我们来打印出当前的工作目录:
|
||||
|
||||
```
|
||||
>>> os.getcwd()
|
||||
```
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Learn-Python-Modules.png)
|
||||
|
||||
*学习 Python 模块*
|
||||
|
||||
现在,让我们把这些结合在一起(包括之前文章里讨论的概念),编写需要的脚本。
|
||||
|
||||
### Python 脚本
|
||||
|
||||
以一段声明文字开始一个脚本是个不错的想法,它可以表明脚本的目的、发布所依据的许可证,以及一个列出做出的修改的修订历史。尽管这主要是个人喜好,但这会让我们的工作看起来比较专业。
|
||||
|
||||
这里有个脚本,可以输出这篇文章最前面展示的那样。脚本做了大量的注释,可以让大家可以理解发生了什么。
|
||||
|
||||
在进行下一步之前,花点时间来理解它。注意,我们是如何使用一个 `if`/`else` 结构,判断每个字段标题的长度是否比字段本身的值还大。
|
||||
|
||||
基于比较结果,我们用空字符去填充一个字段标题和下一个之间的空格。同时,我们使用一定数量的短线作为字段标题与其值之间的分割符。
|
||||
|
||||
```
|
||||
#!/usr/bin/python3
|
||||
# 如果你没有安装 Python 3 ,那么修改这一行为 #!/usr/bin/python
|
||||
|
||||
# Script name: uname.py
|
||||
# Purpose: Illustrate Python's OOP capabilities to write shell scripts more easily
|
||||
# License: GPL v3 (http://www.gnu.org/licenses/gpl.html)
|
||||
|
||||
# Copyright (C) 2016 Gabriel Alejandro Cánepa
|
||||
# Facebook / Skype / G+ / Twitter / Github: gacanepa
|
||||
# Email: gacanepa (at) gmail (dot) com
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see .
|
||||
|
||||
# REVISION HISTORY
|
||||
# DATE VERSION AUTHOR CHANGE DESCRIPTION
|
||||
# ---------- ------- --------------
|
||||
# 2016-05-28 1.0 Gabriel Cánepa Initial version
|
||||
|
||||
### 导入 os 模块
|
||||
import os
|
||||
|
||||
### 将 os.uname() 的输出赋值给 systemInfo 变量
|
||||
### os.uname() 会返回五个字符串元组(sysname, nodename, release, version, machine)
|
||||
### 参见文档:https://docs.python.org/3.2/library/os.html#module-os
|
||||
systemInfo = os.uname()
|
||||
|
||||
### 这是一个固定的数组,用于描述脚本输出的字段标题
|
||||
headers = ["Operating system","Hostname","Release","Version","Machine"]
|
||||
|
||||
### 初始化索引值,用于定义每一步迭代中
|
||||
### systemInfo 和字段标题的索引
|
||||
index = 0
|
||||
|
||||
### 字段标题变量的初始值
|
||||
caption = ""
|
||||
|
||||
### 值变量的初始值
|
||||
values = ""
|
||||
|
||||
### 分隔线变量的初始值
|
||||
separators = ""
|
||||
|
||||
### 开始循环
|
||||
for item in systemInfo:
|
||||
if len(item) < len(headers[index]):
|
||||
### 一个包含横线的字符串,横线长度等于item[index] 或 headers[index]
|
||||
### 要重复一个字符,用引号圈起来并用星号(*)乘以所需的重复次数
|
||||
separators = separators + "-" * len(headers[index]) + " "
|
||||
caption = caption + headers[index] + " "
|
||||
values = values + systemInfo[index] + " " * (len(headers[index]) - len(item)) + " "
|
||||
else:
|
||||
separators = separators + "-" * len(item) + " "
|
||||
caption = caption + headers[index] + " " * (len(item) - len(headers[index]) + 1)
|
||||
values = values + item + " "
|
||||
### 索引加 1
|
||||
index = index + 1
|
||||
### 终止循环
|
||||
|
||||
### 输出转换为大写的变量(字段标题)名
|
||||
print(caption.upper())
|
||||
|
||||
### 输出分隔线
|
||||
print(separators)
|
||||
|
||||
# 输出值(systemInfo 中的项目)
|
||||
print(values)
|
||||
|
||||
### 步骤:
|
||||
### 1) 保持该脚本为 uname.py (或任何你想要的名字)
|
||||
### 并通过如下命令给其执行权限:
|
||||
### chmod +x uname.py
|
||||
### 2) 执行它;
|
||||
### ./uname.py
|
||||
```
|
||||
|
||||
如果你已经按照上述描述将上面的脚本保存到一个文件里,并给文件增加了执行权限,那么运行它:
|
||||
|
||||
```
|
||||
# chmod +x uname.py
|
||||
# ./uname.py
|
||||
```
|
||||
|
||||
如果试图运行脚本时你得到了如下的错误:
|
||||
|
||||
```
|
||||
-bash: ./uname.py: /usr/bin/python3: bad interpreter: No such file or directory
|
||||
```
|
||||
|
||||
这意味着你没有安装 Python3。如果那样的话,你要么安装 Python3 的包,要么替换解释器那行(如果如之前文章里概述的那样,跟着下面的步骤去更新 Python 执行文件的软连接,要特别注意并且非常小心):
|
||||
|
||||
```
|
||||
#!/usr/bin/python3
|
||||
```
|
||||
|
||||
为
|
||||
|
||||
```
|
||||
#!/usr/bin/python
|
||||
```
|
||||
|
||||
这样会通过使用已经安装好的 Python 2 去执行该脚本。
|
||||
|
||||
**注意**:该脚本在 Python 2.x 与 Pyton 3.x 上都测试成功过了。
|
||||
|
||||
尽管比较粗糙,你可以认为该脚本就是一个 Python 模块。这意味着你可以在 IDLE 中打开它(File → Open… → Select file):
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Open-Python-in-IDLE.png)
|
||||
|
||||
*在 IDLE 中打开 Python*
|
||||
|
||||
一个包含有文件内容的新窗口就会打开。然后执行 Run → Run module(或者按 F5)。脚本的输出就会在原始的 Shell 里显示出来:
|
||||
|
||||
![](http://www.tecmint.com/wp-content/uploads/2016/05/Run-Python-Script.png)
|
||||
|
||||
*执行 Python 脚本*
|
||||
|
||||
如果你想纯粹用 bash 写一个脚本,也获得同样的结果,你可能需要结合使用 [awk][3]、[sed][4],并且借助复杂的方法来存储与获得列表中的元素(不要忘了使用 tr 命令将小写字母转为大写)。
|
||||
|
||||
另外,在所有的 Linux 系统版本中都至少集成了一个 Python 版本(2.x 或者 3.x,或者两者都有)。你还需要依赖 shell 去完成同样的目标吗?那样你可能需要为不同的 shell 编写不同的版本。
|
||||
|
||||
这里演示了面向对象编程的特性,它会成为一个系统管理员得力的助手。
|
||||
|
||||
**注意**:你可以在我的 Github 仓库里获得 [这个 python 脚本][5](或者其他的)。
|
||||
|
||||
### 总结
|
||||
|
||||
这篇文章里,我们讲解了 Python 中控制流、循环/迭代、和模块的概念。我们也演示了如何利用 Python 中面向对象编程的方法和属性来简化复杂的 shell 脚本。
|
||||
|
||||
你有任何其他希望去验证的想法吗?开始吧,写出自己的 Python 脚本,如果有任何问题可以咨询我们。不必犹豫,在分割线下面留下评论,我们会尽快回复你。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.tecmint.com/learn-python-programming-to-write-linux-shell-scripts/
|
||||
|
||||
作者:[Gabriel Cánepa][a]
|
||||
译者:[wi-cuckoo](https://github.com/wi-cuckoo)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.tecmint.com/author/gacanepa/
|
||||
[1]: http://www.tecmint.com/learn-python-programming-and-scripting-in-linux/
|
||||
[2]: http://please%20note%20that%20the%20if%20/%20else%20statement%20is%20only%20one%20of%20the%20many%20control%20flow%20tools%20available%20in%20Python.%20We%20reviewed%20it%20here%20since%20we%20will%20use%20it%20in%20our%20script%20later.%20You%20can%20learn%20more%20about%20the%20rest%20of%20the%20tools%20in%20the%20official%20docs.
|
||||
[3]: http://www.tecmint.com/use-linux-awk-command-to-filter-text-string-in-files/
|
||||
[4]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
|
||||
[5]: https://github.com/gacanepa/scripts/blob/master/python/uname.py
|
||||
|
@ -0,0 +1,392 @@
|
||||
如何用 Python 和 Flask 建立部署一个 Facebook Messenger 机器人
|
||||
==========================================================================
|
||||
|
||||
这是我建立一个简单的 Facebook Messenger 机器人的记录。功能很简单,它是一个回显机器人,只是打印回用户写了什么。
|
||||
|
||||
回显服务器类似于服务器的“Hello World”例子。
|
||||
|
||||
这个项目的目的不是建立最好的 Messenger 机器人,而是让你了解如何建立一个小型机器人和每个事物是如何整合起来的。
|
||||
|
||||
- [技术栈][1]
|
||||
- [机器人架构][2]
|
||||
- [机器人服务器][3]
|
||||
- [部署到 Heroku][4]
|
||||
- [创建 Facebook 应用][5]
|
||||
- [结论][6]
|
||||
|
||||
### 技术栈
|
||||
|
||||
使用到的技术栈:
|
||||
|
||||
- [Heroku][7] 做后端主机。免费级足够这个等级的教程。回显机器人不需要任何种类的数据持久,所以不需要数据库。
|
||||
- [Python][8] 是我们选择的语言。版本选择 2.7,虽然它移植到 Pyhton 3 很容易,只需要很少的改动。
|
||||
- [Flask][9] 作为网站开发框架。它是非常轻量的框架,用在小型工程或微服务是非常完美的。
|
||||
- 最后 [Git][10] 版本控制系统用来维护代码和部署到 Heroku。
|
||||
- 值得一提:[Virtualenv][11]。这个 python 工具是用来创建清洁的 python 库“环境”的,这样你可以只安装必要的需求和最小化应用的大小。
|
||||
|
||||
### 机器人架构
|
||||
|
||||
Messenger 机器人是由一个响应两种请求的服务器组成的:
|
||||
|
||||
- GET 请求被用来认证。他们与你注册的 FaceBook 认证码一同被 Messenger 发出。
|
||||
- POST 请求被用来实际的通信。典型的工作流是,机器人将通过用户发送带有消息数据的 POST 请求而建立通信,然后我们将处理这些数据,并发回我们的 POST 请求。如果这个请求完全成功(返回一个 200 OK 状态码),我们也将响应一个 200 OK 状态码给初始的 Messenger请求。
|
||||
|
||||
这个教程应用将托管到 Heroku,它提供了一个优雅而简单的部署应用的接口。如前所述,免费级可以满足这个教程。
|
||||
|
||||
在应用已经部署并且运行后,我们将创建一个 Facebook 应用然后连接它到我们的应用,以便 Messenger 知道发送请求到哪,这就是我们的机器人。
|
||||
|
||||
### 机器人服务器
|
||||
|
||||
基本的服务器代码可以在 Github 用户 [hult(Magnus Hult)][13] 的 [Chatbot][12] 项目上获取,做了一些只回显消息的代码修改和修正了一些我遇到的错误。最终版本的服务器代码如下:
|
||||
|
||||
```
|
||||
from flask import Flask, request
|
||||
import json
|
||||
import requests
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
### 这需要填写被授予的页面通行令牌(PAT)
|
||||
### 它由将要创建的 Facebook 应用提供。
|
||||
PAT = ''
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def handle_verification():
|
||||
print "Handling Verification."
|
||||
if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me':
|
||||
print "Verification successful!"
|
||||
return request.args.get('hub.challenge', '')
|
||||
else:
|
||||
print "Verification failed!"
|
||||
return 'Error, wrong validation token'
|
||||
|
||||
@app.route('/', methods=['POST'])
|
||||
def handle_messages():
|
||||
print "Handling Messages"
|
||||
payload = request.get_data()
|
||||
print payload
|
||||
for sender, message in messaging_events(payload):
|
||||
print "Incoming from %s: %s" % (sender, message)
|
||||
send_message(PAT, sender, message)
|
||||
return "ok"
|
||||
|
||||
def messaging_events(payload):
|
||||
"""Generate tuples of (sender_id, message_text) from the
|
||||
provided payload.
|
||||
"""
|
||||
data = json.loads(payload)
|
||||
messaging_events = data["entry"][0]["messaging"]
|
||||
for event in messaging_events:
|
||||
if "message" in event and "text" in event["message"]:
|
||||
yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape')
|
||||
else:
|
||||
yield event["sender"]["id"], "I can't echo this"
|
||||
|
||||
|
||||
def send_message(token, recipient, text):
|
||||
"""Send the message text to recipient with id recipient.
|
||||
"""
|
||||
|
||||
r = requests.post("https://graph.facebook.com/v2.6/me/messages",
|
||||
params={"access_token": token},
|
||||
data=json.dumps({
|
||||
"recipient": {"id": recipient},
|
||||
"message": {"text": text.decode('unicode_escape')}
|
||||
}),
|
||||
headers={'Content-type': 'application/json'})
|
||||
if r.status_code != requests.codes.ok:
|
||||
print r.text
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
```
|
||||
|
||||
让我们分解代码。第一部分是引入所需的依赖:
|
||||
|
||||
```
|
||||
from flask import Flask, request
|
||||
import json
|
||||
import requests
|
||||
```
|
||||
|
||||
接下来我们定义两个函数(使用 Flask 特定的 app.route 装饰器),用来处理到我们的机器人的 GET 和 POST 请求。
|
||||
|
||||
```
|
||||
@app.route('/', methods=['GET'])
|
||||
def handle_verification():
|
||||
print "Handling Verification."
|
||||
if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me':
|
||||
print "Verification successful!"
|
||||
return request.args.get('hub.challenge', '')
|
||||
else:
|
||||
print "Verification failed!"
|
||||
return 'Error, wrong validation token'
|
||||
```
|
||||
|
||||
当我们创建 Facebook 应用时,verify_token 对象将由我们声明的 Messenger 发送。我们必须自己来校验它。最后我们返回“hub.challenge”给 Messenger。
|
||||
|
||||
处理 POST 请求的函数更有意思一些:
|
||||
|
||||
```
|
||||
@app.route('/', methods=['POST'])
|
||||
def handle_messages():
|
||||
print "Handling Messages"
|
||||
payload = request.get_data()
|
||||
print payload
|
||||
for sender, message in messaging_events(payload):
|
||||
print "Incoming from %s: %s" % (sender, message)
|
||||
send_message(PAT, sender, message)
|
||||
return "ok"
|
||||
```
|
||||
|
||||
当被调用时,我们抓取消息载荷,使用函数 messaging_events 来拆解它,并且提取发件人身份和实际发送的消息,生成一个可以循环处理的 python 迭代器。请注意 Messenger 发送的每个请求有可能多于一个消息。
|
||||
|
||||
```
|
||||
def messaging_events(payload):
|
||||
"""Generate tuples of (sender_id, message_text) from the
|
||||
provided payload.
|
||||
"""
|
||||
data = json.loads(payload)
|
||||
messaging_events = data["entry"][0]["messaging"]
|
||||
for event in messaging_events:
|
||||
if "message" in event and "text" in event["message"]:
|
||||
yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape')
|
||||
else:
|
||||
yield event["sender"]["id"], "I can't echo this"
|
||||
```
|
||||
|
||||
对每个消息迭代时,我们会调用 send_message 函数,然后我们使用 Facebook Graph messages API 对 Messenger 发回 POST 请求。在这期间我们一直没有回应我们阻塞的原始 Messenger请求。这会导致超时和 5XX 错误。
|
||||
|
||||
上述情况是我在解决遇到错误时发现的,当用户发送表情时实际上是发送的 unicode 标识符,但是被 Python 错误的编码了,最终我们发回了一些乱码。
|
||||
|
||||
这个发回 Messenger 的 POST 请求将永远不会完成,这会导致给初始请求返回 5xx 状态码,显示服务不可用。
|
||||
|
||||
通过使用 `encode('unicode_escape')` 封装消息,然后在我们发送回消息前用 `decode('unicode_escape')` 解码消息就可以解决。
|
||||
|
||||
```
|
||||
def send_message(token, recipient, text):
|
||||
"""Send the message text to recipient with id recipient.
|
||||
"""
|
||||
|
||||
r = requests.post("https://graph.facebook.com/v2.6/me/messages",
|
||||
params={"access_token": token},
|
||||
data=json.dumps({
|
||||
"recipient": {"id": recipient},
|
||||
"message": {"text": text.decode('unicode_escape')}
|
||||
}),
|
||||
headers={'Content-type': 'application/json'})
|
||||
if r.status_code != requests.codes.ok:
|
||||
print r.text
|
||||
```
|
||||
|
||||
### 部署到 Heroku
|
||||
|
||||
一旦代码已经建立成我想要的样子时就可以进行下一步。部署应用。
|
||||
|
||||
那么,该怎么做?
|
||||
|
||||
我之前在 Heroku 上部署过应用(主要是 Rails),然而我总是遵循某种教程做的,所用的配置是创建好了的。而在本文的情况下,我就需要从头开始。
|
||||
|
||||
幸运的是有官方 [Heroku 文档][14]来帮忙。这篇文档很好地说明了运行应用程序所需的最低限度。
|
||||
|
||||
长话短说,我们需要的除了我们的代码还有两个文件。第一个文件是“requirements.txt”,它列出了运行应用所依赖的库。
|
||||
|
||||
需要的第二个文件是“Procfile”。这个文件通知 Heroku 如何运行我们的服务。此外这个文件只需要一点点内容:
|
||||
|
||||
```
|
||||
web: gunicorn echoserver:app
|
||||
```
|
||||
|
||||
Heroku 对它的解读是,我们的应用通过运行 echoserver.py 启动,并且应用将使用 gunicorn 作为 Web 服务器。我们使用一个额外的网站服务器是因为与性能相关,在上面的 Heroku 文档里对此解释了:
|
||||
|
||||
> Web 应用程序并发处理传入的 HTTP 请求比一次只处理一个请求的 Web 应用程序会更有效利地用测试机的资源。由于这个原因,我们建议使用支持并发请求的 Web 服务器来部署和运行产品级服务。
|
||||
|
||||
> Django 和 Flask web 框架提供了一个方便的内建 Web 服务器,但是这些阻塞式服务器一个时刻只能处理一个请求。如果你部署这种服务到 Heroku 上,你的测试机就会资源利用率低下,应用会感觉反应迟钝。
|
||||
|
||||
> Gunicorn 是一个纯 Python 的 HTTP 服务器,用于 WSGI 应用。允许你在单独一个测试机内通过运行多 Python 进程的方式来并发的运行各种 Python 应用。它在性能、灵活性和配置简易性方面取得了完美的平衡。
|
||||
|
||||
回到我们之前提到过的“requirements.txt”文件,让我们看看它如何结合 Virtualenv 工具。
|
||||
|
||||
很多情况下,你的开发机器也许已经安装了很多 python 库。当部署应用时你不想全部加载那些库,但是辨认出你实际使用哪些库很困难。
|
||||
|
||||
Virtualenv 可以创建一个新的空白虚拟环境,以便你可以只安装你应用所需要的库。
|
||||
|
||||
你可以运行如下命令来检查当前安装了哪些库:
|
||||
|
||||
```
|
||||
kostis@KostisMBP ~ $ pip freeze
|
||||
cycler==0.10.0
|
||||
Flask==0.10.1
|
||||
gunicorn==19.6.0
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.8
|
||||
MarkupSafe==0.23
|
||||
matplotlib==1.5.1
|
||||
numpy==1.10.4
|
||||
pyparsing==2.1.0
|
||||
python-dateutil==2.5.0
|
||||
pytz==2015.7
|
||||
requests==2.10.0
|
||||
scipy==0.17.0
|
||||
six==1.10.0
|
||||
virtualenv==15.0.1
|
||||
Werkzeug==0.11.10
|
||||
```
|
||||
|
||||
注意:pip 工具应该已经与 Python 一起安装在你的机器上。如果没有,查看[官方网站][15]如何安装它。
|
||||
|
||||
现在让我们使用 Virtualenv 来创建一个新的空白环境。首先我们给我们的项目创建一个新文件夹,然后进到目录下:
|
||||
|
||||
```
|
||||
kostis@KostisMBP projects $ mkdir echoserver
|
||||
kostis@KostisMBP projects $ cd echoserver/
|
||||
kostis@KostisMBP echoserver $
|
||||
```
|
||||
|
||||
现在来创建一个叫做 echobot 的新环境。运行下面的 source 命令激活它,然后使用 pip freeze 检查,我们能看到现在是空的。
|
||||
|
||||
```
|
||||
kostis@KostisMBP echoserver $ virtualenv echobot
|
||||
kostis@KostisMBP echoserver $ source echobot/bin/activate
|
||||
(echobot) kostis@KostisMBP echoserver $ pip freeze
|
||||
(echobot) kostis@KostisMBP echoserver $
|
||||
```
|
||||
|
||||
我们可以安装需要的库。我们需要是 flask、gunicorn 和 requests,它们被安装后我们就创建 requirements.txt 文件:
|
||||
|
||||
```
|
||||
(echobot) kostis@KostisMBP echoserver $ pip install flask
|
||||
(echobot) kostis@KostisMBP echoserver $ pip install gunicorn
|
||||
(echobot) kostis@KostisMBP echoserver $ pip install requests
|
||||
(echobot) kostis@KostisMBP echoserver $ pip freeze
|
||||
click==6.6
|
||||
Flask==0.11
|
||||
gunicorn==19.6.0
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.8
|
||||
MarkupSafe==0.23
|
||||
requests==2.10.0
|
||||
Werkzeug==0.11.10
|
||||
(echobot) kostis@KostisMBP echoserver $ pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
上述完成之后,我们用 python 代码创建 echoserver.py 文件,然后用之前提到的命令创建 Procfile,我们最终的文件/文件夹如下:
|
||||
|
||||
```
|
||||
(echobot) kostis@KostisMBP echoserver $ ls
|
||||
Procfile echobot echoserver.py requirements.txt
|
||||
```
|
||||
|
||||
我们现在准备上传到 Heroku。我们需要做两件事。第一是如果还没有安装 Heroku toolbet,就安装它(详见 [Heroku][16])。第二是通过 Heroku [网页界面][17]创建一个新的 Heroku 应用。
|
||||
|
||||
点击右上的大加号然后选择“Create new app”。
|
||||
|
||||
![](http://tsaprailis.com/assets/create_app.png)
|
||||
|
||||
为你的应用选择一个名字,然后点击“Create App”。
|
||||
|
||||
![](http://tsaprailis.com/assets/create.png)
|
||||
|
||||
你将会重定向到你的应用的控制面板,在那里你可以找到如何部署你的应用到 Heroku 的细节说明。
|
||||
|
||||
```
|
||||
(echobot) kostis@KostisMBP echoserver $ heroku login
|
||||
(echobot) kostis@KostisMBP echoserver $ git init
|
||||
(echobot) kostis@KostisMBP echoserver $ heroku git:remote -a <myappname>
|
||||
(echobot) kostis@KostisMBP echoserver $ git add .
|
||||
(echobot) kostis@KostisMBP echoserver $ git commit -m "Initial commit"
|
||||
(echobot) kostis@KostisMBP echoserver (master) $ git push heroku master
|
||||
...
|
||||
remote: https://<myappname>.herokuapp.com/ deployed to Heroku
|
||||
...
|
||||
(echobot) kostis@KostisMBP echoserver (master) $ heroku config:set WEB_CONCURRENCY=3
|
||||
```
|
||||
|
||||
如上,当你推送你的修改到 Heroku 之后,你会得到一个用于公开访问你新创建的应用的 URL。保存该 URL,下一步需要它。
|
||||
|
||||
### 创建这个 Facebook 应用
|
||||
|
||||
让我们的机器人可以工作的最后一步是创建这个我们将连接到其上的 Facebook 应用。Facebook 通常要求每个应用都有一个相关页面,所以我们来[创建一个][18]。
|
||||
|
||||
接下来我们去 [Facebook 开发者专页][19],点击右上角的“My Apps”按钮并选择“Add a New App”。不要选择建议的那个,而是点击“basic setup”。填入需要的信息并点击“Create App Id”,然后你会重定向到新的应用页面。
|
||||
|
||||
![](http://tsaprailis.com/assets/facebook_app.png)
|
||||
|
||||
|
||||
在 “Products” 菜单之下,点击“+ Add Product” ,然后在“Messenger”下点击“Get Started”。跟随这些步骤设置 Messenger,当完成后你就可以设置你的 webhooks 了。Webhooks 简单的来说是你的服务所用的 URL 的名称。点击 “Setup Webhooks” 按钮,并添加该 Heroku 应用的 URL (你之前保存的那个)。在校验元组中写入 ‘my_voice_is_my_password_verify_me’。你可以写入任何你要的内容,但是不管你在这里写入的是什么内容,要确保同时修改代码中 handle_verification 函数。然后勾选 “messages” 选项。
|
||||
|
||||
![](http://tsaprailis.com/assets/webhooks.png)
|
||||
|
||||
点击“Verify and Save” 就完成了。Facebook 将访问该 Heroku 应用并校验它。如果不工作,可以试试运行:
|
||||
|
||||
```
|
||||
(echobot) kostis@KostisMBP heroku logs -t
|
||||
```
|
||||
|
||||
然后看看日志中是否有错误。如果发现错误, Google 搜索一下可能是最快的解决方法。
|
||||
|
||||
最后一步是取得页面访问元组(PAT),它可以将该 Facebook 应用于你创建好的页面连接起来。
|
||||
|
||||
![](http://tsaprailis.com/assets/PAT.png)
|
||||
|
||||
从下拉列表中选择你创建好的页面。这会在“Page Access Token”(PAT)下面生成一个字符串。点击复制它,然后编辑 echoserver.py 文件,将其贴入 PAT 变量中。然后在 Git 中添加、提交并推送该修改。
|
||||
|
||||
```
|
||||
(echobot) kostis@KostisMBP echoserver (master) $ git add .
|
||||
(echobot) kostis@KostisMBP echoserver (master) $ git commit -m "Initial commit"
|
||||
(echobot) kostis@KostisMBP echoserver (master) $ git push heroku master
|
||||
```
|
||||
|
||||
最后,在 Webhooks 菜单下再次选择你的页面并点击“Subscribe”。
|
||||
|
||||
![](http://tsaprailis.com/assets/subscribe.png)
|
||||
|
||||
现在去访问你的页面并建立会话:
|
||||
|
||||
![](http://tsaprailis.com/assets/success.png)
|
||||
|
||||
成功了,机器人回显了!
|
||||
|
||||
注意:除非你要将这个机器人用在 Messenger 上测试,否则你就是机器人唯一响应的那个人。如果你想让其他人也试试它,到 [Facebook 开发者专页][19]中,选择你的应用、角色,然后添加你要添加的测试者。
|
||||
|
||||
###总结
|
||||
|
||||
这对于我来说是一个非常有用的项目,希望它可以指引你找到开始的正确方向。[官方的 Facebook 指南][20]有更多的资料可以帮你学到更多。
|
||||
|
||||
你可以在 [Github][21] 上找到该项目的代码。
|
||||
|
||||
如果你有任何评论、勘误和建议,请随时联系我。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/
|
||||
|
||||
作者:[Konstantinos Tsaprailis][a]
|
||||
译者:[wyangsun](https://github.com/wyangsun)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://github.com/kostistsaprailis
|
||||
[1]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#tech-stack
|
||||
[2]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#bot-architecture
|
||||
[3]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#the-bot-server
|
||||
[4]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#deploying-to-heroku
|
||||
[5]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#creating-the-facebook-app
|
||||
[6]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#conclusion
|
||||
[7]: https://www.heroku.com
|
||||
[8]: https://www.python.org
|
||||
[9]: http://flask.pocoo.org
|
||||
[10]: https://git-scm.com
|
||||
[11]: https://virtualenv.pypa.io/en/stable
|
||||
[12]: https://github.com/hult/facebook-chatbot-python
|
||||
[13]: https://github.com/hult
|
||||
[14]: https://devcenter.heroku.com/articles/python-gunicorn
|
||||
[15]: https://pip.pypa.io/en/stable/installing
|
||||
[16]: https://toolbelt.heroku.com
|
||||
[17]: https://dashboard.heroku.com/apps
|
||||
[18]: https://www.facebook.com/pages/create
|
||||
[19]: https://developers.facebook.com/
|
||||
[20]: https://developers.facebook.com/docs/messenger-platform/implementation
|
||||
[21]: https://github.com/kostistsaprailis/messenger-bot-tutorial
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user