Wed 09 January, 2008
The end of our big Africa trip is nearly here. The travel through Kenya went well despite the reported violence, demonstrations, and so on. We've been in Zanzibar for the last several days for a little beach time and even a wedding. :-)
On January 8th, 2008 we were married on the beach during a breezy and sunny day. It was a great ceremony in an excellent location and I'll surely write a lot more about it (and the rest of the trip) later. But we need to start our day of travel back to the USA and the harsh reality of not living on a beach resort.
We'll be heading back via Nairobi, London, and finally San Francisco. In the meantime, here are a few more wedding pictures. We'll upload more in a few days--not to mention billions of safari pictures.
See you all in a few days, and thanks for all the good wishes!
(comments)
12月27日,广电总局和信产部联合发布《互联网视听节目服务管理规定》,定下了视频服务“国有化”的基调。为配合新规定的宣传,当晚,CCTV新闻联播开动宣传机器造势,一个孩子和一名家长被选作道具,用来证明“规定”的正义性和合法性。“很黄很暴力”作为08流行语由此引爆。第二天,央视奥运频道启动仪式遭遇斌薇意外,用户很快将手机拍摄的现场视频发布到互联网上,并通过互联网得到广泛传播。这样一个戏剧性的结尾,把所有的问号都留给了2008年。
在中国,通过强大的CCTV,我们每天都在看这样的“导演”出来的新闻。 这些职业导演训练有素,手法娴熟,批量地制造着和谐。我不知道,视频服务国有化,是否就是让其CCTV化,或者说得更明确点,剧本化。如果一切都像奥运会的开幕式一样,有导演,有彩排,有脚本,有分镜头,一切尽在掌握,同一个世界,同一个导演,那会显得多么和谐。有一天,你打开所有的“国有”视频网站,看到的都是导演安排的小朋友在说“很黄很暴力”,你怎么办?我赶快给关了。
在评论斌薇事件时,William Moss说:“这一事件清楚地表明,在即将来临的8月,无论中国怎样控制有关奥运的新闻和形象,任何人只要有一部手机就能成为新闻记者。”不过,我得提醒用手机拍摄的人注意,不要遇上很暴力的天门市城管,也不要遇上派警察到北京来抓记者的县委书记。
仔细想想,天门市城管、西丰县委书记、CCTV、广电总局,他们在干的不都是同一件事吗?控制。但是很不幸,他们遇到了互联网。既然天门市城管、西丰县委书记和CCTV都最终没能控制住,凭什么广电总局就自认可以游离于历史潮流之外?凭什么它就以为自己可以而且必须控制历史、导演历史?
还好,我们没有一个如此强悍,好事都想插一腿,好吃都想吃一嘴的商务部。如果它也出台一个规定,要求从事电子商务服务的公司必须为“国有独资或国有控股单位”,阿里巴巴的投资者们全都将欲哭无泪。
同一个世界,不同的梦想,那是个美丽的世界。偏偏有人连梦都要给导演成同一个,这不是痴人说梦是什么?
Livid 总能搞些让人惊喜的 Web 应用。之前的备受好评的 V2EX 被阻尼后,新开发的大脚社区 也赢得了不少朋友关注。今天早晨 Livid 给我演示了几张截图:大脚准备开放 API了。
目前 API 主要是针对先前大脚的便签本功能(?)。如果客户能够比较轻松的把便签内容集成到自己的站点或者 Blog 上,那么和 Livid 早前的 个人数据中心 的想法还是有些一致的。
本周应该就能看到这个服务了,Livid 还在继续提高程序的健壮性。至于性能,现在“普通的 1U PC-server,性能大概在 100RPS"。更多的小道消息:现在每条便签可存储最多 50000 个 UTF8 字符,每个帐号可以存储最多 10000 条 note,”还计划让每条 Note 都支持带中文分词的 $nc->match() 及 Tagging“
.有想法,能实现,这两条加在一起就非常难了,Livid 正在做.....非常有意思。算起来,大脚也是国内 Web 2.0 站点第二三个提供 API 服务的了(除了 Yupoo 和豆瓣,还有谁?)。
看到霍炬写的“程序员的温情管理文化”,写得很好,与我心有切切焉。
想想很久以前,我也就是这么做的。 那个时候找到的资料很少,对于怎么运行管理项目没有任何经验可言,唯一能找到的就是几本关于Microsoft的书,至今都能记得,比如《code complete》《debug the develop process》《write solid code》, 还有《微软的秘密》《I sing the body electronic(现在有个中译版本可能是“微软面面观”)》, 这些书我现在仍然觉得值得推荐和阅读。
当时没有经验也没有人指导,所以只能啃这些书来摸着石头过河。结合自己的工作习惯,推己及人,我做的第一件事情就是完全的弹性工作时间,很长时间我把这个奉为原则,甚至为此和反对的合作伙伴争吵。无论如何,我营造了一个非常自由宽松,但凝聚力和产能非常强的小队伍,物以类聚,我们大家都是夜猫子,那时候基本是大家都早晨从中午开始,晚上常常2~3点了去大娘水饺夜宵然后才各自回家睡觉,那种感觉真的让我很留恋,而那时候的team很小,但现在总结,那时候10人以内的team是我过去自己带的team中最强的,效率也是最高的,但绝对是最自由散漫的。
随着人变多,问题开始出现,并且越来越严重。人多了接口就多了,人常常找不到,这些都不算真正的问题,真正的问题在于一些充分利用这种自由的人开始悄悄出现了。另外越来越多的来自其他“成熟”公司的“专业”人士指出这种散漫的团体只是小打小闹,要成气候必须要上“正轨”。随着几个关键项目的开发失败,是的,彻底的失败被迫砍掉和停止, 我觉得也许应该要更多的人,要更清晰的process, 上班要更加像一个公司, … 不曾想到的是,这些东西最终逐渐把公司和team变成了也许是别人眼里的“好”公司和“好”团队,却不是我所期望的。
自己做软件带team这么多年下来,觉得自己越来越从一个自由主义的,近乎盲目的Y理论信奉者的人,一步步不情愿却身不由己地变成一个越来越苛刻,X理论的执行者,可能有一些同学因此而痛恨我,不过也许他们不曾想到我为此而痛恨自己和痛恨那些让我不得不这么做的人和事。虽然我自己都很不喜欢这样,但现实中的一些问题如同作茧自缚,常常让自己越来越陷入这样的倾向。 毫无疑问,我不是个好的管理者,或者说我从来没有兴趣去成为一个好的管理者,我的兴趣在于做一流的软件,为了实现这个理想,我才去组team, 才去做一些本来我不想做也未必擅场的事情, 比如管人。总而言之,团队中很多灵活,宽松和人性的东西,常常在一些充分利用这些制度的人的做法下,被迫一点点地失去,不幸的是这样的人虽不多却总是有,而破坏力是强大的,也许他(她)们有他们的能力和强项,但显然不适合我的风格。
回头总结经验和教训,再结合最近这一年来我学到的其他的成功团队的一些做法,我惊讶地发现,过去我最没有经验,最由着性子,摸着石头过河的时候的做法才是最正确的做法,才是最接近一些成功软件企业的软件开发团队的管理做法。看到霍炬的文章,我觉得仿佛找到了我很多年前执行着却自我怀疑着的观念,希望他们能延续和发展下去,成为优秀的中国软件团队,并因此而带动出更多这样的优秀团队。
为什么看似自由散漫的团队反而能有好的生产效率呢? 霍炬的文章中已经谈了一些,我再补充一些。 我现在来看,这样的宽松team的能进行宽松人性管理,还有几个要点,首先重中之重就是人要精干,宁缺勿滥,我党教育的“人多力量大”在软件行业是错误的,《人月神话》已经告诉了我们这是神话而已。 一旦团队中出现了喜欢“利用”制度自我获利的人,就会逐渐在不知不觉中瓦解宽松的优势,就如同千里之堤溃于蚁穴的道理,因此如可能要及早摘除这些不适合的对象。 其二是找适合小团队的敏捷process, 我们过去犯的一个严重错误就是中了CMM的毒害,搞了个一堆大公司的摸板照葫芦画瓢,结果好的没学会,自己的精干敏捷的优势反而丧失了,现在敏捷开发过程已经很流行了,所以已经有很多的书和资料可以参考,我推荐Scrum; 其三,不要迷信所谓“高手”,这似乎和前面说的人求精有矛盾,但对团队来说好的人是指对团队能积极贡献的人而不是纯粹的个人能力,而且高手都是新手长成的,对做的事情有热情是非常重要的,谦虚、合作、不搞特殊化的“高手”才是有价值的,否则反而是有害的。
也许有人说团队总要成长的,你这些东西如何适应大些的team? 我现在的看法是,第一,尽量不要扩大团队的规模,一定要以足够苛刻的面试要求来招人(当然这可能几乎招不到人,所以自己把握),一旦降低条件招来一堆没用的人(或者不适合你用的人),危机就开始了; 第二,几个的小团队可以组合成大些的团队,没有新的领队?说明还不具备扩展新团队的能力,等等吧; 第三,一定要找到“合拍”的人,有些人的能力很强,但不适合于startup team, 引入这些人是lose lose局面;四,不要需要羡慕“大”,大不表示强,强未必需要大。
我的这些观点只适用于这样的小团队:
* 以开发软件产品或者以软件支撑的服务的团队;
* 对软件质量,技术水准有不懈要求的团队
* 不甘平庸,希望make something different的团队
这样的team在中国是否能获得好的回报,我不知道,只是纯粹从技术团队的建立角度出发的,这也是从我自身特长和缺点出发的,未必适用其他人。 这些观点显然不适合在人员管理方面EQ超群长袖善舞者,也可能不适应理想是成为企业家的人,更不适合只是打算靠软件或互联网赚一票而并不是很在意软件和技术本身的人。
我觉得还要谈谈最近学到的一个词“work life balance”, 这太重要的。work life balance的团队才是有长远生命力的团队。也许有人觉得我是个工作狂,但呵呵我实际上是个很注重work life balance的人,只不过我的一些life的喜好和work差不多而已。这么多年的时间,我从来没有放弃自己对计算机技术的喜好和热情,是的包括写代码,这是重要的部分。n年来,n多人,有真诚建议的,有嘲讽的,有鄙视的,他们告诉我要这么喜欢技术动不动自己coding是不可能有更大进步的,我从来没有动摇过,呵呵,因为我喜欢。为work绝对不可以牺牲life, 绝对不可以做work的奴隶,所以我coding, 我去开无关紧要我自己enjoy的会, 我去游历世界,… 这些生活上的喜好,让我总是可以在挫折和问题中寻找到出路和方向。startup是艰苦的,但绝对不能为了创业这种work而牺牲掉life, 否则就是得不偿失的。
很高兴能在这里能共享一些自己的看法,在我过去犯着错误和在现实和理想中挣扎的时候,是多么希望能有一些观点和建议来给自己指明方向啊, 希望这些能对某些谁有一些价值和帮助。
最后需要强调说明的是,这只是我的一家之言,最多只能说是作为一个多走过几步路的人的一些体会,甚至不能称为建议,是否值得采纳请慎重思考。
- No related posts

