Come superare un problema di incompatibilità tra il ksh su Linux rispetto a quella installata sul AIX/Solaris/HPUX?

Sono coinvolti nel processo di porting di un sistema contenente diverse centinaia di ksh script da AIX, Solaris e HPUX per Linux. Ho incontrato il seguente differenza nel modo in cui ksh si comporta nei due sistemi:

#!/bin/ksh
flag=false
echo "a\nb" | while read x
do
    flag=true
done
echo "flag = ${flag}"
exit 0

Su AIX, Solaris e HPUX l’uscita è “flag = true” su Linux, l’uscita è “flag = false”.

Le mie domande sono:

  • C’è una variabile di ambiente che posso impostare per ottenere Linux ksh di comportarsi come l’
    altri Os c’e’? In mancanza di ciò:
  • C’è un’opzione su Linux ksh per ottenere il comportamento richiesto? In mancanza di ciò:
  • C’è un ksh attuazione disponibile per Linux con il comportamento desiderato?

Altre note:

  • Su AIX, Solaris e HPUX ksh è una variante di ksh88.
  • Su Linux, ksh è di dominio pubblico ksh (pdksh)
  • Su AIX, Solaris e HPUX dtksh e ksh93 (dove li ho installati) sono coerenti con ksh
  • I sistemi Windows NT che hanno accesso a: Cygwin e MKS NT, sono coerenti con Linux.
  • Su AIX, Solaris e Linux, bash è coerente, dando il non corretto (dal mio punto di vista) è il risultato di “flag = false”.

La tabella seguente riassume i sistemi il problema:

uname -s       uname -r                   which ksh          ksh version                     flag =
========       ========                   =========          ===========                     ======
Linux          2.6.9-55.0.0.0.2.ELsmp     /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
AIX            3                          /bin/ksh           Version M-11/16/88f             true    //AIX 5.3
                                          /bin/ksh93         Version M-12/28/93e             true
SunOS          5.8, 5.9 and 5.10          /bin/ksh           Version M-11/16/88i             true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
HP-UX          B.11.11 and B.11.23        /bin/ksh           Version 11/16/88                true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
CYGWIN_NT-5.1  1.5.25(0.156/4/2)          /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
Windows_NT     5                          .../mksnt/ksh.exe  Version 8.7.0 build 1859...     false    //MKS

Aggiornamento

Dopo alcuni consigli da parte di persone in mia compagnia abbiamo deciso di apportare la seguente modifica al codice. Questo ci dà lo stesso risultato utilizzando il “reale” ksh (ksh88, ksh93) o una qualsiasi delle ksh cloni (pdksh, MSK ksh). Anche questo funziona correttamente con bash.

#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
    flag=true
done < junk
echo "flag = ${flag}"
exit 0

Grazie a jj33 precedentemente accettato di rispondere.

Che distro Linux stai usando? Che fa la differenza in come ottenere il “corretto” ksh
Questa domanda è molto relative: stackoverflow.com/questions/124167/bash-variable-scope

InformationsquelleAutor Andrew Stein | 2008-09-16

