寫給前端程式設計師的命令列入門

chuck發表於2022-07-11

前言

諸如React、Angular、Vue等現代前端框架嚴重依賴於終端。如果你還不習慣使用命令列介面,你將很難執行本地開發伺服器或構建你的應用程式。

諷刺的是,我們的整個工作都建立在圖形化使用者介面上,但我們在開發中使用的工具卻大多是基於命令列的。

除非你有電腦科學背景,或者在上世紀80年代使用計算機長大,否則你大概率不會擁有豐富的終端經驗。然而,大部分線上資源都假定你已經對此十分熟練了。

要成為一個終端大佬需要多年的練習,但好訊息是:我們可以走捷徑。我們並不真的需要知道可以用終端做的絕大多數的事情。如果我們專注於最重要的關鍵基礎知識,我們應該能夠在很短的時間內適應命令列。✨

這也是這篇文章想要介紹的內容。它是使用現代JS框架(如React)所需的,終端基礎知識的一門手冊,有了它你就可以轉到有趣的事情上:構建使用者介面。

我還將分享我從終端中獲得的技巧和竅門,這些東西我多希望在我剛開始工作時就有人能告訴我。

準備工作

好了,在開始之前,我們還需要做兩件事情。

首先,我們需要一些終端軟體。終端軟體是執行命令列環境的應用程式。

幾乎每個作業系統都會有一個內建的終端,比如MacOS的Terminal.app,或者Windows的Command Prompt ,這些應用程式都可以工作,但都不太讓人滿意。大多數開發者會選擇使用其他軟體。

只要你使用的是現代技術,那麼選擇使用哪款終端應用就沒那麼重要。因此,這裡我有兩個主要建議:

  1. Hyper。Hyper是現代的,多平臺的終端應用程式。它顏值很高,還帶有一些時髦的功能,比如可以分為多個視窗。
  2. 如果你使用 VS Code 作為程式碼編輯器,那麼 VS Code 已經內建了一個強大的、現代化的終端。這非常棒,意味著程式碼和終端可以在一個應用內並排執行。你可以在 VS Code 中通過選擇 檢視→終端 來開啟終端。

在這篇文章中,我將使用Hyper來展示所有的例子。

到這裡,選擇好了終端應用才完成了一半。我們還需要確保執行正確的shell語言。

當我們在終端輸入命令並回車時,命令會通過shell語言進行解釋執行。它本質上是在終端應用程式中執行的環境。

最流行的shell語言是Bash。當你在網上看到命令列說明時,這些說明很有可能是基於Bash的。這是大多數Linux發行版使用的預設shell語言。

現代的MacOS版本自帶的Zsh,而不是Bash。但Zsh與Bash十分類似:它們屬於同一家族,幾乎共享所有相同的命令。從目的角度出發,它們是可以互換使用的。

如果你使用的是Linux或者MacOS,那就可以正式開始了。你的計算機已經在使用一種"行業標準"的shell語言。然而,如果你使用的是Windows,我們還有一點工作要做。

形象的比喻

你是否曾經在你的瀏覽器中開啟開發者控制檯,來執行一些任意的JavaScript程式碼?

在這種情況下,應用程式是Chrome,而語言是JavaScript。Chrome提供了命令列介面,但當我們執行命令時,這些命令是用JavaScript解釋的。

當涉及到終端時,它也是同樣的道理。像Hyper這樣的終端應用可能正在執行Bash shell語言。與瀏覽器不同的是,終端應用可以在多種shell語言之間進行切換。

Windows設定

首先,我需要承認的是,當涉及到Windows開發時,我並不是專業人士。請對我接下來說的每一句話持保留態度。

Bash是基於Linux的shell語言,它不會在Windows上原生執行。幸運的是,較新版本的Windows具有安裝和執行Linux的能力,就像Linux是一種應用程式一樣。這被稱為Windows Subsystem for Linux,通常縮寫為WSL。

這裡有一個教程,介紹了所需的步驟:在Windows中,如何安裝並使用Zsh

我自己執行了這些步驟,雖然這有點乏味,但它確實起作用了!

一旦設定好之後,你就可以配置終端來使用Bash或者Zsh。這裡有一些關於配置Hyper來使用Zsh的介紹。

如果你在這些步驟中遇到了麻煩,這裡有些其他的解決方案你可以試一試。一個流行的方法是Git Bash,它允許你在Windows內使用模擬技術執行Bash。

歸根結底,你如何做到並不重要。重要的是,你能夠在Windows中使用Bash或Zsh。

Hello World

當你第一次開啟終端應用時,你會遇到這個相當無助的介面:

