2013-03-28 17 views
7

मैं एक प्रणाली को पोर्ट करने की प्रक्रिया में शामिल हूं जिसमें AIX 6.1 से SUSE-Linux तक कई ksh स्क्रिप्ट शामिल हैं। मैं निम्नलिखित अंतर सामने आने वाले में जिस तरह से ksh दो प्रणालियों पर बर्ताव करता है:स्थानीय चर द्वारा वैश्विक वैरिएबल को ओवरराइट करने के लिए लिनक्स पर ksh को कैसे रोकें?

# LocalVar.sh 

test_loc_var() 
{ 
typeset -t var 
var=localvariable 
echo "var = $var" 
} 

typeset var=globalvariable 

echo "var = $var" 
test_loc_var 
echo "var = $var" 

AIX पर सही परिणाम है:

var = globalvariable 
var = localvariable 
var = globalvariable 

लिनक्स पर गलत परिणाम है:

var = globalvariable 
var = localvariable 
var = localvariable 

मेरे प्रश्न हैं:

  • है वहाँ एक पर्यावरण चर है कि मैं एईक्स पर व्यवहार करने के लिए लिनक्स के ksh पाने के लिए सेट कर सकते हैं? विफल रहा है:
  • क्या आवश्यक व्यवहार प्राप्त करने के लिए लिनक्स के क्षीण पर कोई विकल्प है? विफल रहा है:
  • लिनक्स पर वांछित व्यवहार प्राप्त करने के लिए कोड में मुझे क्या परिवर्तन करना है?

नोट:

  • मैं पहले से ही "स्थानीय" के साथ चर घोषित करने की कोशिश की है, लेकिन है कि लिनक्स पर एक त्रुटि दी, AIX पर यह काम करता है।

निम्नलिखित तालिका सारांशित दो प्रणालियों:

uname -s     | Linux     AIX   
uname -r     | 2.6.16.60-0.54.5-smp  1 
which ksh    | /bin/ksh     /usr/bin/ksh 
rpm -qa | grep -i ksh | ksh-93s-59.11.35   - 
lslpp -l | grep -i ksh | -      bos.rte.shell 6.1.8.15 APPLIED Shells (bsh, ksh, csh) 

उत्तर

4

टी एल; डॉ: तुच्छ मामलों के लिए: f() compound-command से function f { ...; } करने के लिए अपने समारोह परिभाषा वाक्य रचना स्विच करें। जटिल मामलों के लिए: केवल ksh93-(अधिक लचीला) पर निर्भर करता है, नीचे बेतुका हैक (हार्ड) का उपयोग करें, सख्ती से POSIX अनुरूप (शायद कठिन, अनावश्यक) होने के लिए पुनः लिखें, वास्तविक भाषा में फिर से लिखें (लेकिन कभी-कभी गोले अच्छे होते हैं)।

कोई "लिनक्स ksh" नहीं है। यह सभी प्रणालियों पर समान व्यवहार करता है और केवल उस संस्करण पर निर्भर करता है जिसका आप उपयोग कर रहे हैं।

AIX एक संशोधित ksh88 जहाज। ksh88 में गतिशील स्कोप सिस्टम था, बैश और अन्य सभी गोले के समान जो स्थानीय लोगों का समर्थन करते थे, लेकिन ksh93 के विपरीत। स्थानीय लोगों को ksh93 के अंतर्गत काम करने के लिए, आपको कार्यों को परिभाषित करने के लिए POSIX वाक्यविन्यास के बजाय "आधुनिक" function name { ; } वाक्यविन्यास का उपयोग करना होगा। यह ksh88 में आवश्यक हो सकता है या नहीं भी हो सकता है, क्योंकि यह दस्तावेज नहीं है और परीक्षण करने के लिए मेरे पास कोई संभावित तरीका नहीं है, क्योंकि ksh88 मालिकाना सॉफ़्टवेयर है और संभवतः आधुनिक x86 हार्डवेयर पर चलाने के लिए भी बनाया गया नहीं है।

