將 Perl 腳本從 Solaris 移植到 Linux
隨著可視化技術的發展,企業逐漸將物理服務器合并到虛擬環境,提高資產管理同時減少能量消耗和物理空間。有些情況下,合并活動涉及到從一個舊操作系統遷移到一個能提供便利的系統管理或其他總擁有成本優勢的系統。
如果您計劃從 Solaris 遷移到 Linux,那么幾乎您的所有定制代碼(包括 C、shell 腳本、Perl,等等)都需要一些矯正 — 一個映射屬性的 “再排列” — 因為平臺不同。此外,Perl 不同于其他語言 — 盡管程序本身可在各種平臺上移植,而且您只需要安裝一個解析程序來在目標系統上運行代碼 — 但是一些矯正類型的問題仍然可能出現。特定 Solaris 資源 — 最明顯的操作系統路徑名、系統命令和 Perl 模塊 — 通常在代碼中受到影響。因此,您應該期待采用某種代碼矯正(code remediation)來確保 Perl 腳本在遷移之后正常運行。
但是什么 Perl 語法結構,哪個操作符最值得關注呢?在本文中,我們將向您介紹最常見的可移植性陷阱,并為您呈現一個將 Perl 腳本從 Solaris 遷移到 Linux 的路線圖。您可以使用本文提供的路線圖從大多數 Unix 操作系統將 Perl 腳本遷移到 Linux;然而,所有示例、樣例代碼以及參考資料只關注 Solaris 到 Linux 的遷移。
Perl 可移植性問題
您應該檢查 Perl 腳本中引用的參考資料,來確保腳本在 Linux 系統中運行時不會出現由特定 Solaris 代碼引起的問題。例如,想想從一個僅在 Solaris 上遇到的文件中提取信息的腳本;想像使用一個在 Linux 系統中不可用的標志執行一個系統命令。多數可移植性問題根據他們訪問的或引用的系統資源可以被分成 5 類,見表 1 。
表 1. Perl 腳本中可移植性問題的分類
類別 | 可移植性問題 |
---|---|
01 | 特定平臺 Perl 模塊依賴項 |
02 | 操作系統命令和 IPC(進程間通信) |
03 | 使用的操作系統路徑名 |
04 | 存放特定平臺信息的特定變量的使用 |
05 | 不同實現或不能跨平臺實現的功能 |
5 步讓 Perl 移植變完美
讓我們來看看將 Perl 腳本從 Solaris 移植到 Linux 的路線圖,這個路線圖是根據表 1 中的可移植性問題分類構建的。線路圖包括 5 個步驟,每一個對應表中的一個類;每步都可以識別需要代碼矯正的 Perl 語法結構或操作符問題。
第 1 步. 檢查特定 Solaris 模塊依賴項
第一步都是關于檢查導入 Perl 模塊的。其中一些專門用于構建 Solaris,一旦您使用了它們,它們就將腳本綁定到 Solaris 平臺。我們需要通過腳本代碼識別這些模塊,弄清楚它們所用的函數和變量,然后進行適當改變,以防將您困于 Perl 腳本不能運行的平臺上。
在 CPAN 庫您可以找到一個 特定 Solaris 模塊完整列表;它們的名稱通常以 Solaris:: 或 Sun:: 開頭。您可以使用清單 1 中的腳本識別 Perl 腳本文件和以 “Solaris” 或 “Sun” 開頭的導入語句。
清單 1. 如何找到 Solaris 模塊導入
find . -name "*.pl" -exec grep -ilP "^\s*use (Solaris|Sun)" {} \;
您可以修改清單 1 中的代碼,使其在 Perl 腳本內更精確地尋找特定 Solaris 模塊。例如,您可以將清單 1 中的腳本轉換成 Perl,從而利用 PPI 模塊 進行解析。模塊的使用不在本文范圍之內,但是在解析 Perl 代碼時,為更精確我們建議使用它。
在使用特定 Solaris 代碼識別腳本之后,您需要搜索可以在 Linux 系統上運行的等價模塊。就功能性而言,識別這類模塊通常并不那么容易,因為原始模塊可能涉及到 Solaris 平臺的專有技術。出現這種情況時,您就不得不執行更加深入的分析。要使用一個等價的基于 Linux 的模塊,您需要用新模塊的等價類替換所有導入語句以及所有稱為函數和變量的對象。
第 2 步. 檢查特定 Solaris 系統命令調用
從 Perl 腳本內調用操作系統命令,在執行從 Solaris 到 Linux 遷移時,可以呈現多數常見問題,原因如下:
目標系統命令缺乏
命令有不同的標志集
命令在兩個系統上表現不同
因此,在處理這些問題時,要特別關注第 2 類可移植性問題:系統調用。這里的目標是確保任何在腳本上按照語法和語義調用的系統命令,在 Linux 上都能正確運行。簡而言之,都是關于識別在含有特定 Solaris 系統命令的腳本中使用的 Perl 核心函數和操作符。讓我們從一個示例開始。清單 2 是一個用于顯示 Solaris 系統內存大小的簡單 Perl 腳本。
清單 2. Perl 腳本顯示系統內存大小
my $mem_info = `prtconf | grep Memory`;
my (undef, $mem_size) = split(':', $mem_info);
($mem_size, undef) = split(' ', $mem_size);
print "Memory size is: ".$mem_size."\n";
現在,假設我們想在 Linux 上運行同一個腳本。通過 backtick 操作符,我們斷定它調用一個管道系統命令(prtconf | grep Memory),而 prtconf 命令是特定于 Solaris 的。第一步是為它尋找一個代替品。您可以使用 cat /proc/meminfo | grep MemTotal,即使輸出的格式不同,因為 /proc/meminfo 保存信息的單位是 KB,而 prtconf 是 MB。
要矯正這些腳本,您可以使用 cat /proc/meminfo 替換 ptrconf,但將輸出信息單位保存為 MB(我們不知道這個腳本的輸出是否會用于其他腳本的輸入,因此最好不要改變),我們可以使用一個簡單的轉換。清單 3 是矯正該腳本的一個示例。
清單 3. 矯正清單 2 腳本
my $mem_info = `cat /proc/meminfo | grep MemTotal`;
my (undef, $mem_size) = split(':', $mem_info);
($mem_size, undef) = split(' ', $mem_size);
$mem_size = int($mem_size / 1000);
print "Memory size is: ".$mem_size."\n";
因為 Perl 足夠靈活,可以適應不同執行操作系統命令的方法,因此有許多不同的核心函數和操作符。表 2 列出了用來從 Perl 腳本中調用系統命令的 Perl 核心函數和操作符。
表 2. 調用系統命令的 Perl 核心函數和操作符
函數/操作符 | Solaris 中的示例 | Linux 中的示例 |
---|---|---|
backtick (`` ) |
`prstat` |
`ps -e` |
system | system("psrinfo") |
system("cat","/proc/cpuinfo") |
exec | exec("/usr/sbin/df -kZ") |
exec("/bin/df -kZ") |
qx | qx/"metastat"/ |
qx/"lvdisplay"/ |
open | open DATA, "cat /var/cron/log |" |
Open DATA, "cat /var/log/cron" |
readpipe | readpipe( "cat /etc/default/login " ) |
Readpipe( "cat /etc/default/login" ) |
第 3 步. 檢查 OS 路徑名的使用
現在,我們來研究通過 Perl 腳本遷移使用的路徑名;這一步類似于第 2 步。這里,您需要留意用于打開或操作文件的語法元素和操作符。盡管有特定操作符執行這一任務,但是在引用路徑名方面也可能出問題。(當您調用像步驟 2 中提到的那些命令時,您將會看到這些問題)。清單 4 顯示了一個小腳本,閱讀 Solaris 的 NFS 服務器配置文件并以標準輸出打印。
清單 4. 將以標準輸出打印文件系統內容的 Perl 腳本
open(NFSCONF, '/etc/default/nfs');
print <NFSCONF>;
close(NFSCONF);
當從 Solaris 遷移到 Linux 時,您需要注意系統路徑,這常常不同。在本例中,在這個 Solaris 腳本中引用的文件 /etc/default/nfs 在 Linux/Red Hat 發布版中不存在,但是可以使用 /etc/sysconfig/nfs 替代。清單 5 顯示了矯正后的腳本。
清單 5. 清單 4 的矯正
open(NFSCONF, '/etc/sysconfig/nfs');
print <NFSCONF>;
close(NFSCONF);
您需要了解操作文件的 Perl 命令。表 3 是一些在 Perl 中常見的路徑處理命令;如果其中一些用在腳本中,遷移時就需要矯正路徑名。
表 3. Perl 中常見的路徑處理命令
命令 | 描述 |
---|---|
chdir |
修改工作路徑。 |
chmod |
修改文件清單的許可。 |
glob |
返回一系列擴展文件名(可能為空)。 |
link |
創建鏈接到舊文件名的新文件名。 |
mkdir |
創建一個新路徑。 |
open |
打開一個文件。 |
opendir |
打開一個目錄。 |
rename |
修改一個文件的文件名。 |
rmdir |
刪除指定目錄。 |
sysopen |
打開特定文件,以及將它和一個特定文件句柄聯系在一起。 |
第 4 步. 檢查保存特定 Solaris 信息的特定變量
一些保存環境信息的特定變量可能是特定于 Solaris 的;您需要識別這些變量并進行適當轉換。表 4 列出了幾個可能保存特定 Solaris 信息或參考資料的關鍵變量。
表 4. 一些 Perl 核心變量
變量 | 描述 |
---|---|
ENV | 含有當前環境變量。其中一些變量可能不支持在 Solaris 和 Linux 之間直接映射,比如 NETPATH、MSGVERB 和 SEV_LEVEL。 |
SIG | 含有信號處理程序。關于在兩個平臺上發送信號的差異,見 參考資料 部分。 |
第 5 步. 識別在各種平臺上實現有所不同的函數的使用
有些核心 Perl 函數要么不能實現,要么在各個平臺上的實現都不相同;這些函數在 Solaris 和 Linux 上的表現也不同。您需要修改它們,或者找到 Linux 平臺的兼容版本并自然過渡到其中;再一次,查看 Perl Programming Documentation。
結束語
識別在從 Solaris 到 Linux(或者, HP/UX 或 AIX 到 Linux)的遷移過程中可能會引起問題的 5 個常見組件并不是很困難。但是進行必要的代碼矯正和代碼替換來將您的腳本成功地移入 Linux 很費時間,特別是如果您有很多腳本需要遷移。本文的示例和代碼矯正會幫您快速上手。祝您好運!