init.png

你的終端看起來可能會有些不同,這取決於你使用的作業系統、終端應用、shell語言。總的來說,你可能會看到一行文字,和一堆空白空間。

這一行文字被稱為提示。它之所以被稱為"提示",是因為它在等待你提供某種指令。

我們的第一個命令,輸入文字echo "hello world"並回車:

echo.png

語法有一點不同,但你可以認為命令就是內建的JavaScript函式。echo命令與JavaScript中的console.log函式非常相似。

跟函式一樣,命令也可以接收引數。在本例中,echo接收了一個引數,並輸出了字串。

當我們按下回車時,命令就會立即執行,值也會被列印。下一行會呈現一個新的提示,讓我們知道它已經準備好接收下一個指令。

就像這樣,你已經成功執行了第一條終端命令。

跳過$

在閱讀NPM包的安裝說明時,你會經常看到這樣的內容:

$ npm install some-package

如果你試圖執行這一段文字,你會得到一個錯誤。這是因為美元符號($)不應該被包括在內。你應該在美元符號之後輸入所有內容。

為什麼安裝說明會包含一個隨機的符號,而這個符號實際上並不是命令的一部分?好吧,在Bash shell語言中,$是提示符,顯示在提示的末尾。

它本質上是一個符號,並說道:嘿,這裡的東西要在終端執行!

儘管在許多現代shell語言(如Zsh)中,$實際上並不作為提示字元使用,但其象徵意義仍然存在,比如儲存的圖示是一個軟盤形狀,儘管我們已經幾十年沒有使用軟盤了。

導航

終端的主要目的是能夠讓你在檔案系統中移動檔案,並開啟/執行東西。它本質上是我們每天使用的GUI檔案資源管理器(如Finder、Windows Explorer)的基於文字的版本。

為了幫助我們全方位導航,有很多終端命令可以使用。讓我們來探索其中的一些。

pwd命令代表著 Print Working Directory ,它有點像購物中心地圖上的“你在這裡”箭頭。它會告訴你當前所處的位置:

pwd.png

當你開啟終端應用時,你通常會被扔進 ”home” 目錄,該目錄包含了 Documents 和 Desktop 目錄。在我的機器上,這個目錄位於/Users/joshu

使用ls(List的簡寫)命令,你可以檢視當前目錄下的內容:

ls.png

在我的終端上,目錄是加粗的,並以淺水色展示。而單個檔案是普通文字粗細,以白色展示。

我們可以使用cd(Change Directory)命令來移動檔案系統:

cd.png

這相當於在GUI檔案資源管理器中雙擊 "stuff" 目錄。

需要注意的是,提示從波浪字元(~)變成了 "stuff" 。在Zsh shell語言中,預設的提示由一個箭頭和當前目錄的名稱組成,比如說"→ Documents"。 等一下,為什麼之前是一個波浪字元,而不是父目錄的名稱?在MacOS和Linux上,波浪字元是使用者home目錄的縮寫。在我的機器上,"~"相當於"/Users/joshu"。 很容易誤以為"~"是一個提示字元,就像Bash中的"$"一樣。

如果我想返回上一級,返回到home目錄該怎麼辦?我也可以使用cd命令來達到目的,但是要帶有兩個點(..) 。

cd...png

在大多數shell語言中,點字元(.)具有著特殊的含義:

  • 一個點(.)表示當前目錄。
  • 兩個點(..)表示父級目錄。

如果你在JavaScript中使用過模組系統,你可能已經熟悉了這個慣例。它使用同樣的符號,用兩個點來表示父級目錄:

import { COLORS } from '../../constants';
import Button from '../Button';

關於cd命令,有件很重要的事情需要知道。那就是cd可以接收復雜的路徑。終端的初學者往往會像在GUI檔案資源管理器中那樣,一步一步地走:

cd-step-by-step.png

這樣做是沒問題的,但是需要花費大量額外的工作。我們可以像這樣一步到位地完成同樣的路徑跳轉:

cd-single-bound.png

Tab自動補全

終端最令人生畏的事情之一是,它不會給你任何線索或提示。使用GUI檔案資源管理器,你可以看到檔案和資料夾的完整列表,以重新整理你的記憶並幫助你找到你要找的東西。

如果你想按照我的建議使用cd,從一個地方一下子跳到另一個地方,看起來你可能需要一個照相式的記憶。除非你記住路徑鏈中每個目錄的確切名稱,否則你無法做到這一點,對不對?

幸運的是,一個非常方便的技巧使這一切變得更加容易:tab自動補全。

