初學機器學習的你,是否掌握了這樣的Linux技巧?

機器之心發表於2017-11-21

Linux 因為其穩定性獲得了不少開發者的青睞,同時也成為大多數伺服器的作業系統,對於機器學習開發來說,使用 Mac/Linux 系統幾乎是必須的。然而因為上手難度較大,很多人對其望而卻步。本文將介紹一些 Linux 常用指令以幫助你快速上手。

隨著軟體系統的不斷髮展,今天,不同的作業系統對應著不同的適用人群:Windows 面向辦公室和商用,Mac 面向創意人群,而 Linux 面向軟體開發者。對於作業系統提供商而言,這種市場分割大幅度簡化了產品技術需求、使用者體驗和產品方向上的投入。然而,這也加劇了相容性問題,讓不同業務進入了狹窄、互不相容的領域:商務人士無法對創意提供洞察力,而開發者也無法深入商務決策中去。

在現實中,知識和技能是流動的,跨越多個學科和領域。與其說「你只能擅長一件事」的理念是邁向精通的路線圖,還不如說一種過早最佳化的方法。一旦從社會中取樣大量的任務,你就只能知道你擅長什麼,也許你還發現自己擅長它們中的很多。

對於現代的業務分析師,彌補業務與軟體之間的鴻溝尤其重要。業務分析必須是「雙重平臺」,能夠利用僅在 Linux(或 OS X)上可用的命令列工具,但是仍然受益於 Windows 的 Microsoft Office。可以理解的是,Linux 會使具有商學學位的人感到恐懼。幸運的是,正如大多數事情一樣,你只需 20% 的任務即可完成 80% 的工作。下面是我的 20%。

業務分析是基於資料的,而機器學習正是強大的資料分析工具。我們利用機器學習模型分析資料最好的環境卻恰恰是 Linux 系統,這不僅是因為它支援廣泛的 Python 機器學習庫,同時在於環境配置與管理的簡單明瞭。因此,本文將為機器學習讀者梳理 Linux 系統的基本特性與命令。

為什麼機器學習分析師需要了解 Linux


由於其開源的底層,Linux 從不斷從數以萬計的開發者貢獻中受益。他們構建的程式和工具不僅使其工作更簡單,也簡化了跟隨他們的程式設計人員的工作。結果,開源開發帶來了一種網路效應:在平臺上構建工具的開發者越多,能夠利用這些工具立刻編寫其程式的其他開發者就越多。

結果就是 Linux 中編寫的 Linux 程式和實用工具(統稱為軟體)的擴充套件套件——其中很多從未用於 Windows。一個示例是被稱作 git 的流行的版本控制系統(VCS)。開發者本可以編寫這一在 Windows 工作的軟體,但是卻沒有。他們讓其在 Linux 命令列上工作,因為生態系統已經提供全部所需的工具。

具體來說,Windows 上的開發有兩個主要問題:

1. 基本任務,比如檔案解析、工作排程和文字搜尋比執行命令列工具更為重要。

2. 程式語言(比如 Python、C++)及其相關程式碼庫會引發錯誤,因為它們期望特定的 Linux 引數或檔案系統定位。

這意味著若想在 Windows 上進行開發,我們需要花費更多的時間來重寫 Linux 中已有的基本工具,並排除作業系統相容性錯誤。這並不令人意外——Windows 生態系統當初並沒有考慮軟體開發設計的需求。

藉助這個 Linux 開發案例,讓我們從最基本的開始。

Linux 的基本單元:「shell」


「shell」(也被稱為終端、控制檯或命令列)是一個基於文字的使用者介面,透過它把命令傳送給機器。在 Linux 中,shell 的預設語言是 bash。與主要在 Windows 內部進行點選操作的 Windows 使用者不同,Linux 開發者堅持使用鍵盤把命令輸入到 shell。對於那些沒有程式設計背景的人來說,這種轉變一開始也許會不自然,但是在 Linux 中開發的好處很容易超過最初的學習投資。

學習幾個重要的概念


和成熟的程式語言相比,bash 只需要學習幾個主要的概念。這一步完成之後,之後 bash 的學習就只剩下記憶了。更清楚地說就是:要學好 bash,只需要記住 20—30 個命令(command)以及其中最常用的引數(argument)就可以了。

對於非開發者而言,Linux 很令人費解,因為開發者似乎能隨意且不費力地使用深奧的終端命令。其實是因為他們只記住了少量的命令—對於更復雜的問題,他們(和所有普通人一樣)也需要谷歌一下。

以下就是 bash 中的主要概念。

命令語法


bash 中的命令是區分大小寫的,且遵循 {命令}{引數} 的語法結構。

例如,在『grep-inr』中,grep 是命令(搜尋文字的一個字串),-inr 是標記(flag)或引數(隨 grep 預設執行而變化)。理解這個命令的唯一方法是使用谷歌搜尋,或輸入『man grep』命令。我推薦同時學習命令和其中最常用的引數,否則單獨學習每一個標記的作用是很費力的。

目錄相對地址


當前目錄:.

上一級目錄的上一級目錄:..

使用者的主目錄:~

檔案的系統根目錄:/

例如,為了從當前目錄換到上一級目錄,需要輸入:「cd..」。類似地,為了複製位於「/path/to/file.txt」檔案到上一級目錄中,需要輸入「cp /path/to/file.txt.」(請注意命令末尾的點)。這些例子中使用的都是相對路徑,可以使用絕對路徑替換。

標準輸入(STDIN)/標準輸出(STDOUT)


任何輸入和提交(透過鍵入 ENTER)到視窗的命令都被稱為標準輸入(standard input,STDIN)。

