成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

帶你了解Shell腳本編程陷阱

系統(tǒng) Linux
Ruby 版本的代碼雖然不是那么長(zhǎng),也并不復(fù)雜。但是 shell 版是如此簡(jiǎn)單,我甚至不用實(shí)際測(cè)試就可以確保它是正確的。而 Ruby 版的我就沒(méi)法確定它不會(huì)出錯(cuò)了,必須得測(cè)試一下。而且它要長(zhǎng)一倍,看起來(lái)也更復(fù)雜。

[[263427]]

 Shell 腳本很棒,你可以非常輕松地寫(xiě)出有用的東西來(lái)。甚至像是下面這個(gè)傻瓜式的命令:

  1. # 用含有 Go 的詞匯起名字:
  2. $ grep -i ^go /usr/share/dict/* | cut -d: -f2 | sort -R | head -n1
  3. goldfish

如果用其他編程語(yǔ)言,就需要花費(fèi)更多的腦力,用多行代碼實(shí)現(xiàn),比如用 Ruby 的話:

  1. puts(Dir['/usr/share/dict/*-english'].map do |f|
  2. File.open(f)
  3. .readlines
  4. .select { |l| l[0..1].downcase == 'go' }
  5. end.flatten.sample.chomp)

Ruby 版本的代碼雖然不是那么長(zhǎng),也并不復(fù)雜。但是 shell 版是如此簡(jiǎn)單,我甚至不用實(shí)際測(cè)試就可以確保它是正確的。而 Ruby 版的我就沒(méi)法確定它不會(huì)出錯(cuò)了,必須得測(cè)試一下。而且它要長(zhǎng)一倍,看起來(lái)也更復(fù)雜。

這就是人們使用 Shell 腳本的原因,它簡(jiǎn)單卻實(shí)用。下面是另一個(gè)例子:

  1. curl https://nl.wikipedia.org/wiki/Lijst_van_Nederlandse_gemeenten |
  2. grep '^<li><a href=' |
  3. sed -r 's|<li><a href="/wiki/.+" title=".+">(.+)</a>.*</li>|\1|' |
  4. grep -Ev '(^Tabel van|^Lijst van|Nederland)'

這個(gè)腳本可以從維基百科上獲取荷蘭基層政權(quán)的列表。幾年前我寫(xiě)了這個(gè)臨時(shí)的腳本,用來(lái)快速生成一個(gè)數(shù)據(jù)庫(kù),到現(xiàn)在它仍然可以正常運(yùn)行,當(dāng)時(shí)寫(xiě)它并沒(méi)有花費(fèi)我多少精力。但要用 Ruby 完成同樣的功能則會(huì)麻煩得多。


現(xiàn)在來(lái)說(shuō)說(shuō) shell 的缺點(diǎn)吧。隨著代碼量的增加,你的腳本會(huì)變得越來(lái)越難以維護(hù),但你也不會(huì)想用別的語(yǔ)言重寫(xiě)一遍,因?yàn)槟阋呀?jīng)在這個(gè) shell 版上花費(fèi)了很多時(shí)間。

我把這種情況稱(chēng)為“Shell 腳本編程陷阱”,這是沉沒(méi)成本謬論的一種特例(LCTT 譯注:“沉沒(méi)成本謬論”是一個(gè)經(jīng)濟(jì)學(xué)概念,可以簡(jiǎn)單理解為,對(duì)已經(jīng)投入的成本可能被浪費(fèi)而念念不忘)。

實(shí)際上許多腳本會(huì)增長(zhǎng)到超出預(yù)期的大小,你經(jīng)常會(huì)花費(fèi)過(guò)多的時(shí)間來(lái)“修復(fù)某個(gè) bug”,或者“添加一個(gè)小功能”。如此循環(huán)往復(fù),讓人頭大。

如果你從一開(kāi)始就使用 Python、Ruby 或是其他類(lèi)似的語(yǔ)言來(lái)寫(xiě)這個(gè)程序,你可能會(huì)在寫(xiě)***版的時(shí)候多花些時(shí)間,但以后維護(hù)起來(lái)就容易很多,bug 也肯定會(huì)少很多。

以我的 packman.vim 腳本為例。它起初只包含一個(gè)簡(jiǎn)單的用來(lái)遍歷所有目錄的 for 循環(huán),外加一個(gè) git pull,但在這之后就剎不住車(chē)了,它現(xiàn)在有 200 行左右的代碼,這肯定不能算是最復(fù)雜的腳本,但假如我一上來(lái)就按計(jì)劃用 Go 來(lái)編寫(xiě)它的話,那么增加一些像“打印狀態(tài)”或者“從配置文件里克隆新的 git 庫(kù)”這樣的功能就會(huì)輕松很多;添加“并行克隆”的支持也幾乎不算個(gè)事兒了,而在 shell 腳本里卻很難實(shí)現(xiàn)(盡管不是不可能)。事后看來(lái),我本可以節(jié)省時(shí)間,并且獲得更好的結(jié)果。

出于類(lèi)似的原因,我很后悔寫(xiě)出了許多這樣的 shell 腳本,而我在 2018 年的新年誓言就是不要再犯類(lèi)似的錯(cuò)誤了。

附錄:?jiǎn)栴}匯總

需要指出的是,shell 編程的確存在一些實(shí)際的限制。下面是一些例子:

  • 在處理一些包含“空格”或者其他“特殊”字符的文件名時(shí),需要特別注意細(xì)節(jié)。絕大多數(shù)腳本都會(huì)犯錯(cuò),即使是那些經(jīng)驗(yàn)豐富的作者(比如我)編寫(xiě)的腳本,因?yàn)樘菀讓?xiě)錯(cuò)了,只添加引號(hào)是不夠的
  • 有許多所謂“正確”和“錯(cuò)誤”的做法。你應(yīng)該用 which 還是 command?該用 $@ 還是 $*,是不是得加引號(hào)?你是該用 cmd $arg 還是 cmd "$arg"?等等等等。
  • 你沒(méi)法在變量里存儲(chǔ)空字節(jié)(0x00);shell 腳本處理二進(jìn)制數(shù)據(jù)很麻煩。
  • 雖然你可以非常快速地寫(xiě)出有用的東西,但實(shí)現(xiàn)更復(fù)雜的算法則要痛苦許多,即使用 ksh/zsh/bash 擴(kuò)展也是如此。我上面那個(gè)解析 HTML 的腳本臨時(shí)用用是可以的,但你真的不會(huì)想在生產(chǎn)環(huán)境中使用這種腳本。
  • 很難寫(xiě)出跨平臺(tái)的通用型 shell 腳本。/bin/sh 可能是 dash 或者 bash,不同的 shell 有不同的運(yùn)行方式。外部工具如 grepsed 等,不一定能支持同樣的參數(shù)。你能確定你的腳本可以適用于 Linux、macOS 和 Windows 的所有版本嗎(無(wú)論是過(guò)去、現(xiàn)在還是將來(lái))?
  • 調(diào)試 shell 腳本會(huì)很難,特別是你眼中的語(yǔ)法可能會(huì)很快變得記不清了,并不是所有人都熟悉 shell 編程的語(yǔ)境。
  • 處理錯(cuò)誤會(huì)很棘手(檢查 $? 或是 set -e),排查一些超過(guò)“出了個(gè)小錯(cuò)”級(jí)別的復(fù)雜錯(cuò)誤幾乎是不可能的。
  • 除非你使用了 set -u,變量未定義將不會(huì)報(bào)錯(cuò),而這會(huì)導(dǎo)致一些“搞笑事件”,比如 rm -r ~/$undefined 會(huì)刪除用戶(hù)的整個(gè)家目錄(瞅瞅 Github 上的這個(gè)悲劇)。
  • 所有東西都是字符串。一些 shell 引入了數(shù)組,能用,但是語(yǔ)法非常丑陋和費(fèi)解。帶分?jǐn)?shù)的數(shù)字運(yùn)算仍然難以應(yīng)付,并且依賴(lài)像 bcdc 這樣的外部工具($(( .. )) 這種方式只能對(duì)付一下整數(shù))。

反饋

你可以發(fā)郵件到 martin@arp242.net,或者在 GitHub 上創(chuàng)建 issue 來(lái)向我反饋,提問(wèn)等。


責(zé)任編輯:龐桂玉 來(lái)源: Linux中國(guó)
相關(guān)推薦

2019-09-27 09:40:06

ElvishShellLinux

2019-03-26 10:50:22

Python面向?qū)ο?/a>編程語(yǔ)言

2011-09-27 13:52:41

2020-06-17 10:42:54

shellshell腳本Linux

2019-08-06 09:00:00

JavaScript函數(shù)式編程前端

2022-05-13 16:21:38

javascrip腳本SVG

2020-12-23 08:12:08

javascriptSVG腳本SVG元素

2020-10-21 11:55:44

Shell編程語(yǔ)言Linux

2018-06-08 08:50:35

編程語(yǔ)言并發(fā)編程

2022-09-26 11:30:40

MQTT協(xié)議客戶(hù)端協(xié)議

2010-07-05 16:20:32

NetBEUI協(xié)議

2024-11-07 16:09:53

2010-06-23 15:55:36

Linux Bash

2020-12-31 12:16:49

SAP云計(jì)算SAP產(chǎn)品

2021-02-03 16:22:43

新基建SAP

2010-09-02 16:59:35

資源預(yù)留協(xié)議

2021-12-10 10:29:07

在線客服系統(tǒng)

2019-11-05 10:18:04

RPM包RPMLinux

2021-05-31 14:22:56

物聯(lián)網(wǎng)物聯(lián)網(wǎng)安全

2018-03-01 16:25:52

Linux內(nèi)核內(nèi)存管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 午夜三区 | 国产精品九九视频 | 在线一区视频 | 91深夜福利视频 | 久久久成人动漫 | 一区二区久久 | www.日韩 | 亚洲美女一区二区三区 | 日韩久久精品电影 | 男女午夜激情视频 | 日韩在线免费视频 | 亚洲视频免费在线观看 | 色www精品视频在线观看 | 国产一区 | av中文字幕在线播放 | 欧美1区| 国产小视频精品 | 天天亚洲 | 久久久精品一区 | 99热在这里只有精品 | 国产在线视频一区二区 | 日韩一级一区 | 国产乱人伦 | 日本不卡一区二区三区 | 五月婷六月丁香 | 成年视频在线观看福利资源 | 日韩欧美大片 | 国产精品久久久久免费 | 一级特黄视频 | 久久久国产精品一区 | 国内自拍偷拍视频 | 精品久久久久久 | 亚洲不卡视频 | www312aⅴ欧美在线看 | av福利网 | 免费一区二区 | 青青久草 | 中文字幕免费在线 | 亚洲精品久久久一区二区三区 | 国产99久久精品一区二区永久免费 | 一区二区日韩 |