在有效使用終端時,Tab鍵是至關重要的。除了這裡展示的導航技巧外,我們還可以用Tab鍵來自動完成Git分支,或者補全命令的剩餘部分。

試試在不同情況下按下Tab鍵,看看會發生什麼吧。

Visual自動補全

如果你發現很難掌握Tab的自動補全,你可能會對Fig感興趣。Fig是一個終端外掛,它增加了編輯器風格的自動補全。

我也剛剛開始嘗試使用Warp,一個為速度和使用者體驗而建立的現代終端。在寫這篇文章的時候,它是MacOS獨有的,但他們確實計劃在測試版之後將其移植到Windows和Linux。

我們正生活在一個終端復興的時代,有很多工具的目的是使它不那麼令人生畏。

標誌

早些時候,我提到過Bash/Zsh裡的命令,就像JavaScript裡的函式。當涉及到標誌時,這個類比就不太適用了。

標誌是修飾符,以預先定義的方式調整命令的行為。

舉例來說,讓我們來看一看rm命令。該命令允許我們刪除單個檔案:

rm.png

我們沒有得到任何形式的確認,但如果我們再次檢視,會發現theme-song.mp3檔案確實已被刪除。

再繼續之前,我應該警告你:終端可能相當不寬容。 rm命令沒有 "你確定嗎?"的確認提示。也沒有任何撤銷操作。當你使用rm刪除檔案,它不會進入回收站/垃圾桶。它被永久地、不可逆轉地刪除。 這是終端的一個共同主題。沒有太多的安全機制。因此,在使用rm這樣的命令時,請務必小心。

如果你嘗試在目錄上使用rm命令,你會得到一個錯誤:

rm-error.png

預設情況下,rm只可以刪除單個檔案,但我們可以使用r標誌來改變規則:

rm-r.png

r標誌代表著遞迴(recursive)。它將刪除stuff目錄在內的任何東西,stuff目錄內的目錄內的任何東西,stuff目錄內的目錄內的任何東西,以此類推。

你也可能遇到一些檔案許可權問題。由於這個原因,f標誌(Force)也是很常用的。我們可以用一個破折號將多個標誌分組,就像這樣:

rm-rf.png

標誌有很多形狀和大小。按照慣例,標誌通常有一個簡短的形式(例如:-f)和一個完整的形式(--force)。完整形式通常使用兩個破折號,並使用整個單詞而不是單個字母。

讓我們看個其他的例子。早前我們看到過的ls命令,通常使用兩個標誌呼叫:

  • l標誌,也就是long。它將目錄內容列印成一個帶有後設資料的詳細列表。
  • a標誌,也就是all。它將包含隱藏檔案和目錄。

這很大程度上改變了輸出格式:

ls-la.png

這裡有很多煩人的資料,包括令人琢磨不透的許可權字元。但是一些後設資料,比如顯示檔案最後一次更新日期,可是很有用的。

手冊

為了瞭解更多有關命令的內容,你可以使用man命令(manual的縮寫)調取它的內建文件。

man-ls.png

我要告訴你的是,man文件密密麻麻,而且經常難以解析。但它對於瞭解某些命令有哪些標誌還是很有用的。

在某些情況下,檔案會在你的預設文字編輯器中開啟,但通常會在終端中開啟,如圖所示。這裡使用了一個被稱為less的程式。

要在less中滾動檔案,請使用上/下方向鍵。在現代版本的MacOS上,你也可以使用滑鼠滾輪來滾動,儘管這在其他平臺上可能會導致錯誤的行為。

當你完成手冊檢視後,按q退出。它應該會恢復到典型的終端檢視中。

中斷命令

有些程式是長時間不間斷執行,如果要停止執行,就需要進行中斷。

舉例來說,開啟終端並嘗試執行接下來的命令:ping 8.8.8.8

ping命令將檢查給定IP地址的延遲情況。它對於檢查一個給定的伺服器是否線上很有用。8.8.8.8是谷歌DNS伺服器的IP地址。

image.png

與我們到目前為止看到過的命令不同,ping是一個長期執行的程式,它永不停歇。預設情況下,它將一直ping Google的DNS伺服器,直到時間結束。

當我們對結果感到滿意時,我們可以通過按下ctrlc來中斷該命令。即使在MacOS上,大多數的快捷鍵都使用的⌘修飾符,這裡我們也使用ctrl

另一個很有用的命令是ctrl + d。這會終止當前的會話。如果ctrl + c在某些情況下不起作用,ctrl + d可能會起作用。