任何程式列印(print)到終端的東西(例如,一份檔案中的文字)都被稱為標準輸出(standard output,STDOUT)。

管道(PIPING)


1 | 

 一種管道,其左方是一個命令的 STNOUT,將作為管道右方的另一個命令的 STDIN。

 例如:echo 『test text』 | wc -l

2 >

 大於號,作用是取一個命令 STDOUT 位於左方,並將其寫入/覆寫(overwrite)入右方的一個新檔案。

 例如:ls > tmp.txt

3 >>

 兩個大於號,作用是取一個命令 STDOUT 位於左方,並將其追加到右方的一個新的或現有檔案中。

 例如:date >> tmp.txt

萬用字元(WILDCARDS)


這類似於 SQL 中的% 符號,例如,使用「WHERE first_name LIKE 『John%』」搜尋所有以 John 起始的名字。

在 bash 中,相應的命令是「John*」。如果想列出一個資料夾中所有以「.json」結尾的檔案,可以輸入:「ls *.json」。

TAB 鍵自動完成


如果我們輸入一個命令並按下 TAB 鍵,那麼 Bash 將自動完成該命令。但是,我們也應該使用一些如 zsh 或 fish 工具來自動完成,因為我們很難記住各種命令及它們的引數。更準確地說,這些工具會基於我們的命令列歷史自動完成命令語句。

退出


有時候我們會卡在一些程式中並不知道如何退出它們。這在 Linux 新手中是很常見的問題,這也會大大損害新手的積極性。一般來說,退出命令會和字母「q」有一些關係,所以記住以下的退出命令或快捷鍵就十分有用了。

  • Bash

         CTRL+c

         q

         exit

  • Python

         quit()

         CTRL+d

  • Nano: CTRL+x
  • Vim: <Esc> :q!

常用 Bash 命令


以下是在 Linux 中最常用到的指令,在使用新系統進行開發時,記住這些指令對於快速上手非常重要。

  • cd {directory}:轉換當前目錄
  • ls -lha:列出目錄檔案(詳細資訊)
  • vim or nano:命令列編輯器
  • touch {file}:建立一個新的空檔案
  • cp -R {original_name} {new_name}:複製一個檔案或目錄(包含內部所有檔案)
  • mv {original_name} {new_name}:移動或重新命名檔案
  • rm {file}:刪除檔案
  • rm -rf {file/folder}:永久刪除檔案或資料夾(小心使用)
  • pwb:列印當前工作目錄
  • cat or less or tail or head -n10 {file}:檔案的標準輸出內容
  • mkdir {directory}:建立一個空的目錄
  • grep -inr {string}:在當前目錄或子目錄的檔案中搜尋一個字串
  • column -s, -t <delimited_file>:在 columnar 格式中展示逗號分隔檔案
  • ssh {username}@{hostname}:連線到遠端機器中
  • tree -LhaC 3:向下展示三級目錄結構(帶有檔案大小資訊和隱藏目錄資訊)
  • htop (or top):工作管理員
  • pip install --user {pip_package}:Python 安裝包管理器,安裝包到~/.local/bin 目錄下
  • pushd . ; popd ; dirs; cd -:在堆疊上 push/pop/view 一個目錄,並變回最後一個目錄
  • sed -i "s/{find}/{replace}/g" {file}:替代檔案中的一個字串
  • find . -type f -name '*.txt' -exec sed -i "s/{find}/{replace}/g" {} \;:替換當前目錄和子目錄下字尾名為.txt 檔案的一個字串
  • tmux new -s session, tmux attach -t session:建立另一個終端會話介面而不建立新的視窗 [高階命令]
  • wget {link}:下載一個網頁或網頁資源
  • curl -X POST -d "{key: value}" http://www.google.com:傳送一個 HTTP 請求到網站伺服器
  • find <directory>:遞迴地列出所有目錄和其子目錄的內容


高階&不常用的指令


保留一個有用命令列表以備不需也是非常必要的,即使這些情況不常發生(如某個程式阻塞了幾個網路埠)。以下我們將列出幾個不常用命令:

  • lsof -i :8080:列出開啟檔案的描述符(-i 是網路介面的標記)
  • netstat | head -n20:列出當前開啟的 Internet/UNIX 介面(socket)以及相關資訊
  • dstat -a:輸出當前硬碟、網路、CPU 活動等資訊
  • nslookup <IP address>:找到遠端 IP 地址的主機名
  • strace -f -e <syscall> <cmd>:跟蹤程式的系統呼叫(-e 標記用於過濾某些系統呼叫)
  • ps aux | head -n20:輸出目前活動的程式
  • file <file>:檢查檔案型別(例如可執行檔案、二進位制檔案、ASCII 文字檔案)
  • uname -a:核心資訊
  • lsb_release -a:系統資訊
  • hostname:檢視你的機器的主機名(即其他電腦可以搜尋到的名稱)
  • pstree:視覺化分支程式
  • time <cmd>:執行一個命令並報告用時
  • CTRL + z ; bg; jobs; fg:從當前 tty 中傳遞一個程式到後臺再返回前臺
  • cat file.txt | xargs -n1 | sort | uniq -c:統計檔案中的獨特字(unique words)數量
  • wc -l <file>:計算檔案的行數
  • du -ha:在磁碟上顯示目錄及其內容的大小
  • zcat <file.gz>:顯示壓縮文字檔案的內容
  • scp <user@remote_host> <local_path>:將檔案從遠端複製到本地伺服器,或反過來
  • man {command}:為一個命令顯示 manual(說明文件),但是通常這樣不如谷歌搜尋好用

相關文章