跟濤哥一起學嵌入式第12集:關於 apt-get 軟件安裝那些事兒

對於很多linux/ubuntu新手來說,要想在Ubuntu系統上熟練地安裝、升級、卸載軟件,確實是挺考驗人的一件事,會遇到各種各樣的問題,有時候會把人搞得很不耐煩,打擊人的學習積極性。Ubuntu一般使用apt-get命令 (ubuntu16.04版本以後也可以使用apt) 來安裝、升級、卸載軟件。比如我們想安裝一個軟件,常用下面的命令進行安裝:

    $  apt-get install xxx
    $  apt-get update
    $  apt-get upgrade

順利安裝還好,但有時候還是會遇到各種各樣的問題,雖說有時候能通過互聯網解決掉,但是對於 apt-get 如何安裝的卻不是很清楚,比如什麼是軟件源,就沒有啥概念。本文目的就是跟大家一起了解下Ubuntu環境下 apt-get 的軟件安裝基本原理。


想要了解apt-get的工作原理,首先我們要明白軟件的安裝是怎麼回事。我們知道一個程序的運行,一般是要先加載(load)到內存(RAM)中,因爲RAM存儲器支持隨機讀寫,因此CPU可以一條一條地去取指令、翻譯指令、運行指令。但是RAM有一個缺點,就是斷電後數據會消失,無法保存。因此,我們需要將程序文件保存到一個非易失性存儲器上,比如硬盤、NAND Flash上,斷電後數據也可以保存。把程序保存到磁盤上的過程其實就是軟件的安裝過程,早期的單片機裸機環境,程序一般都是使用專門的工具直接燒寫到Flash上的,後來有了OS和文件系統,我們可以很方便的通過鼠標,直接將程序文件安裝到某個文件目錄下面,程序在運行時,系統就可以直接到這個目錄下面找到對應的二進制文件,加載到內存,然後就可以直接運行了。


無論是Windows還是Linux,基本流程都是如此:告訴系統你的程序二進制文件存放到哪裏了,然後程序在運行時,系統就會到這個指定的路徑下面去找你要運行的二進制程序文件,加載到內存,然後運行。在Windows下面,你安裝好軟件後,在桌面上會有一個快捷方式,其實就是指向你安裝路徑的軟鏈接。在Linux環境下面,我們要運行的程序一般是放在默認的路徑下面的,如:/bin、/sbin、/usr/bin、/usr/sbin等。比如你在shell下面運行:$ ls

命令時,系統就會到這些默認的路徑下面去尋找ls文件,在/bin/ls下面找到後,就會加載到內存,然後 ls 程序就可以運行了。

我們寫一個簡單的helloworld程序,編譯爲a.out,我們可以直接運行它:

    $ ./a.out

爲什麼不能直接運行$ a.out呢,因爲我們的a.out沒有安裝到默認路徑,因此運行時,你要指定路徑信息,否則系統就找不到。你把a.out放到默認的/usr/bin下面,然後就可以直接通過$ a.out文件名去執行程序了。當然,你可以可以把自己編譯的a.out二進制文件放在自定義的某個目錄下面,然後以環境變量的形式告訴系統這個安裝路徑,當系統在那些默認路徑下面找不到時,會到這個安裝路徑下查找。


我們在Linux環境下安裝軟件時,最簡單的方法是從網上下載這個二進制程序文件,放到Linux系統中的默認路徑下面就可以了。但是有些程序是採用動態鏈接編譯的,運行時需要依賴一些動態共享庫,因此需要打包一起安裝。我們下載的軟件一般很少是一個單純的二進制文件,而是壓縮包的形式,在這個壓縮包裏有:二進制程序文件、動態鏈接庫、軟件文檔說明、安裝信息、甚至有一些自動安裝的腳本等。在 Debian 和 Ubuntu 環境下,這個壓縮包格式爲deb格式,我們安裝軟件時,先從網上下載對應的deb包,然後可以使用dpkg工具去解析這個包、安裝這個包。

$ dpkg -i xxx.deb   安裝xxx.deb軟件包
$ dkpg -R /home/xxx   安裝xxx目錄下的多個deb包
$ dkpg -r xxx   卸載xxx軟件包

當然你也可以將自己的二進制程序製作成一個deb安裝包,放到網上,供其他人下載安裝:

$ apt install checkinstall dh-make
$ ./configure --prefix=/home/tools //配置編譯信息
$ make  //編譯你的程序
$ checkinstall  //製作deb包
$ dkp -i xxx.deb //安裝deb包

