談 Linux GNU 實用工具兼容性

王 麗娜 ([email protected]), 軟件工程師, IBM 中國軟件開發中心

2007 年 11 月 29 日


GNU utility 的默認行爲和 POSIX 標準有不兼容的地方。Linux 系統的不同版本採用了不同版本的 POSIX 標準,而 POSIX 不同版本標準之間有不兼容的地方。這兩個不兼容問題對於產品在 Linux 各個平臺之間的可移植性影響很大。

Linux 系統的兼容性問題

POSIX 定義:

POSIX 表示可移植操作系統接口:Portable Operating System Interface,電氣和電子工程師協會(Institute of Electrical and Electronics Engineers,IEEE)最初開發 POSIX 標準,是爲了提高 UNIX 環境下應用程序的可移植性。

GNU utility 定義:

GNU 是 GNU Is Not UNIX 的遞歸縮寫。Linux 的開發使用了許多 GNU 工具。Linux 系統上用於實現 POSIX 標準的工具幾乎都是 GNU 項目開發的,如 emacs 編輯器、著名的 GNU C 和 C++ 編譯器。

兼容性問題 1:

GNU/Linux 與 POSIX 標準基本是兼容的,但是在一些情況下,GNU utility 的默認行爲和 POSIX 標準有不兼容的地方。

兼容性問題 2:

Linux 系統的不同版本採用了不同版本的 POSIX 標準,而 POSIX 不同版本標準之間有不兼容的地方。

這兩個不兼容問題對於產品在 Linux 各個平臺之間的可移植性影響很大,因此,掌握如何解決這兩個兼容性問題非常重要。



GNU utility

在一些情況下,GNU utility 的默認行爲和 POSIX 標準不兼容。爲了解決這種不兼容情況,Linux 系統引入了環境變量’POSIXLY_CORRECT’。

設置方法:

export POSIXLY_CORRECT=TRUE
取消設置:

unset POSIXLY_CORRECT
例如:df命令(報告文件系統的磁盤使用情況)輸出在 POSIX 標準下和 GNU 下是不同的。要使系統 GNU utilities 完全遵從 POSIX 標準,可以設置環境變量’POSIXLY_CORRECT’。

POSIX 細節:

輸出結果在缺省時以 512 字節爲計數單位,若給以 -k 選項,則以 1024 字節爲計數單位。

GNU 細節:

(在沒有用選項指定計數單位的情況下)輸出結果以 1024 字節爲計數單位,但不包括由於設置了環境變量’POSIXLY_CORRECT’而跟從 POSIX 標準的情況。

清單 1. df 命令輸出

# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 70675484 9834248 57251112 15% /
# export POSIXLY_CORRECT=True
# df
Filesystem 512B-blocks Used Available Use% Mounted on
/dev/sda1 141350968 19668496 114502224 15% /
# df –k
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 70675484 9834248 57251112 15% /
# unset POSIXLY_CORRECT

# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 70675484 9834248 57251112 15% /
Linux系統的不同版本採用了不同版本的POSIX標準,如 RedHat3,4系統採用的是舊版本 POSIX 標準 1003.2-1992,RedHat5 採用的是新版本 POSIX 標準 1003.1-2001,新舊版本的 POSIX 標準在一些地方有不兼容情況存在。

GNU utilities 通常遵從的 POSIX 版本就是系統所在的 POSIX 版本。RedHat5 GNU utilities 採用的是新的 POSIX 版本,RedHat3,4 採用的是舊的 POSIX 版本,由於 POSIX 新舊版本之間有不兼容存在,導致一些在 RedHat3,4 上運行良好的應用程序和腳本直接移植到 RedHat5 上不能正常運行行。

比如,’tail +2 <filename>’這個命令在舊版本 POSIX 上的意思是得到文件從第二行到末尾的內容,但是從新的 POSIX 版本 1003.1-2001 開始,這個命令的意思變成了得到文件’+2’的內容,如果你想得到真正文件的內容,就得改用命令’tail –n +2 <filename>’。

清單 2. 文件 wln.txt 內容

# more wln.txt
It is sunny today,
you are an industrious boy,
give the room a good sweep
這是用於下面tail命令示例的文件。

清單 3. 在舊版本POSIX上運行

# tail +2 wln.txt
you are an industrious boy,
give the room a good sweep.
舊版本POSIX用’tail +2’可以正確顯示文件前兩行內容。

清單 4. 在新版本POSIX上運行

# tail +2 wln.txt
tail: cannot open `+2` for reading: No such file or directory
==> wln.txt <==
It is sunny today,
you are an industrious boy,
give the room a good sweep.
# tail –n +2 wln.txt
you are an industrious boy,
give the room a good sweep.
新版本POSIX用’tail +2’命令不能正確顯示文件前兩行內容,必須用’tail –n +2’命令才行。

爲了解決不同版本的 POSIX 標準的兼容性問題,使得 GNU utilities 能和不同版本的 POSIX 標準工作,Linux 系統引入了環境變量’_POSIX2_VERSION’,這個變量的格式是 YYYYMM,表示 POSIX 標準採用的年代和月份。

當前’_POSIX2_VERSION’有兩個值:

‘199209’ 代表 POSIX 1003.2-1992

‘200112’ 代表 POSIX 1003.1-2001

設置用法:

export _POSIX2_VERSION=199209
取消設置:

unset _POSIX2_VERSION
如果你有舊版本的應用程序和腳本想移植到採用新版本 POSIX 標準的系統上運行,比如’tail +10’,’sort +1’等,你就能通過設置環境變量’_POSIX2_VERSION=199209’來解決兼容性。

清單 5. 使用’_POSIX2_VERSION’環境變量

# tail +2 wln.txt
tail: cannot open `+2` for reading: No such file or directory
==> wln.txt <==
It is sunny today,
you are an industrious boy,
give the room a good sweep.
# export _POSIX2_VERSION=199209
# tail +2 wln.txt
you are an industrious boy,
give the room a good sweep.
引入’_POSIX2_VERSION’變量後,’tail +2’能夠正確顯示文件前兩行了。




總結

本文講述了Linux系統下的兩個環境變量解決兼容性問題的方法。Linux是個開源的系統,通過這兩個環境變量的使用,提高了應用程序在不同Linux版本之間的移植性。






參考資料



關於作者


王麗娜,中國軟件開發中心 Tivoli 部門軟件工程師,負責 IBM 產品TMF(Tivoli Management Framework)的維護和客戶支持工作,熱愛 Linux。



發佈了10 篇原創文章 · 獲贊 12 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章