最後,如果上面的方法都失敗了,可以直接關閉當前的tab頁或者視窗。該方式的快捷鍵取決於你使用的作業系統以及終端程式。如果是在MacOS上使用的Hyper,關閉當前視窗的快捷鍵組合是  + w

退出Vi / Vim

有的時候,會使用Vi或者Vim來編輯檔案。這些編輯器是出了名的難以退出;ctrl + c在這裡可幫不了你。

要在不儲存的情況下退出,請遵循以下步驟:

  • 按下Escape
  • 按下: ,這應該會在終端的底部新增一個提示。
  • 輸入q! ,並按下回車。

通用開發任務

到目前為止,我們已經看到了很多關於如何使用終端做事情的例子。接下來讓我們來看看,如何通過終端完成一些典型的開發任務。

下面的示例假設你已經在本地安裝了Node.js。如果你還沒有安裝,你可以從Node主頁下載安裝包進行安裝。

管理依賴

假設今天是你上班的第一天。你的團隊已經允許你訪問專案的原始碼,你已經把原始碼下載到了你的電腦上。然後呢?

第一步就是下載專案的第三方依賴。

以下是需要遵循的步驟:

cd path/to/project
npm install

npm代表著Node Package Manager。當你安裝Node.js時,npm會自動被安裝。

執行該命令會從NPM倉庫下載專案所依賴的所有第三方程式碼。這些程式碼將存在於本地的node_modules目錄中。

執行NPM指令碼

此時,你已經下載好了第三方的程式碼,然後呢?

如果你檢視專案的package.json ,你可能會看到這樣的一部分配置:

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

這些scripts是可以用NPM工具執行的任務。它們可以通過執行npm run [name]來執行。舉個例子,為了啟動一個本地開發伺服器,我們會執行:

cd path/to/project
npm run start

執行該命令會啟動一個長期執行的程式。它啟動了一個Node伺服器,允許我們在應用程式上進行開發,監聽檔案的變動,當我們編輯檔案時,重新進行打包。

當我們結束開發時,我們可以使用ctrl + c來關閉該服務。

NPM指令碼的美妙之處在於它們將事情標準化。startbuild,和 test 是這些標準任務的常見名稱。因此,我們不必記住每個專案定製的命令,即使這些專案使用完全不同的工具。

我們也可以建立屬於自己的NPM指令碼。關於此,我會在後面的文章進行詳細說明。

在IDE中開啟專案

當我想在一個專案上開始工作時,首先我會在終端導航到專案的根目錄。然後執行以下命令:

cd path/to/project
code .

我們在前面提到過,.指的是當前工作目錄。code是我的程式碼編輯器VS Code新增的一個命令。執行這個命令可以在我的程式碼編輯器中開啟整個專案,讓我可以隨心所欲地在不同的檔案之間輕鬆跳轉。

需要注意的是,該命令的執行取決於你的編輯器。而且,對於在MacOS上使用VS Code的人,你需要做一些工作來啟用code命令。

重新安裝依賴

你知道對任何電腦問題的標準建議是重啟嗎?

該問題的JavaScript版本是重新安裝NPM依賴。有時候,只需要徹底刪除並重新安裝就可以解決問題。尤其是你會編輯node_modules檔案並進行除錯時。

我們可以這麼做:

cd path/to/project
rm -rf node_modules
npm install

我們進入到正確的目錄後,使用rm命令刪除所有的第三方程式碼,然後使用npm install重新安裝依賴。

使用Git

雖然有GUI應用程式可以使用Git,但許多開發者更願意使用命令列來完成與Git相關的任務。

完整的 Git 命令列教程遠遠超出了本文的範圍,但這裡有一份我常用的命令的快速小抄:

// 下載Git倉庫到本地
git clone [URL]
// 檢查哪些檔案被修改
git status -s
// 檢視更改
git diff
// 新增所有檔案到暫存區
git add .
// 提交暫存的檔案
git commit -m "Short descriptive message"
// 建立新的本地分支
git switch -c [new branch name]
// 切換分支
git switch [branch name]
// 推送程式碼
git push origin [branch name]
// 開啟可互動的變基
git rebase -i [branch name or commit hash]

小技巧

多年來,我掌握了一些終端小技巧。它們並不重要,但它們有助於改善開發者使用終端的體驗。

迴圈和切換命令

許多終端程式會記錄下你在一個特定會話中所執行的每一條命令。你可以使用上鍵迴圈檢視先前的命令。

如果我明確知道最近執行過某條命令,通常按幾次上鍵會比從頭開始輸入更快。

這裡還有一個不久前學到的神奇小技巧: - 字元。