यदि उपर्युक्त सही है, और आपकी स्क्रिप्ट ksh88 के लिए लिखी गई थीं, तो बस फ़ंक्शन परिभाषा सिंटैक्स स्विच करना स्थानीय चर के लिए कम से कम कार्य करने के लिए पर्याप्त है। हालांकि, जबकि ksh93 का स्थिर दायरा अन्य गोले के गतिशील दायरे से काफी बेहतर है, यह गंभीर पोर्टेबिलिटी समस्या का कारण बनता है - शायद सभी शैल स्क्रिप्टिंग में काम करना सबसे मुश्किल है।

यदि आपको पोर्टेबल स्थानीय लोगों की आवश्यकता है, तो कोई शानदार समाधान नहीं है। मैं दो तकनीकों के साथ आया हूं जो ksh88/bash/mksh/zsh आदि जैसे "ब्रेक" ksh scope

गैर-टूटे हुए पॉज़िक्स शैल में पहला काम करता है।

#!/bin/sh 
# (Partially) Working shells: dash, posh, bash, ksh93v, mksh, older zsh 
# Broken shells: current zsh, busybox sh, non-bleeding edge alpha ksh93, heirloom 

f() { 
    if ! ${_called_f+false}; then 
     # Your code using "x" 
     for x; do 
      printf '%s, ' "$x" 
     done 
    else 
     # This hackishly localizes x to some degree 
     _called_f= x= command eval typeset +x x 2\>/dev/null \; f '"[email protected]"' 
    fi 
} 

# demonstration code 
x='outside f'; printf "$x, "; f 1 2 3; echo "$x" 

दूसरी विधि केवल ksh की तरह गोले में काम करता है और स्पष्ट रूप से संदर्भ द्वारा सब कुछ गुजर और बड़े पैमाने पर अविवेक का उपयोग कर शामिल है।

#!/usr/bin/env ksh 
# bash, ksh93, mksh, zsh 
# Breaking things for dash users is always a plus. 

# This is crude. We're assuming "modern" shells only here. 
${ZSH_VERSION+false} || emulate ksh 
${BASH_VERSION+shopt -s lastpipe extglob} 
unset -v is_{ksh93,mksh} 
case ${!KSH_VERSION} in 
    .sh.version) is_ksh93= ;; 
    KSH_VERSION) is_mksh= 
esac 

function f { 
    # We want x to act like in dynamic scope shells. (not ksh93) 
    typeset x 
    g x 
    typeset -p x 
} 

function g { 
    # Note mksh and bash 4.3 namerefs kind of suck and are no better than eval. 
    # This makes a local of a pointer to the variable arg of the same name. 
    # Remember it's up to the programmer to ensure the sanity of any NAME 
    # passed through an argument. 

    ${is_ksh93+eval typeset -n ${1}=\$1} 
    typeset y=yojo 

    # mksh... you fail at printf. We'll try our best anyway. 
    eval "$(printf %${is_mksh+.s%s=%s%.s }s=%q "$1" ${is_mksh+"${[email protected]}"} "$y")" 
} 


f 

यदि आप कुछ है कि वह भी पोर्टेबल हो गया है मजबूत पुस्तकालय कोड लिखने की आवश्यकता है में से एक हैं मैं केवल इनमें से किसी सलाह देते हैं।

+0

हैलो ओर्माज, आपके विस्तृत और बहुत उपयोगी उत्तर के लिए बहुत बहुत धन्यवाद। ऐसा लगता है कि मुझे उम्मीद थी कि मुझे झूठी उम्मीदें और अधिक करने की उम्मीद है। लेकिन अब मैं कम से कम जानता हूं कि माइग्रेशन प्रक्रिया में आने वाली समस्याओं में कैसे आगे बढ़ें। – Cologne2202

संबंधित मुद्दे