8 Replies
  1. 7

    Invece di utilizzare pdksh su linux, utilizzare il “reale” ksh da kornshell.org. pdksh è un cieco re-implementazione di ksh. kornshell.org è l’originale korn shell risalenti a 25 anni o giù di lì (quello scritto da David Korn). AIX e Solaris utilizzare le versioni originali ksh, in modo che il kornshell.org la versione è di solito di funzionalità e bug – completo. Aver tagliato i miei denti con SunOS/Solaris, l’installazione di kornshell.org ksh è di solito una delle prime cose che faccio su un nuovo Linux box…

    ksh da <kornshell.org> fa il trucco!

    InformationsquelleAutor jj33

  2. 3

    Dopo alcuni consigli da parte di persone in mia compagnia abbiamo deciso di apportare la seguente modifica al codice. Questo ci dà lo stesso risultato utilizzando il “reale” ksh (ksh88, ksh93) o una qualsiasi delle ksh cloni (pdksh, MSK ksh). Anche questo funziona correttamente con bash.

    #!/bin/ksh
    echo "a\nb" > junk
    flag=false
    while read x
    do
        flag=true
    done < junk
    echo "flag = ${flag}"
    exit 0
    

    Grazie a jj33 per il precedente accettato di rispondere.

    È possibile utilizzare una named pipe invece il file temporaneo.

    InformationsquelleAutor Andrew Stein

  3. 1

    Ho installato ‘ksh’ e ‘pdksh’ nel mio Ubuntu Hardy sistema.

    ii  ksh            93s+20071105-1 The real, AT&T version of the Korn shell
    ii  pdksh          5.2.14-21ubunt A public domain version of the Korn shell
    

    ksh ha “corretto” il comportamento che ci si aspetta, mentre pdksh non. Si potrebbe controllare il vostro locale di distribuzione di Linux repository di software per un “vero” ksh, invece di utilizzare pdksh. Il “Vero Unix” OS ha intenzione di installare la AT&T versione dei Korn shell, piuttosto che pdksh, per impostazione predefinita, che con il loro essere basati su AT&T (Unix System V) :-).

    InformationsquelleAutor jtimberman

  4. 1

    La ragione per la differenza è che se all’interno del blocco viene eseguito in un originale contesto della shell o in una subshell. Si può essere in grado di controllare questo con l’ () {} raggruppamento di comandi. Utilizzando un file temporaneo, così come si fa l’aggiornamento, funziona la maggior parte del tempo, ma verrà eseguito in problemi se lo script viene eseguito due volte rapidamente, o se si esegue senza cancellare il file, etc.

    #!/bin/ksh
    flag=false
    echo "a\nb" | { while read x
    do    
         flag=true
    done }
    echo "flag = ${flag}"
    exit 0
    

    Che può aiutare con il problema che si stavano su Linux ksh. Se si utilizzano le parentesi invece di parentesi graffe, si otterrà il Linux comportamento sugli altri ksh implementazioni.

    Grazie per il suggerimento. Purtroppo questo fa il contrario di quello che voglio 🙂 sto cercando di ottenere tutti i nostri script porting da altri Unix a Linux….

    InformationsquelleAutor mpez0

  5. 1

    Qui è un’altra soluzione per echo “\n” problema

    Seguente procedura:

    1. Trovare ksh nome del pacchetto

    $ rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep "ksh"
    ksh-20100621-19.el6_4.3(x86_64)

    1. disinstallare ksh
      $ sudo yum remove ksh-20100621-19.el6_4.3.x86_64

    2. verso il basso carico di pdksh-5.2.14-37.el5_8.1.x86_64.rpm (si Prega di controllare il sistema operativo a 32-bit o 64-bit e scegliere il giusto pkg)

    3. Installare pdksh-5.2.14-37.el5_8.1.x86_64.rpm

    $ sudo yum -y install /SCRIPT_PATH/pdksh-5.2.14-37.el5_8.1.x86_64.rpm

    Uscita prima PDKSH installare

    $ ora_db_start_stop.sh
    \n==============
    Usage: START
    ==============\n\n
    ./ora_db_start_stop.sh START ALL    \n
    OR \n
    ./ora_db_start_stop.sh START ONE_OR_MORE    \n
    \n==============
    Usage: STOP
    ==============\n\n
    ./ora_db_start_stop.sh STOP ALL    \n
    OR \n
    ./ora_db_start_stop.sh STOP ONE_OR_MORE    \n\n
    

    Dopo PDKSH installare

    ==============

    Uso: INIZIARE

    ./ora_db_start_stop.sh START ALL

    O

    ./ora_db_start_stop.sh START ONE_OR_MORE

    ==============

    Uso: STOP

    ./ora_db_start_stop.sh STOP ALL

    O

    ./ora_db_start_stop.sh STOP ONE_OR_MORE

    InformationsquelleAutor venkat

  6. 0

    Non so di qualsiasi particolare opzione per forzare ksh per essere compatibile con una particolare versione precedente. Detto questo, forse si potrebbe installare una versione molto vecchia di ksh sulla vostra linux box, e si comportano in un modo compatibile?

    Potrebbe essere più facile per installare una versione più moderna di amy shell su AIX/HP-UX, e solo la migrazione di script per l’utilizzo sh. So che ci sono versioni di bash disponibile per tutte le piattaforme.

    InformationsquelleAutor zigdon

  7. 0

    Tuo script dà il giusto (vero) di uscita quando zsh viene utilizzato con il emulate -L ksh opzione. Se tutto il resto fallisce, si potrebbe desiderare di provare a utilizzare zsh su Linux.

    InformationsquelleAutor Alex M

  8. 0

    Devo restare entro ksh?

    Anche se si utilizza lo stesso ksh ti chiamano ancora tutti i tipi di comandi esterni (grep, ps, gatto, ecc…) parte di loro hanno diversi parametri e di uscita diversi da sistema a sistema. O si dovrà prendere in considerazione anche le differenze o utilizzare la versione GNU di ogni uno di loro a fare le stesse cose.

    Il Perl linguaggio di programmazione originariamente è stato concepito proprio per superare questo problema.
    Esso include tutte le caratteristiche di una shell unix programmatore avrebbe voluto da lui programma di shell, ma
    è la stessa in ogni sistema Unix. Si potrebbe non avere la versione più recente di tutti coloro
    sistemi, ma se avete bisogno di installare qualcosa, forse è meglio installare perl.

    I comandi esterni sono generalmente abbastanza costante, fino a quando si utilizza POSIX comandi. Se si imposta il POSIXLY_CORRECT=1 variabile su Linux e impostare UNIX95=1 su HP-UX (di solito si può solo impostare sia di quelli su tutte le piattaforme), quindi i comandi esterni comportano sempre allo stesso modo. E se si bastone con ksh93, come oposed 88, si ottiene un livello di funzionalità in grado di rivaleggiare con perl.

    InformationsquelleAutor szabgab

Lascia un commento