If you want to use Google Web History and save your browser's history on Google's servers, you generally need to go to this page and select "Enable Web History and install the toolbar". This procedure installs Google Toolbar, a plug-in available only for Internet Explorer and Firefox, and enables the PageRank feature, which displays the ranking of any site you visit while sending the URL to Google in the process.
If you use another browser or if you don't like Google Toolbar, there's an alternative way to send all the web pages you visit to Google: a script that asks Google for the PageRank of any web pages you load in your browser. To install the script you need:
* Greasemonkey, an extension for Firefox. Make sure to restart the browser before trying to add the script.
* Trixie, one of the best Greasemonkey-like plug-ins for Internet Explorer
* SIMBL and GreaseKit for Safari
* no additional software for Opera, but you need to enable the feature from Opera's interface
* Konqueror Userscript for Konqueror
The script is taken from this site, that also adapted it from other scripts. I mirrored the script to an easily-accessible location.
Once you've added the script, you only need to enable Google Web History: go to this page and select "Enable Web History and install the toolbar", but cancel the downloading process (you don't need the toolbar).
This feature only works when you're logged in to your Google Account. To disable it, remove the script from Greasemonkey or from another plug-in you've installed.
This Week’s Featured Job
➪ Senior Web Developer - Vodori, Chicago, IL
Many thanks to all our job posters. You’ll see your company or organization on 43 Folders when you post to the 43f Job Board. Featured jobs will be featured in weekly posts like this one.
But, since we only had one featured job this week, I wanted to recognize all our new employers — lots of great opportunities here for a new job in the new year:
- Software Engineer - DonorsChoose.org, New York, NY
- Software Engineer in Test - DonorsChoose.org, New York, NY
- Front-End Web Developer - DonorsChoose.org, New York, NY
- C# Developer - R/GA, NYC, NY
- Flash Developer - R/GA, NYC, NY
- Web Applications Programmer/Server Admin - Environmental Working Group, Washington, DC (Oakland, CA, or telecommute)
- Software Engineer - Webmetrics, San Diego, CA (Sorrento Valley)
- International Business Development Manager - Twitter, Inc., San Francisco, CA
- Software Developer - dynaConnections Corporation, Austin, TX
- Rails Developer - Emmet Labs, San Francisco, CA
- Associate Geek - Obvious, San Francisco, CA
- Principal Designer - DonorsChoose.org, New York, NY
- Senior Information Designer - AdaptiveBlue, New York, NY (Tri-state area)
- Graphic Designer / Hip Young Gunslinger - Driven Media, Cranbrook/Kimberley, BC, Canada (Rocky Mountains)
- Software Engineers - Bebo, San Francisco, CA
- App Genius for Developing Facebook Applications - Context Optional, Inc, San Francisco, CA (San Francisco Bay Area)
- User Interface Designer - Wikispaces, San Francisco, CA
- Software Engineer - Wikispaces, San Francisco, CA
- User Experience & Interaction (UE/UX/UI) Director - jaxtr, Inc., Menlo Park, CA
- Enterprising codesmith wanted - Synthesis Studios, Inc., Cambridge, MA
- Senior User Experience Designer - Citrix Online LLC, Santa Barbara, CA
Howard Rheingold, online pioneer and dapper man of the mustache and Indiana Jones hats, has started a new video blog to update his seminal 1992 essay, “A Slice of Life in my Virtual Community,” with how he spends his time online with today’s technologies. The first video is a little remedial, but what caught my eye is his promise to clue us in to his daily process, including not only his office time, but time spent on hobbies like painting and gardening. Looking back at that sentence, I know that sounds about as exciting as getting a flu shot, but I’m a sucker for watching how smart people manage their days. Should be worth a watch.
Reading back through that old essay, one thing that made me stop was his explanation of how he found his online homebase, The Well:
I found this digital watering hole for information-age hunters and gatherers the same way most people find such places — I was lonely, hungry for intellectual and emotional companionship, although I didn’t know it. While many commuters dream of working at home, telecommuting, I happen to know what it’s like to work that way. I never could stand to commute or even get out of my pajamas if I didn’t want to, so I’ve always worked at home. It has its advantages and its disadvantages. Others like myself also have been drawn into the online world because they shared with me the occupational hazard of the self-employed, home-based symbolic analyst of the 1990s — isolation.
I’m curious to see his updated thoughts on isolation of the self-employed, “symbolic analyst,” because as someone whose daily companions are usually a toddler and a dog, I can tell you that it still exists 16 years later.
Johni Brown asks:
Can you describe initial direction you took when developing Highrise, before you started over? How did it differ from today’s Highrise? What aspect of it were you unhappy with, and why?
The primary problem with the first version of Highrise was that we didn’t use it ourselves. It was built on fantasy requirements of what some people might need one day. That’s an incredibly hard way to build software. And it certainly isn’t our way of building software.
Here’s an early (ugly) screenshot from the initial direction. Lots of unstyled stuff, but hopefully it gives you an idea of the complexity we didn’t like.
The focus on “some people” lead us down the path of “they might also need this” and “it would probably be cool to have that”. Before we knew it, the create a new note screen had a barrage of options that needed to be set before you could post. It was too cumbersome, too slow, and surprisingly too rigid despite trying to be flexible. (The aha moment for us was contrasting the ease of getting data into Campfire vs Highrise at the time).
Getting too clever with language and permissions
We also got lost down the rabbit hole of cleverness a few times. We wanted categories for your notes that would align to natural language. I forget the specifics exactly, but it was akin to “David has completed a phone call with Jason”. Where “phone call” would be the category. But how do you figure out what the joining words would be when the category is “fax”? “David has completed a fax with Jason” doesn’t really work. We tried too hard for too long to be clever on wording when it really doesn’t matter all that much.
The second rabbit hole was permissions. Permissions is always a deep, dark dungeon that you really would rather not venture into. But some times dragons need slaying and so we did. We started out with a ridiculously flexible system that allowed you to mix and match any number of groups and people together. You could have a note visible by “Marketing, Programming, John, and Jane”. That proved to be incredibly complex on both the implementation side and the UI side. But for a long time we couldn’t let go because we were caught up chasing edge cases.
The promises that got us back on track
So when we finally realized that this wasn’t going to work, we rebooted the project with a number of promises:
- Design for yourself, make everyone on the team want to use Highrise—not just Jason talking to journalists, but Ryan dealing with his mechanic as well
- Not every edge case needs solving—yes, there might be a case where having both Marketing and Jane see something but not Joe, but it’s not worth the complexity of enabling that case.
- Start using the product right away—a lot of “what ifs” and “wouldn’t it be cools” just go away when you actually start using something and discover what really matters.
As you can see, these lessons are nothing new. We’ve been preaching these ideas for a long time, but living them is so much harder. When we let the core principles of Getting Real slide, not even we could produce software worth a damn.
Got a question for us?
Got a question about design, business, marketing, etc? We’re happy to try to provide some insight into how we’d tackle the problem. Just email svn [at] 37signals dot com with the subject “Ask 37signals”. Thanks.
Johni Brown asks:
Can you describe initial direction you took when developing Highrise, before you started over? How did it differ from today’s Highrise? What aspect of it were you unhappy with, and why?
The primary problem with the first version of Highrise was that we didn’t use it ourselves. It was built on fantasy requirements of what some people might need one day. That’s an incredibly hard way to build software. And it certainly isn’t our way of building software.
Here’s an early (ugly) screenshot from the initial direction. Lots of unstyled stuff, but hopefully it gives you an idea of the complexity we didn’t like.
The focus on “some people” lead us down the path of “they might also need this” and “it would probably be cool to have that”. Before we knew it, the create a new note screen had a barrage of options that needed to be set before you could post. It was too cumbersome, too slow, and surprisingly too rigid despite trying to be flexible. (The aha moment for us was contrasting the ease of getting data into Campfire vs Highrise at the time).
Getting too clever with language and permissions
We also got lost down the rabbit hole of cleverness a few times. We wanted categories for your notes that would align to natural language. I forget the specifics exactly, but it was akin to “David has completed a phone call with Jason”. Where “phone call” would be the category. But how do you figure out what the joining words would be when the category is “fax”? “David has completed a fax with Jason” doesn’t really work. We tried too hard for too long to be clever on wording when it really doesn’t matter all that much.
The second rabbit hole was permissions. Permissions is always a deep, dark dungeon that you really would rather not venture into. But some times dragons need slaying and so we did. We started out with a ridiculously flexible system that allowed you to mix and match any number of groups and people together. You could have a note visible by “Marketing, Programming, John, and Jane”. That proved to be incredibly complex on both the implementation side and the UI side. But for a long time we couldn’t let go because we were caught up chasing edge cases.
The promises that got us back on track
So when we finally realized that this wasn’t going to work, we rebooted the project with a number of promises:
- Design for yourself, make everyone on the team want to use Highrise—not just Jason talking to journalists, but Ryan dealing with his mechanic as well
- Not every edge case needs solving—yes, there might be a case where having both Marketing and Jane see something but not Joe, but it’s not worth the complexity of enabling that case.
- Start using the product right away—a lot of “what ifs” and “wouldn’t it be cools” just go away when you actually start using something and discover what really matters.
As you can see, these lessons are nothing new. We’ve been preaching these ideas for a long time, but living them is so much harder. When we let the core principles of Getting Real slide, not even we could produce software worth a damn.
Got a question for us?
Got a question about design, business, marketing, etc? We’re happy to try to provide some insight into how we’d tackle the problem. Just email svn [at] 37signals dot com with the subject “Ask 37signals”. Thanks.
Van Mardian at Declutter Your Desk has sparked inspiration with a really clever way to deal with all the cables, connections and peripherals that make your desk a mess. He attached a pegboard to the underside of his desk and tied all those boxes and wires into a clean layout hidden from view. I especially like how he made the pegboard removable, so you don’t need to crawl around on your back to add or remove components. Total cost of the materials is $33.42 Canadian and around 2 hours of work. Awesome.
Van Mardian at Declutter Your Desk has sparked inspiration with a really clever way to deal with all the cables, connections and peripherals that make your desk a mess. He attached a pegboard to the underside of his desk and tied all those boxes and wires into a clean layout hidden from view. I especially like how he made the pegboard removable, so you don’t need to crawl around on your back to add or remove components. Total cost of the materials is $33.42 Canadian and around 2 hours of work. Awesome.
今天戴飞和我聊起来为什么在一些公司会很闲但是很累,在另外一些公司工作量大但是很开心的话题。不由得勾起了我总结一下长久以来关于工作,尤其是对程序员的工作管理的一些话题。
从我带第一个技术团队算起,已经有很多年了。我始终坚持的一件事就是温情。所谓温情,很简单,替别人多想一些。我在附中的时候,下班总要“轰”大家回家,不让团队成员加班。如果为了躲避晚高峰不想走,我就鼓动他们玩玩游戏,看看电影看看书,别太累。
这事情在所谓“管理者”眼里是个笑话,在他们那里几个参数是等同的,加班==工资==产能。事实上每个工作过几年的人都知道这不可能。程序员是这样一群家伙,他们可以把1000行代码写成10行,当然也可以把10行代码写成1000行。他们可以让这1000行代码比那10行容易看懂效率更高,也可以让那10行比这1000行容易看懂效率更高。
在这种情况下,我更愿意在质量和工作量中找一个平衡点。即,不让任何一个人累着,不要让他们早晨起来躺在床上懒得上班,不要让他们因为加班被家人抱怨甚至感情危机。人首先是生活的人,如果放弃了生活,工作也没意义。皮之不存,毛将焉附?
最终找到的这种平衡点很有趣。那就是,程序员很难在一天内完成超过4个小时的高效工作。我说的是要求质量,有能动性,要动脑子,有创意的那种工作,拼贴代码那种机械工作咱们就不讨论了。因此我尝试在我和tiny的新公司实行每天6小时,每周30小时工作制。同时我们在力所能及的情况下不主动压低任何人的工资。我们不用期权引诱人,我们首先保证所有人生活正常,无压力,虽然我们认为我们的期权很值钱。但值钱不值钱这件事不是自己吹牛吹出来的,是大家共同努力出来的。
事实证明,每天6个小时工作时间不但没有降低效率,反而比8个小时高很多。想想也不奇怪,早晚放弃了1个小时,所有人都可以躲过早晚交通高峰,路上花费更少的时间,不会被人挤,心情不会太差,到公司可以很快进入工作状态,且心情轻松。
我倾向于相信,如果生活稳定,家庭幸福,收入正常,且在做一份有未来的事业,所有人都愿意尽自己最大努力。反之,其实所有人都有去稳定的大公司的机会。没人愿意来创业。
说到这里,一定会有人反驳:软件工程就是用来降低程序员不稳定性,工作量不够,产品质量不高的问题的。是的,这种说法完全对,不过仅限于外包领域。外包领域具有明确的需求和验收标准,产品相当稳定。他们追求的是重复性,可复用性。因此他们希望通过一种机制,让程序员变成机器。一个程序员“坏了”(不开心了,辞职了,老了精力下降了),那就换一个,就好像换掉一个巨大机器上面的齿轮,咔的一声,拧好螺丝,继续运转,一切都跟没发生过一样。刚才那个被拧下的齿轮呢?老天,谁关心那个。
在互联网,尤其是带有较高技术含量的领域,或是新鲜的领域,我们因为没有标准可循,所以并不需要这种机器。我力图把程序员重新还原成人。所以我更喜欢创造一个有温情的环境。其实不仅仅我这个小创业者的胡思乱想,google给员工极度的自由,极好的待遇,我觉得也可以看做这种思路。google知道无法管理技术人员,所以他们干脆选择了彻底的,全面的妥协。一切都交给你们,你们努力去做就好,我们不给你压力。事实上,在选好人的情况下,这种思路产生的产能是惊人的。当然,在中国似乎没选好人,所以产生的浪费也是惊人的。
几乎所有武术都在讲,出拳的时候手臂要放松,接触目标的瞬间发力,这样才有力量。如果出拳即发力,则会导致肌肉紧张,动作变形,最终你使出了全身的力气,却只打出了软绵绵的一拳。这多么的悲哀。
After 10-years in the works, the Eames House, Lounge Chair, La Chaise, Crosspatch, House of Cards, and other famous Eames designs will get your mail from point A to point B this summer. More from the Chairman of the Board of the Eames Foundation.
After 10-years in the works, the Eames House, Lounge Chair, La Chaise, Crosspatch, House of Cards, and other famous Eames designs will get your mail from point A to point B this summer. More from the Chairman of the Board of the Eames Foundation.
Jason Fried was recently interviewed on John Jantsch’s Duct Tape Marketing Podcast.
We spent a fair amount of time discussing the workings of their newest offering, a CRM app known as Highrise…As is usually the case, 37Signals chose to do some of the primary CRM functions elegantly and leave the others to, well, others. It’s worth a look.
And let’s play some catchup: Here are summaries (posted by others) of a couple of Jason’s 2007 conference presentations…
2007 MIMA Summit Wrap Up mentions red flag words like need, can’t, easy, just, only, etc.
The afternoon Keynote was an eye opening look into a new way of working: silent. The guys at 37signals have found out that talking to each other is a big productivity killer. To help fix this, they have days where no one is allowed to talk. Their example was to think of it like sleeping. If you constantly get interrupted, you never get a good night sleep. Work is the same way. By being silent and only communicating via IM or email, you are more apt to get into the zone and crank out more quality work in a shorter amount of time.
Another tip was to avoid meetings as they can be toxic. Some meetings can be an hour long, but really, the meeting could be 15-20 minutes and have the same outcome. It seems people are more apt to fill the time than have shorter meetings.
I have to say, Jason had some great ideas. I’m not convinced that they’d work out for all companies, but there was one take away that I can start doing today; and that’s avoiding “red flag” words. Words such as need, can’t, easy, just, only and fast are all words that don’t come across well in communication as it means you’re making assumptions.
“We just need this one feature.” “It should be easy to just add one more thing.” “Let’s do it fast and get it done with.”
These types of statements make it appear as if the sender is assuming that the receiver’s job is simple. The receiver may feel insulted or under-appreciated. Avoiding those “red flag” words can help out communication quite a bit. I know I’m going to print them out and do my best to try and avoid them.
Jason Fried: Say No More sums up the Mossberg/Fried interview at The Business Innovation Factory.
Mossberg began by saying they weren’t going to be talking about technology, but it quickly became clear that he meant they weren’t going to talk about technology from a technical standpoint. Instead, Mossberg focused on what Fried knows best: what makes technology good. Anyone who has read anything from 37Signals can guess Fried’s answer: simplicity.
Fried introduced 37Signals as a company that makes software for small businesses, but quickly corrected himself, “We don’t really think of it as software,” he said, “we think of it as tools to get things done.” 37Signals focuses on the simplest way to solve a problem and then “gets out of the way,” said Fried. The problem with traditional software is that it often gets in the way. It gets complicated, bloated, and hard to use.
The reason, argued Jason, is that the software industry is structured to build crap (borrowing the term Mossberg used to describe Outlook). Software is designed to make money on new versions shipped every year or so, and in order to convince users to keep upgrading developers feel pressure to add new features. 37Signals, on the other hand, offers its software over the web as a service. When people are paying a monthly fee, the company can release updates on a continuous basis and focus on making things work as simply as possible, rather than adding more features.
Always the skeptic, Mossberg didn’t buy it. How do you balance your mantra of simplicity with demands of self selected vocal customers who want more, he asked. How do you avoid feature creep?
Echoing a post he made on his company’s blog this morning, Fried said that good software needs editors. The same way a museum needs a curator or a writer needs an editor, software development too demands a leader with a clear voice who is willing to say, “no.” “You have to be a hard ass,” said Fried. 37Signals is what Fried calls an “opinionated company.” They believe in their way of doing things, and users who agree with those ideas will have a great time using their software. Another company built in this mold is Apple.
“But Steve Jobs is a dictator,” said Mossberg of the comparison to Apple. “And I love that,” said Fried. “I think it’s unbelievably fantastic.”
In their book Getting Real, 37Signals talks about making software for a core group of customers. “The customer is not always right,” they write. “The truth is you have to sort out who’s right and who’s wrong for your app.” The number one person who is right for you app is you, the developer. If you’re not making software that you would use, and is built with your vision in mind, then the software will suffer because as a result. As Fried told the crowd here, “Fundamentally, people need to say no more.”
Jason Fried was recently interviewed on John Jantsch’s Duct Tape Marketing Podcast.
We spent a fair amount of time discussing the workings of their newest offering, a CRM app known as Highrise…As is usually the case, 37Signals chose to do some of the primary CRM functions elegantly and leave the others to, well, others. It’s worth a look.
And let’s play some catchup: Here are summaries (posted by others) of a couple of Jason’s 2007 conference presentations…
2007 MIMA Summit Wrap Up mentions red flag words like need, can’t, easy, just, only, etc.
The afternoon Keynote was an eye opening look into a new way of working: silent. The guys at 37signals have found out that talking to each other is a big productivity killer. To help fix this, they have days where no one is allowed to talk. Their example was to think of it like sleeping. If you constantly get interrupted, you never get a good night sleep. Work is the same way. By being silent and only communicating via IM or email, you are more apt to get into the zone and crank out more quality work in a shorter amount of time.
Another tip was to avoid meetings as they can be toxic. Some meetings can be an hour long, but really, the meeting could be 15-20 minutes and have the same outcome. It seems people are more apt to fill the time than have shorter meetings.
I have to say, Jason had some great ideas. I’m not convinced that they’d work out for all companies, but there was one take away that I can start doing today; and that’s avoiding “red flag” words. Words such as need, can’t, easy, just, only and fast are all words that don’t come across well in communication as it means you’re making assumptions.
“We just need this one feature.” “It should be easy to just add one more thing.” “Let’s do it fast and get it done with.”
These types of statements make it appear as if the sender is assuming that the receiver’s job is simple. The receiver may feel insulted or under-appreciated. Avoiding those “red flag” words can help out communication quite a bit. I know I’m going to print them out and do my best to try and avoid them.
Jason Fried: Say No More sums up the Mossberg/Fried interview at The Business Innovation Factory.
Mossberg began by saying they weren’t going to be talking about technology, but it quickly became clear that he meant they weren’t going to talk about technology from a technical standpoint. Instead, Mossberg focused on what Fried knows best: what makes technology good. Anyone who has read anything from 37Signals can guess Fried’s answer: simplicity.
Fried introduced 37Signals as a company that makes software for small businesses, but quickly corrected himself, “We don’t really think of it as software,” he said, “we think of it as tools to get things done.” 37Signals focuses on the simplest way to solve a problem and then “gets out of the way,” said Fried. The problem with traditional software is that it often gets in the way. It gets complicated, bloated, and hard to use.
The reason, argued Jason, is that the software industry is structured to build crap (borrowing the term Mossberg used to describe Outlook). Software is designed to make money on new versions shipped every year or so, and in order to convince users to keep upgrading developers feel pressure to add new features. 37Signals, on the other hand, offers its software over the web as a service. When people are paying a monthly fee, the company can release updates on a continuous basis and focus on making things work as simply as possible, rather than adding more features.
Always the skeptic, Mossberg didn’t buy it. How do you balance your mantra of simplicity with demands of self selected vocal customers who want more, he asked. How do you avoid feature creep?
Echoing a post he made on his company’s blog this morning, Fried said that good software needs editors. The same way a museum needs a curator or a writer needs an editor, software development too demands a leader with a clear voice who is willing to say, “no.” “You have to be a hard ass,” said Fried. 37Signals is what Fried calls an “opinionated company.” They believe in their way of doing things, and users who agree with those ideas will have a great time using their software. Another company built in this mold is Apple.
“But Steve Jobs is a dictator,” said Mossberg of the comparison to Apple. “And I love that,” said Fried. “I think it’s unbelievably fantastic.”
In their book Getting Real, 37Signals talks about making software for a core group of customers. “The customer is not always right,” they write. “The truth is you have to sort out who’s right and who’s wrong for your app.” The number one person who is right for you app is you, the developer. If you’re not making software that you would use, and is built with your vision in mind, then the software will suffer because as a result. As Fried told the crowd here, “Fundamentally, people need to say no more.”
An updated version of Google's paper about MapReduce (available at ACM and mirrored here) provides new information about Google's scale. MapReduce is a software framework used by Google to "support parallel computations over large (...) data sets on unreliable clusters of computers". Google uses it for indexing the web and computing PageRank, for processing geographic information in Google Maps, clustering news articles, machine translation, Google Trends etc.The input data for some of the MapReduce jobs run in September 2007 was 403,152 TB (terabytes), the average number of machines allocated for a MapReduce job was 394, while the average completion time was 6 minutes and a half. The paper mentions that Google's indexing system processes more than 20 TB of raw data. Since 2003, when MapReduce was built, the indexing system progressed from 8 MapReduce operations to a much bigger number today.
Niall Kennedy calculates that the average MapReduce job runs across a $1 million hardware infrastructure, assuming that Google still uses the same cluster configurations from 2004: two 2 GHz Intel Xeon processors with Hyper-Threading enabled, 4 GB of memory, two 160 GB IDE hard drives and a gigabit Ethernet link.
Greg Linden notices that Google's infrastructure is an important competitive advantage. "Anyone at Google can process terabytes of data. And they can get their results back in about 10 minutes, so they can iterate on it and try something else if they didn't get what they wanted the first time."
| Aug. '04 | Mar. '06 | Sep. '07 | |
| Number of jobs (1000s) | 29 | 171 | 2,217 |
| Avg. completion time (secs) | 634 | 874 | 395 |
| Machine years used | 217 | 2,002 | 11,081 |
| map input data (TB) | 3,288 | 52,254 | 403,152 |
| map output data (TB) | 758 | 6,743 | 34,774 |
| reduce output data (TB) | 193 | 2,970 | 14,018 |
| Avg. machines per job | 157 | 268 | 394 |
| Unique implementations | |||
| map | 395 | 1958 | 4083 |
| reduce | 269 | 1208 | 2418 |
{ The screenshot illustrates a Google rack from 2007. I don't remember the exact source of the image, but it's likely to be a presentation. }
时间上溯到136亿年前,银河系在宇宙中诞生了。
从大爆炸横空出世的宇宙,这时只有10亿岁。这样一个年轻的宇宙是氢和氦的海洋,它让银河系的第一批恒星充满了大量的氢和氦。
这是“黄金时代”的恒星。这第一批恒星猛烈地燃烧着,把四个氢原子核转变成一个氦原子核。它们的生命像夏花一样绚烂而短暂,当氢被烧完的时候,这些大熔炉骤然升温,开始把氦原子核聚合成碳和氧。当氦也燃烧殆尽的时候,又开始燃烧碳和氧,最后燃烧硅,从而形成了大量的铁。当硅也燃烧完之后,这些恒星便成为超新星,化作一团璀璨的焰火,用猛烈的爆炸结束了自己可歌可泣的生命。
随后诞生了属于“白银时代”的第二批恒星。它们斯斯文文地燃烧着,重复着几乎和第一批恒星一样的冶炼元素的过程。只是,一些恒星等不到硅燃烧的阶段就熄灭了,它们变成了白矮星,像幽灵一样在黑暗冰冷的宇宙中踽踽独行;另一些恒星则再次重复了“黄金时代”恒星辉煌的晚年,它们在发生超新星爆炸前的一刹那燃烧硅,为宇宙生出了更多的铁的“灰烬”。
46亿年前,一颗“白银时代”的超新星爆炸,释放出的能量扰动了它周边的一团含铁的星云,于是这团星云开始收缩、分化,在它中间生成了一颗属于“青铜时代”的银河系第三批恒星——太阳。在太阳的周围,众多含铁的星际尘埃也不断碰撞、汇聚,逐渐凝成了八大行星和众多的小天体。地球,就是这八大行星中距太阳第三远的那颗大行星。
原始地球是一团炽热的熔融之球。在这团熔岩逐渐冷却的过程中,原先混在一起的各种化学元素,便因为彼此的秉性不同而分道扬镳。铁,这种表面热情、内心却冷若冰霜的元素,大部分和它的同伴镍一起,挟持着大量的贵金属,沉降到地球的中心,形成地核——也就是地球的那颗至今滚烫而转动不息的心。
如果地球上所有的铁都沉降到地核里,那么也就不会有这本书后面的一切故事了。幸好,还有一部分铁和其他元素携手,形成了和金属铁性质迥异的轻质化合物,这些轻质化合物冉冉上升,成为构成地幔的重要成分。
地幔就像一壶正在加热的表面还浮着一层冰的水,它下面的地核是加热器,上面那一层已经冷凝成坚硬的岩石的薄层就是地壳。就像水加热时会对流一样,地幔内部也有大大小小的对流,地幔物质便在这永无止息的对流中有上有下地缓慢运动着。当上升的地幔热流——也就是岩浆——到达地壳的底部时,要么将它撕裂或顶穿,于是形成壮观的火山喷发,要么只能渗透到它的下层裂缝中,于是形成侵入的岩浆岩。当岩浆中的铁含量比较高时,在火山喷发之后便会形成火山岩浆铁矿,而在岩浆侵入地壳之后,则形成侵入岩浆铁矿。
有时候,在侵入地壳的岩浆温度降低之后,会从中分离出溶解有许多元素的热水来。这些热水比岩浆更容易钻进地壳的裂缝中,一边钻一边把周边的岩石泡得沾上了新的元素,就像腌菜时把蔬菜泡得沾满了盐一样;最后,在这些热水的温度降低之后,还溶解在其中的物质又纷纷析出,形成新的岩石。当热水中的铁含量比较高时,浸泡周边岩石形成的铁矿叫做接触交代铁矿,遇冷析出的铁矿,则叫做热液铁矿。
在地壳内部受到这样的火和热水的锤炼之时,地壳外部却在受着冷水的洗礼。在水的作用下,一些岩石中的可溶成分逐渐被溶走,其中的铁却留了下来,逐渐富集成残余铁矿。但更多的时候,连铁也被溶走,随水注入河流,直到百川归流入海,这些铁才在海中沉积下来,形成沉积铁矿。上面的各种铁矿,如果在后来又受到岩浆的烘烤,在成分上发生一定的变化,则不管原来成因为何,统统叫做变质铁矿。
现在在地球上能找到的最老的岩石,年龄为38亿年。38亿年来,铁,这种刚强与柔弱并存的元素,便在这种种的地质活动中,逐渐在地表或靠近地表的岩层中富集,悄无声息地形成了众多的铁矿。是的,在人类诞生之前,天下之铁,无论聚散,都是悄无声息。
20万年前,智人出现。
从此,铁的历史不再悄无声息,却充满了喧嚣嘈杂,甚至刀光剑影。
2008.01.09
Hi Friends, we’re excited to be launching our 2008 Release here shortly! After working on several bugs and our well awaited mobile version, we’re excited to be delivering this special installment of Zooomr to everyone.
There will be some upload outages as marked above as we are moving some data to our Japanese Data Centers, but we plan to have both Web and Static photos online for your viewing pleasure.
Our team and myself have been working hard here for the last 5 months in Japan for everyone’s benefit. I’m glad that we’ve been able to save Zooomr from a money crisis that could have killed Zooomr for good — but, instead, we have found investments and are moving full speed ahead for you guys — our users.
We’ve also launched the Zooomr Knowledge Center where you can find more information about our upcoming release, as well as submit bugs. We’re trying our best to keep everyone in the loop.
Please be safe — we’re only 9 days into the year and moving strong!
kristopher
Tue 08 January, 2008
从 Greg Linden 的文章看到的数据:Google 的 MapReduce 平均每天处理 20 Petabytes 的数据。每天能跑完 10 万个工作任务。光是 07 年 9 月,就用掉了 11081 个"机器年" ,跑了 220 万个 Mapreduce 任务。这个计算能力是惊人的。
Yahoo! 也用 Hadoop 实现了 Mapreduce , 我个人感觉和 Google 可能还有一段距离。光有计算环境还不行,还要有应用程序来实现功能,Google 已经实现了超过 1 万个应用程序,Yahoo! 有多少呢?
这方面估计微软更没戏了,要是弄个不包括 "Window" 的 Windows 服务器集群估计还能差不多,否则,光是一个视窗要耗费多少计算资源? 如果服务器规模是几万、几十万台,计算能力的浪费是惊人的。微软的对抗计划是 Dryad.
所以说啊,Google 的计算能力仍是独步武林,虽然有不服气的,但有什么办法? 这方面 Google 就是强啊
--EOF-- 补充: 更多的数据(来源):感谢fcicq,他的new 30 days系列为我们带来了不少好文章。
今天想分析的是这篇Bash Pitfalls, 介绍了一些bash编程中的经典错误。fcicq说可能不适合初学者,而我认为, 正是bash编程的初学者才应该好好阅读一下这篇文章。
下面就逐个分析一下这篇文章中提到的错误。不是完全的翻译,有些没用的话就略过了, 有些地方则加了些注释。
- 1. for i in `ls *.mp3`
- 2. cp $file $target
- 3. [ $foo = "bar" ]
- 4. cd `dirname "$f"`
- 5. [ "$foo" = bar && "$bar" = foo ]
- 6. [[ $foo > 7 ]]
- 7. grep foo bar | while read line; do ((count++) ); done
- 8. if [grep foo myfile]
- 9. if [bar="$foo"]
- 10. if [ [ a = b ] && [ c = d ] ]
- 11. cat file | sed s/foo/bar/ > file
- 12. echo $foo
- 13. $foo=bar
- 14. foo = bar
- 15. echo <<EOF
- 16. su -c 'some command'
- 17. cd /foo; bar
- 18. [ bar == "$foo" ]
- 19. for i in {1..10}; do ./something &; done
- 20. cmd1 && cmd2 || cmd3
- 21. UTF-8的BOM(Byte-Order Marks)问题
- 22. echo "Hello World!"
- 23. for arg in $*
- 24. function foo()
1. for i in `ls *.mp3`
常见的错误写法:
for i in `ls *.mp3`; do # Wrong!
为什么错误呢?因为for...in语句是按照空白来分词的,包含空格的文件名会被拆成多个词。 如遇到 01 - Don't Eat the Yellow Snow.mp3 时,i的值会依次取 01,-,Don't,等等。
用双引号也不行,它会将ls *.mp3的全部结果当成一个词来处理。
for i in "`ls *.mp3`"; do # Wrong!
正确的写法是
for i in *.mp3; do
2. cp $file $target
这句话基本上正确,但同样有空格分词的问题。所以应当用双引号:
cp "$file" "$target"
但是如果凑巧文件名以 - 开头,这个文件名会被 cp 当作命令行选项来处理,依旧很头疼。可以试试下面这个。
cp -- "$file" "$target"
运气差点的再碰上一个不支持 -- 选项的系统,那只能用下面的方法了:使每个变量都以目录开头。
for i in ./*.mp3; do cp "$i" /target ...
3. [ $foo = "bar" ]
当$foo为空时,上面的命令就变成了
[ = "bar" ]
类似地,当$foo包含空格时:
[ multiple words here = "bar" ]
两者都会出错。所以应当用双引号将变量括起来:
[ "$foo" = bar ] # 几乎完美了。
但是!当$foo以 - 开头时依然会有问题。 在较新的bash中你可以用下面的方法来代替,[[ 关键字能正确处理空白、空格、带横线等问题。
[[ $foo = bar ]] # 正确
旧版本bash中可以用这个技巧(虽然不好理解):
[ x"$foo" = xbar ] # 正确
或者干脆把变量放在右边,因为 [ 命令的等号右边即使是空白或是横线开头,依然能正常工作。 (Java编程风格中也有类似的做法,虽然目的不一样。)
[ bar = "$foo" ] # 正确
4. cd `dirname "$f"`
同样也存在空格问题。那么加上引号吧。
cd "`dirname "$f"`"
问题来了,是不是写错了?由于双引号的嵌套,你会认为`dirname 是第一个字符串,`是第二个字符串。 错了,那是C语言。在bash中,命令替换(反引号``中的内容)里面的双引号会被正确地匹配到一起, 不用特意去转义。
$()语法也相同,如下面的写法是正确的。
cd "$(dirname "$f")"
5. [ "$foo" = bar && "$bar" = foo ]
[ 中不能使用 && 符号!因为 [ 的实质是 test 命令,&& 会把这一行分成两个命令的。应该用以下的写法。
[ bar = "$foo" -a foo = "$bar" ] # Right! [ bar = "$foo" ] && [ foo = "$bar" ] # Also right! [[ $foo = bar && $bar = foo ]] # Also right!
6. [[ $foo > 7 ]]
很可惜 [[ 只适用于字符串,不能做数字比较。数字比较应当这样写:
(( $foo > 7 ))
或者用经典的写法:
[ $foo -gt 7 ]
但上述使用 -gt 的写法有个问题,那就是当 $foo 不是数字时就会出错。你必须做好类型检验。
这样写也行。
[[ $foo -gt 7 ]]
7. grep foo bar | while read line; do ((count++) ); done
由于格式问题,标题中我多加了一个空格。实际的代码应该是这样的:
grep foo bar | while read line; do ((count++)); done # 错误!
这行代码数出bar文件中包含foo的行数,虽然很麻烦(等同于grep -c foo bar或者 grep foo bar | wc -l)。 乍一看没有问题,但执行之后count变量却没有值。因为管道中的每个命令都放到一个新的子shell中执行, 所以子shell中定义的count变量无法传递出来。
8. if [grep foo myfile]
初学者常犯的错误,就是将 if 语句后面的 [ 当作if语法的一部分。实际上它是一个命令,相当于 test 命令, 而不是 if 语法。这一点C程序员特别应当注意。
if 会将 if 到 then 之间的所有命令的返回值当作判断条件。因此上面的语句应当写成
if grep foo myfile > /dev/null; then
9. if [bar="$foo"]
同样,[ 是个命令,不是 if 语句的一部分,所以要注意空格。
if [ bar = "$foo" ]
10. if [ [ a = b ] && [ c = d ] ]
同样的问题,[ 不是 if 语句的一部分,当然也不是改变逻辑判断的括号。它是一个命令。可能C程序员比较容易犯这个错误?
if [ a = b ] && [ c = d ] # 正确
11. cat file | sed s/foo/bar/ > file
你不能在同一条管道操作中同时读写一个文件。根据管道的实现方式,file要么被截断成0字节,要么会无限增长直到填满整个硬盘。 如果想改变原文件的内容,只能先将输出写到临时文件中再用mv命令。
sed 's/foo/bar/g' file > tmpfile && mv tmpfile file
12. echo $foo
这句话还有什么错误码?一般来说是正确的,但下面的例子就有问题了。
MSG="Please enter a file name of the form *.zip" echo $MSG # 错误!
如果恰巧当前目录下有zip文件,就会显示成
Please enter a file name of the form freenfss.zip lw35nfss.zip
所以即使是echo也别忘记给变量加引号。
13. $foo=bar
变量赋值时无需加 $ 符号——这不是Perl或PHP。
14. foo = bar
变量赋值时等号两侧不能加空格——这不是C语言。
15. echo <<EOF
here document是个好东西,它可以输出成段的文字而不用加引号也不用考虑换行符的处理问题。 不过here document输出时应当使用cat而不是echo。
# This is wrong: echo <<EOF Hello world EOF # This is right: cat <<EOF Hello world EOF
16. su -c 'some command'
原文的意思是,这条基本上正确,但使用者的目的是要将 -c 'some command' 传给shell。 而恰好 su 有个 -c 参数,所以su 只会将 'some command' 传给shell。所以应该这么写:
su root -c 'some command'
但是在我的平台上,man su 的结果中关于 -c 的解释为
-c, --commmand=COMMAND
pass a single COMMAND to the shell with -c
也就是说,-c 'some command' 同样会将 -c 'some command' 这样一个字符串传递给shell, 和这条就不符合了。不管怎样,先将这一条写在这里吧。
17. cd /foo; bar
cd有可能会出错,出错后 bar 命令就会在你预想不到的目录里执行了。所以一定要记得判断cd的返回值。
cd /foo && bar
如果你要根据cd的返回值执行多条命令,可以用 ||。
cd /foo || exit 1; bar baz
关于目录的一点题外话,假设你要在shell程序中频繁变换工作目录,如下面的代码:
find ... -type d | while read subdir; do cd "$subdir" && whatever && ... && cd - done
不如这样写:
find ... -type d | while read subdir; do (cd "$subdir" && whatever && ...) done
括号会强制启动一个子shell,这样在这个子shell中改变工作目录不会影响父shell(执行这个脚本的shell), 就可以省掉cd - 的麻烦。
你也可以灵活运用 pushd、popd、dirs 等命令来控制工作目录。
18. [ bar == "$foo" ]
[ 命令中不能用 ==,应当写成
[ bar = "$foo" ] && echo yes [[ bar == $foo ]] && echo yes
19. for i in {1..10}; do ./something &; done
& 后面不应该再放 ; ,因为 & 已经起到了语句分隔符的作用,无需再用;。
for i in {1..10}; do ./something & done
20. cmd1 && cmd2 || cmd3
有人喜欢用这种格式来代替 if...then...else 结构,但其实并不完全一样。如果cmd2返回一个非真值,那么cmd3则会被执行。 所以还是老老实实地用 if cmd1; then cmd2; else cmd3 为好。
21. UTF-8的BOM(Byte-Order Marks)问题
UTF-8编码可以在文件开头用几个字节来表示编码的字节顺序,这几个字节称为BOM。但Unix格式的UTF-8编码不需要BOM。 多余的BOM会影响shell解析,特别是开头的 #!/bin/sh 之类的指令将会无法识别。
MS-DOS格式的换行符(CRLF)也存在同样的问题。如果你将shell程序保存成DOS格式,脚本就无法执行了。
$ ./dos -bash: ./dos: /bin/sh^M: bad interpreter: No such file or directory
22. echo "Hello World!"
交互执行这条命令会产生以下的错误:
-bash: !": event not found
因为 !" 会被当作命令行历史替换的符号来处理。不过在shell脚本中没有这样的问题。
不幸的是,你无法使用转义符来转义!:
$ echo "hi\!" hi\!
解决方案之一,使用单引号,即
$ echo 'Hello, world!'
如果你必须使用双引号,可以试试通过 set +H 来取消命令行历史替换。
set +H echo "Hello, world!"
23. for arg in $*
$*表示所有命令行参数,所以你可能想这样写来逐个处理参数,但参数中包含空格时就会失败。如:
#!/bin/bash # Incorrect version for x in $*; do echo "parameter: '$x'" done $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg' parameter: '1' parameter: 'arg2' parameter: 'arg3'
正确的方法是使用 "$@"。
#!/bin/bash # Correct version for x in "$@"; do echo "parameter: '$x'" done $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg 1' parameter: 'arg2' parameter: 'arg3'
在 bash 的手册中对 $* 和 $@ 的说明如下:
* Expands to the positional parameters, starting from one.
When the expansion occurs within double quotes, it
expands to a single word with the value of each parameter
separated by the first character of the IFS special variable.
That is, "$*" is equivalent to "$1c$2c...",
@ Expands to the positional parameters, starting from one.
When the expansion occurs within double quotes, each
parameter expands to a separate word. That is, "$@"
is equivalent to "$1" "$2" ...
可见,不加引号时 $* 和 $@ 是相同的,但"$*" 会被扩展成一个字符串,而 "$@" 会 被扩展成每一个参数。
24. function foo()
在bash中没有问题,但其他shell中有可能出错。不要把 function 和括号一起使用。 最为保险的做法是使用括号,即
foo() {
...
}