因爲每個人都可以編譯、製作deb包、並隨意發佈到網上,這就很容易造成混亂,魚龍混雜、質量得不到保證,甚至有些包還有可能是一個病毒軟件。因此Ubuntu系統採用一個軟件倉庫來管理這些deb軟件包,把這些包放到一個官方的網站服務器上,類似於蘋果系統的APP store,用戶使用apt命令安裝軟件時,只能到這個服務器上下載軟件。考慮到全球各個地方的網絡環境差異,往往會在全球各地同時配置幾個鏡像服務器,這樣全球各地的Ubuntu用戶都可以根據網絡狀況到最合適的服務器上去下載和安裝deb軟件包了。這些服務器我們也稱爲軟件源 (repository) 或者簡稱爲“源”。

這些服務器的網絡地址保存在/etc/apt/source.list文件中。文件內容如下所示:

deb http://us.archive.ubuntu.com/ubuntu/ xenial universe

當我們使用apt install安裝軟件時,apt工具就會根據這個source.list文件中的網絡地址,選擇最合適的服務器去下載軟件包。

一般Ubuntu默認的軟件源是Ubuntu官方網站,打開上面的網址,你會發現上面存有很多軟件包的信息。

小Q截圖-20181126133506.png

對於國內用戶來說,訪問國外的網站速度可能會慢很多、甚至無法訪問。國內高校和互聯網公司其實也有很多服務器提供下載,大家百度搜索一下:阿里雲軟件源、中科大軟件源,一般都會搜索到很多服務器地址,可以選擇其中幾個,添加到/etc/apt/source.list文件中,以後使用apt-get安裝軟件時,就可以直接從國內的服務器上直接下載deb包了,速度會快很多。

修改好/etc/apt/source.list文件後,你還需要使用$ apt-get update命令更新一下。這個命令的作用訪問 /etc/apt/source.list 文件中的每一個服務器,讀取可以支持下載安裝的軟件列表,並保存到本地電腦中(/var/lib/apt/lists)。這個列表就像飯店裏的菜單一樣,要按照菜單去點菜,直接使用apt install xxx 就可以直接安裝軟件了。如果你要安裝的軟件如果不在軟件列表中,很可能就安裝失敗。

軟件列表的另一個作用是可以幫助你軟件更新,因爲服務器上的軟件版本也會不斷更新,你本地已經安裝的軟件如果跟軟件列表中的軟件版本不一致,它可能就會提示你軟件需要更新,就像我們PC中的軟件管家一樣,它會提示你,你的電腦中有多少個軟件可以更新。

小Q截圖-20181126135019.png

當然,你也可以使用apt list命令去查看具體需要更新的軟件包:

小Q截圖-20181126135137.png

接下來,如果你想更新這些已經安裝的軟件,就可以通過$ apt-get upgrade命令來完成。這個命令會將本地已經安裝的軟件與剛剛使用update命令下載到本地的軟件列表進行對比,如果發現版本不一致,就會重新安裝最新的版本。如果你的系統需要更新的軟件包太多,這個可能需要一定的時間,耐心等待就可以了,升級成功後,一般會有提示信息,你升級了多少個軟件包...


使用apt安裝軟件的另一個好處是可以自動處理依賴關係。比如你想安裝一個B,需要依賴A,那麼你安裝B的同時,B所依賴的A軟件包也會自動安裝上了。在/var/lib/dpkg/available文件中,有詳細的軟件包信息,包括軟件版本、軟件依賴的包等。包括在視頻教程《使用QEMU搭建嵌入式U-boot+Linux+NFS開發環境》中,很多學員反饋說,爲什麼我的環境跟視頻中的不一樣?這是因爲每個Ubuntu版本不同、安裝的軟件不同,安裝的庫、頭文件也不一樣,大家在編譯的時候如果遇到一些無法識別的命令、缺少一些頭文件,直接安裝對應的工具和庫就可以了,隨着你的Ubuntu系統安裝的一些依賴庫、工具越來越多,以後再編譯其它軟件時,一般都可以順利編譯了,因爲很多依賴的庫文件、頭文件、工具、命令等都安裝得差不多了。


對於一個新手。在使用apt-get安裝軟件時,經常遇到的問題很多,比如權限不夠,使用sudo、或切換到root安裝可以解決這個問題。無法獲取軟件包,網絡訪問不了,可以在/etc/apt/source.list文件中添加國內的一些鏡像服務器地址(軟件源)。還有一個經常遇到的問題是:

E: 無法獲得鎖 /var/cache/apt/archives/lock

直接刪除這個文件就可以了,對應的還有 /var/lib/dpkg/lock文件,順便也刪除掉,一般就可以解決問題。在安裝的過程中,如果遇到其它問題,建議先到百度裏搜一搜,你遇到的問題、踩到的坑,前面可能已經有無數人遇到過了,看看它們是怎麼解決的,一般都可以解決問題。


最後,當你安裝的軟件在服務器中確實沒有時,這就需要你手動下載源碼、編譯安裝了,一般在Linux系統中,可以直接下載GNU工程開源代碼,然後直接通過三步走,就可以直接編譯和安裝了:

$ ./configure$ make$ make install

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章