假設我們想用cd在兩個目錄之間來回跳動。我們可以通過輸入整個路徑來做到這一點。亦或者使用cd - 來快速切換到上一個cd的目錄下。

清除終端

就像清空桌面那樣,清空終端可以讓人頭腦清晰。

有好幾種辦法可以做到這一點。先來看看clear命令,它可以清除所有先前輸入的命令,並使它看起來像你剛剛開啟一個新的終端會話。

還有一個通用的快捷鍵,ctrl + L。它與clear命令的效果相同。它應該能在MacOS、Windows和Linux中工作。

這個命令/快捷鍵是在Bash/Zsh中實現的。它是shell環境的一部分。這意味著它只在shell空閒時起作用。

某些終端程式也實現了它們自己的快捷鍵,這些快捷鍵甚至可以在shell繁忙時工作。下面是我所知道的快捷鍵的清單:

  • 在MacOS中,幾乎所有的shell(Terminal.app、iTerm2、Hyper),快捷鍵是⌘ + k。
  • 如果在非MacOS平臺使用Hyper,那麼快捷鍵是ctrl + shift + k

這些應用程式級的快捷鍵要好用得多。即使在shell繁忙的時候也可以使用它們。

比如說,假設你正在執行一個開發伺服器,這是一個長期執行的程式,所以ctrl + L的快捷鍵是不起作用的。當你開發專案時,大量的資訊會被記錄在終端視窗中。應用程式的快捷鍵允許你清除舊的日誌,就像歸檔舊的電子郵件一樣。這真的非常有用,也是現代終端程式如何使我們更加輕鬆的絕佳示例。

別名

每隔一段時間,我就會發現自己會重複敲一些命令。如果這個命令又長又複雜,每次都要完整的敲出來,而且要逐字逐句地記住,這就非常煩人。

Bash和Zsh都支援別名,這是一種建立自定義快捷鍵的方法。比如說,我可以把它設定成每當我輸入hi時,它就自動執行echo "Hello World!"

alias.png

設定別名有點超出了本教程的範圍,而且根據你的shell語言,說明也有點不同。這裡有一些更深入的有用教程:

切換到GUI檔案資源管理器

除非你已經達到了使用終端的黑帶段位,否則有時你會想在GUI檔案資源管理器中開啟工作目錄。

在MacOS中,open .命令可以做到這一點。

open命令一般用於開啟一個檔案,就像在GUI檔案資源管理器中雙擊一個檔案開啟它一樣。

然而,當我們試圖開啟一個目錄時,它會選擇彈出一個新的Finder視窗,同時顯示該目錄的內容。

由於點字元(.)代表的是當前目錄,所以開啟.允許我們從終端切換到Finder,以繼續我們在終端之外的工作。

在Windows上,你可以使用explorer .來達到同樣的目的。

在Linux上,只要Linux發行版實現了FreeDesktop標準,xdg-open就可以用來開啟檔案,或當前目錄。

鏈式命令

每當我從Github上克隆一個新專案時,我一般要做兩件事:

  • npm install ,來拉取第三方依賴。
  • npm run start ,來啟動本地開發伺服器。

npm install命令通常需要花費幾分鐘時間。我沒有足夠的注意力坐在那裡盯著依賴是否下載完成,所以我經常會用Twitter來分散自己的注意力。接下來我知道的是,20分鐘過去了,我完全忘記了我要啟動一個開發伺服器。

我們可以使用鏈式命令來解決該問題。以下是它的工作原理:

chain.png

&&操作符允許我們將多個命令連結在一起。第一條命令將被執行,即npm install。當它完成的同時,第二個命令將自動執行。

這是一個特別巧妙的技巧,因為npm run start通常會開啟一個瀏覽器視窗,吸引我的注意力,讓我知道一切都準備好了。相比之下,npm install是靜默完成的。

一旦我掌握了鏈式命令的竅門,我就開始到處使用它。我經常會把一堆Git命令排列在一起:

git add . && git commit -m "Stuff" && git push origin main

總結

我們在這篇文章中涵蓋了很多內容。希望你不會感覺到太大的壓力。

終端有一個很好的名聲,對初學者來說是令人生畏和棘手的。如果你對它感到費勁,那也是完全正常的。

希望這篇文章至少能縮小你需要學習的範圍。可以使用終端做很多事情,但我們可以專注某一部分功能。

如果你覺得這篇文章對你有所幫助,歡迎收藏關注轉發~

原文連結:https://www.joshwcomeau.com/javascript/terminal-for-js-devs/#cycling-and-toggling-commands

作者:Joshua Comeau

相關文章