2014-04-04 66 views
0

我有一個需要在(主要)3環境(AIX,Linux [Red hat],sun [幾乎不會因遷移而導致])下運行的腳本,但始終在ksh ksh93的)在不同ksh環境下的賦值變量

我嘗試將值分配給變量,將在3環境在工作,特別是導致操作的像wc -lsed/awk,...

由於規格和外殼解釋我無法找到一個通用的代碼爲了這。我可以使用if命令來使用分配的代碼庫的特定版本在OS但代碼必須由每個殼的問題(和eval溶液)

樣品與陣列聲明理解

if ${HostLinux} 
then 
    eval 'typeset -a aModeTrace=([0]=false [1]=false [2]=false [3]=false)' 
else 
    eval 'set -A aModeTrace false false false false' 
fi 

現在我有一個字符串sed和分配給一個變量 AIX的代碼工作,

ThisLine="have a \" and a ' or maybe a \\; and many more other char like any log file could have" 
cst_PrintfPipeOS=" 
" 
SampleSize=24 
printf '%s%s' "${ThisLine}" "${cst_PrintfPipeOS}" | sed -e "s/^\(.\{${SampleSize}\}\).*/\1/" | read Result 

容易,我可以使用3 VAR HostLinuxHostSunHostAix設置爲true/false取決於運行environement(只有1是真實的,你可以想象)

1)如何處理相當於|在linux讀取其中代碼不會在AIX掛/ SUN使用結果=(代碼等read Result <<<掛在AIX) 2)「some code」依賴的"'內容和可變周圍報價

我儘量避免eval每個分配行(有超過1500線,想象中的代碼和註釋和樂趣調試)


解決方案使用(感謝@Gilles)

使用="$(some code without escape specific)華里EK爲='some code'(」爲反引號)

Result1="`echo '\"'`" 
Result2="$(echo '"')" 
echo '+Grep' 
set | egrep "[R]esult" 

-> 

Result1=" 
Result2=" 
+Grep 
Result1='"' 
Result2='"' 

特定無法識別碼仍然需要通過字符串‘評估’

回答

2

簡短的回答:在所有平臺上使用ksh93

set -A語法爲ksh的所有版本中的作品分配值。如果您在bash下運行腳本,則只需使用備用typeset -a語法。最簡單的解決方案是始終在ksh下運行你的代碼。所有的平臺都有ksh93,所以只需要使用它:在Linux上,安裝ksh包並使用它而不是bash。在ksh93下,你也可以使用a=(aModeTrace false false false false);這也適用於bash,但不適用於ksh88(AIX的ksh is ksh88 but there is also a ksh93`)。

如果您絕對需要在ksh88和bash之間可移植的腳本,則可以將eval hackery放入函數中。只有整個數組分配需要以這種方式進行包裝,訪問單個元素的語法,數組大小和單個元素分配是相同的。使用shell而不是操作系統來選擇實現。

## set_array ARRAY ELEMENT0 ELEMENT1 … 
## Set the variable ARRAY to contain the specified elements. Like 
## ARRAY=(ELEMENT0 ELEMENT1 …), but also supply a method that works in ksh88. 
if [[ -n $BASH_VERSION ]]; then eval ' 
    set_array() { eval "shift; $1=(\"\[email protected]\")"; }' 
else eval ' 
    set_array() { typeset __set_array_var=$1; shift 
    set -A $__set_array_var -- "[email protected]" 
    }' 
fi 

(請注意,在KSH,set -A "[email protected]"幾乎工作,但不完全:如果數組的第一個元素以破折號開始就失敗。)

字符串分配和引用的工作以同樣的方式在所有的炮彈,那裏都沒有可移植性問題。

要分配命令的輸出,請使用命令替換(同樣,它是可移植的)。輸出改變的唯一方法是刪除尾隨的換行符(不像read,它擴大反斜槓並修剪前導空白和尾隨空白)。

Result="$(printf '%s%s' "${ThisLine}" "${cst_PrintfPipeOS}" | 
    sed -e "s/^\(.\{${SampleSize}\}\).*/\1/")" 
+0

應該不錯,但我沒有可能在每個系統上都有ksh93,有些但不是全部如此,同樣的問題如果我測試這個選項也會發生其他意外的行爲。 – NeronLeVelu

+0

+1爲「$(...)」,似乎與包含單個引號的變量一起工作,其中''失敗(在我的AIX測試中)。還有一些測試來驗證你的答案。謝謝 – NeronLeVelu

+1

@NeronLeVelu'$(...)'可以在所有現代shell(bash,ksh,dash,...)中無縫地工作,只有在一些舊的Bourne shell中需要使用古怪的反引號語法。我強烈建議在任何地方安裝ksh93(它*在任何地方都可用),但是如果您絕對需要可以在ksh88和bash中運行的腳本,我已經編輯了我的答案,以說明如何處理陣列分配的不同語法。 – Gilles