1. 程式人生 > >Linux下和編譯器、程式的執行、環境變數等相關的常見問題

Linux下和編譯器、程式的執行、環境變數等相關的常見問題

(不斷更新)

索引:

(1) Linux下環境變數相關的問題

(2) Linux下GNU工具鏈相關的問題(GNU Toolchain)(gcc/g++/ld/make等等工具)

(3) Linux下可執行檔案的格式(主要是ELF格式,還有a.out/coff等)和可執行檔案的載入

(4) 可執行程式執行載入動態庫的搜尋路徑問題

Linux編譯環境變數(LD_LIBRARY_PATH。。。)

(1) Linux下環境變數相關的問題

1. Linux下如何設定環境變數

A. 在終端輸入export設定環境變數
export var=value

export var=“value”
特點:臨時的,只對當前shell有效

(即當前的命令列,如果在命令列中執行其它的shell指令碼,指令碼檔案中定義的export環境變數在指令碼執行完後對“當前"shell無效,因為執行指令碼會開一個新的shell程序,當然,這裡只是簡單提示一下這一點)。

說明:
1. var和=之間不能有空格。測試如下:

$export xx =
bash: export: `=': 不是有效的識別符號
$
2. value是可選的,如果沒有value,那麼var的值就是空的。(當然,一般不會這麼用)
export var=value中,value的寫法一般有兩種,用引號和不使用引號。如果value的值不包含空格,那麼value可以直接寫,否則,var的值遇到空格就停止了,後面的會被忽略;如果value的值包含空格,那麼可以對value使用引號,如果使用了多對引號,那麼就是對字串連結了,引號都不包括在value中。測試如下:
$export var=abc
$echo $var
abc
$export var= abc
$echo $var


$export var=abc def
$echo $var
abc
$export var="abc"
$echo $var
abc
$export var= "abc"
$echo $var


$export var="abc" def
$echo $var
abc
$export var="abc" "def"
$echo $var
abc
$export var="abc def"
$echo $var
abc def
$export var=" abc def g"
$echo $var
abc def g
$export var="abc"def"g"h
$echo $var
abcdefgh
$export var="abc"def"g"h"
> xx"
$echo $var
abcdefgh xx
$
這裡只是一些測試,其實這些應該是shell對字串的一些要求了,比如"abc"def"gh"得到的是abcdefgh這樣的字串。如果引號不配對,就會認為沒有輸入完成,會讓繼續輸入的。那麼,如果value中必須要包含引號呢?那就是反義字元了。如下:
$export var=abc\"def
$echo $var
abc"def
$export var=abc\"def\"
$echo $var
abc"def"
$export var="abc\"def\"""gh"
$echo $var
abc"def"gh
$
總之,看看這些測試的就很容易理解了,一般也不會用到這些。主要知道引號的作用就可以了,它是不會被包含在var的值中的

B、在/etc/profile裡新增環境變數
就是開啟檔案,在其中新增export的內容,export的使用和上面的一樣。
特點:永久的,且對所有使用者有效
說明:如果在命令列下修改檔案,退出編輯後,設定不會馬上生效,需要執行source /etc/profile,如果不執行source,那麼下次啟動登入此使用者的時候會生效。參考Linux的source命令的用法。

C、在使用者目錄下的.bash_profile(~/.bash_profile)裡新增環境變數

和/etc/profile裡新增的方法一樣,

特點:永久的,但是隻對當前使用者有效

說明:和/etc/profile是對應的,所以同樣,設定後使用source才會馬上生效,否則,需要重新登入此使用者。

D、其它方法

上面三種是常見的設定環境變數的方法,對於BC兩種方法,如果不使用source命令則需要重新登入使用者才能生效,對應的其實還有一些其他的bash配置檔案也可以設定,這裡主要說的是使用者目錄下的.bashrc檔案(~/.bashrc),其對應於.bash_profile的設定,區別在於,.bashrc在每次重啟shell(命令列)就會生效,不需要重新登入使用者。當然,對應的還有其它一下檔案可能也可以設定環境變數,但是原理方法是一樣的,參考相關內容比較這些配置檔案的區別和理解其原理。

說明:個人習慣使用的方式是export和~/.bashrc的方法,這也應該是比較常見的使用方式。

2. 如何引用(表示)另一個環境變數

定義了一個環境變數後,用$var就表示引用這個環境變量了。

2. Linux下如何顯示環境變數(的值)

A、使用echo顯示單個環境變數

上面已經涉及到了,直接echo就可以輸出單個環境變數的值,其實,這只是引用環境變數的一個例子而已了,環境變數用$var引用就可以了,shell會將其“翻譯"為其vaue,所以,自然,下面也是可以的:

$export var=test
$echo $var"add something"
testadd something
$echo $var add something
test add something
$

B、使用env顯示所有環境變數和其值

相當於對所有環境變數使用echo $var,直接命令列輸入env命令即可。

C、使用set顯示所有的使用者變數

set命令可以顯示的是使用者變數,關於環境變數和使用者變數,參考相關內容。(提示:使用者變數直接定義即可,比如var=value,對使用者變數的引用也是$var,更多內容參考shell程式設計相關知識)(使用者的環境變數也是使用者變數的一部分)。

說明:unset可以刪除使用者變數,如unset var。注意:不是unset $var!unset可以刪除使用者變數和函式等,環境變數只是其中的一小部分。當然,所謂的”刪除“變數,其實,將其設定為空,效果也是一樣的了(如何設定?直接賦值!如$var=newvalue,同樣也是適用於環境變數和普通的使用者變數。

(2) Linux下GNU工具鏈相關的問題

1. GNU工具鏈介紹(包含的內容)

GNU工具鏈(GNU toolchain)是一個包含了由GNU專案所產生的各種程式設計工具的集合。這些工具形成了一條工具鏈(序列使用的一組工具),用於開發應用程式和作業系統。 GNU工具鏈中包含的專案有:
GNU make:用於編譯和構建的自動工具;
GNU編譯器集合(GCC):一組多種程式語言的編譯器;
GNU Binutils:包含連結器、彙編器和其它工具的工具集;
GNU Debugger(GDB):程式碼除錯工具;
GNU構建系統(autotools):
Autoconf
Autoheader
Automake
Libtool

由於工具很多,所以不一一說明。注意:GNU toolchain並不只是指gcc、g++、ld這些。

2.  Linux下程式的編譯的過程(windows類似)

3. Linux下可執行檔案的格式(主要是ELF格式,還有a.out/coff等)和可執行檔案的載入

Linux下的可執行檔案的格式,目前的Linux上的可執行程式基本其實都是ELF了,包括.so共享動態連結庫其實也是ELF格式的。

利用file命令可以檢視Linux上檔案的格式,下面是對兩個測試檔案使用file的結果:

a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped
這是一個hello,world編譯後得到的a.out使用file a.out的結果,下面是對一個動態連結庫使用file得到的結果:
libBox2D.so.2.1.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
關於可執行檔案的格式的相關內容比較複雜,可以參考下面的內容深入學習:

等。

##/lib/ld-linux.so.2 
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
You have invoked `ld.so', the helper program for shared library executables.
This program usually lives in the file `/lib/ld.so', and special directives
in executable files using ELF shared libraries tell the system's program
loader to load the helper program from this file.  This helper program loads
the shared libraries needed by the program executable, prepares the program
to run, and runs it.  You may invoke this helper program directly from the
command line to load and run an ELF executable file; this is like executing
that file itself, but always uses this helper program from the file you
specified, instead of the helper program file specified in the executable
file you run.  This is mostly of use for maintainers to test new versions
of this helper program; chances are you did not intend to run this program.

  --list                list all dependencies and how they are resolved
  --verify              verify that given object really is a dynamically linked
			object we can handle
  --library-path PATH   use given PATH instead of content of the environment
			variable LD_LIBRARY_PATH
  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names
			in LIST
  --audit LIST          use objects named in LIST as auditors
##

相關的命令:

file xxx:檢視檔案xxx的檔案型別

ldd xxx:檢視可執行檔案xxx依賴的動態連結庫。

nm:列舉檔案中的符號(symbols)。


4. 可執行程式執行載入動態庫的搜尋路徑問題

需要注意的是:LD_LIBRARY_PATH,這個環境變數是被ld.so使用的,所以和編譯器的連結階段並沒有關係。