Como posso obter com segurança a versão do ksh de um script ksh?
ksh --version
echo ${.sh.version}
echo $KSH_VERSION
E, dadas as circunstâncias corretas, cada uma delas funciona corretamente. No entanto, eu me preocupo com o caso não perfeito.
Especificamente, existem várias máquinas com as quais trabalho que possuem versões mais antigas do ksh que, para meus propósitos, estão com uma falta grave de funcionalidade. De qualquer forma, o motivo pelo qual desejo verificar a versão (programaticamente) é ver se a versão ksh é uma das versões menos capazes; e, se assim for, quero executar um ramo com código menos impressionante.
No entanto, nas máquinas problemáticas, a inaptidão do shell se estende à verificação da versão ...
- Se eu tentar
ksh --version
, ele não imprime nada e abre uma nova instância doksh
! Se eu tentar
echo ${.sh.version}
,ksh
trata isso como um erro de sintaxe que não pode ser descartado2> /dev/null
.$ echo ${.sh.version} 2> /dev/null ksh: ${.sh.version}: bad substitution
É claro que
echo $KSH_VERSION
parece funcionar bem - quero dizer, não falhará - embora nessas máquinas esteja em branco. Além disso, eu vi em algum lugar queKSH_VERSION
é definido apenas porpdksh
.
Questões:
- Como posso verificar com segurança a versão do
ksh
programaticamente? Para meus propósitos aqui, eu realmente não me importo com o número da versão real, apenas se é uma versão desatualizada doksh
. - É
$KSH_VERSION
bom o suficiente? Quero dizer, se estiver em branco, então éksh
necessariamente uma versão desatualizada? Esse outro fórum estava correto e pode não ser definido mesmo para versões mais recentesksh
? - Não há como verificar isso?
fonte
PS1
para usar essa função. No entanto, ksh Velho não suporta$()
noPS1
. Portanto, se é uma versão moderna do ksh, queroPS1
usar a função que criei; se é a versão antiga, eu uso apenas$PWD
.Respostas:
Eu acho que
.sh.version
existe desde a primeira versão do ATT ksh 93. Não está disponível em pdksh ou mksh. Desde a${.sh.version}
existe um erro de sintaxe em shells diferentes de ksh93, envolva o teste em um subshell e proteja-oeval
.KSH_VERSION
começou no clone ksh de domínio público (pdksh) e foi adicionado ao shell Korn real há relativamente pouco tempo, em 2008, com o ksh93t.Em vez de testar o número de uma versão, você deve testar o recurso específico que está causando sofrimento. A maioria dos recursos pode ser testada, tentando alguma construção em um subshell e veja se ele desencadeia um erro.
fonte
${.sh.version}
como um erro de sintaxe que não pode ser reconciliado. A mensagem que recebo ébad substitution
./dev/null
e ignore o status de saída.eval '_sh_version=$(echo "${.sh.version}")' 2>/dev/null
melhor?KSH_VERSION
não foi implementadoksh93
antes da versão 93t. Ele será definido emmksh
,pdksh
,lksh
. Então, para verificar a versão doksh
, podemos tentar estas etapas:KSH_VERSION
para detectarmksh
,pdksh
,lksh
ksh93
eksh88/86
( deixe David Korn nos mostrar ).Com isso em mente, irei com:
fonte
$KSH_VERSION
não está em branco? Na minha máquina Ubuntu, isso imprime "ksh93", aindaKSH_VERSION
está definido..kshrc
.ENV
variável estiver definida (e normalmente estiver definida como~/.kshrc
), o script definitivamente lerá o.kshrc
arquivo. Obviamente, seria bastante estranho para um script definir um KSH_VERSION falso, mas isso é possível, assim como executar explicitamente um script com um intérprete diferente do especificado na primeira linha é uma situação possível.KSH_VERSION
. E emmksh
,pdksh
,lksh
,KSH_VERSION
é marcado como somente leitura.Para
ksh
lançamentos "reais" (ou seja, baseados na AT&T), eu uso este comando:Aqui estão várias saídas que recebo:
Ksh original:
dtksh;
Ksh93 moderno:
Para
pdksh
/msh
ksh
clones eksh
versões modernas da AT&T também, aqui está algo que funciona:Editar:
Eu esqueci que você estava perguntando sobre fazer isso de dentro de um script, não conhecendo o caminho para o binário ksh testado.
Supondo que você realmente queira a versão
ksh
usada, e não os recursos suportados, aqui está uma maneira de fazê-lo usando apenas ostrings
comando que deve funcionar pelo menos no Linux e Solaris:Observe que esse método não é confiável, pois
/proc
pode não ser montado, e certamente existem outros pontos fracos. Não foi testado em outros sistemas operacionais Unix.fonte
lksh
epdksh
no Debian Jessie.lksh
epdksh
não pode ser separado delesKSH_VERSION
?strings
neles.KSH_VERSION
definitivamente pode.ksh
lançamentos " reais " », excluí explicitamente clones que não são da AT&T como kshpdksh
,mksh
elksh
.strings
em algum binário ksh é uma má idéia, porque você não sabe se é esse que está executando seu script. Talvez seu script esteja sendo executado por/usr/local/bin/ksh
ou/home/bob/bin/ksh
ou/bin/sh
ou/usr/posix/bin/sh
ou ...Enquanto escrevia um script
ksh
, notei que a-a
opção dowhence
comando interno do ksh parece não ser suportada em versões mais antigas doksh
. E isso parece ser verdade em todos os sistemas que verifiquei, incluindo Solaris, AIX, HP-UX e Linux.Então, aqui está a solução como uma função ksh:
E aqui está como usá-lo:
fonte
${.sh.version}
?whence
no Zsh tem-a
whence
comando interno, que não está de forma alguma vinculado ao ksh ou à sua versão. Nem sei por que você gostaria de verificar se o ksh é uma versão antiga de uma instância do zsh, que é um shell completamente diferente./bin/ksh
, por exemplo, no Debian Linux. Agora não o uso lá (e no momento não posso alterar meu shell de login para verificar), então não sei se ele lê.kshrc
ou não, mas eu suspeitaria que sim.CTRL+ ALT+V
ou
ESC, CTRL+V
Em geral, eles se mostraram muito confiáveis na determinação interativa da versão do KSH que você está usando, no entanto, a criação de scripts para eles se mostrou mais difícil.
fonte
set -o vi
para definir as combinações de teclas como vi. Antes disso, ou com + o vi ou -o emacs, simplesmente não me mostrava. PD KSH v5.2.14 99/07 / 13.2 no OpenBSD 6.1Eu acho que o problema fundamental com o uso de $ {. Sh.version} é que o ksh88 para, com um código de saída diferente de zero.
Portanto, minha solução é colocar o código que faz referência a $ {. Sh.version} em um sub-shell e, em seguida, testar se o sub-shell sai diferente de zero e possui um código no sub-shell que funcionará nas versões do o ksh em que a referência a $ {. sh.version} funciona. Embrulhando-o em uma função que é chamada por outra função que reverte o código de retorno, para que a chamada final seja verificada como verdadeira.
Eu executei isso no AIX e Oracle Enterprise Linux 5 e 6, com ksh88, ksh93 e pdksh.
Pete
fonte
.sh.version
(na verdade,KSH_VERSION
é um apelido para ele). Além disso, alguns shells, como o NetBSD sh, simplesmente param de ler após o encontro${.sh.version}
e nenhuma quantidade de redirecionamento pode mantê-los executando o script.O seguinte parece funcionar razoavelmente bem para todos os shells que testei, incluindo o antigo ksh88e e uma gama quase completa de clones Ksh comuns (embora apenas uma versão de cada), embora ainda não testei um shell Bourne original real ( e isso pode exigir a adaptação da
test
expressão para versões mais antigas ....Termo aditivo:
Agora também testei com sucesso isso com o Heirloom Bourne Shell, embora com um programa externo (e mais moderno)
test
.fonte
${.sh.version}
não podem fazer parte da solução, porque certas versões do ksh - as versões em que a postagem original se preocupava - erro fatal nessa sintaxe.