Vou me ater aos recursos de script. Recursos interativos avançados (edição de linha de comando, conclusão, prompts etc.) tendem a ser muito diferentes, atingindo efeitos semelhantes de maneiras totalmente incompatíveis. Quais recursos estão no zsh e estão ausentes no bash ou vice-versa? fornece algumas dicas sobre o uso interativo.
A coisa mais próxima do bash seria ATT ksh93 ou mksh (o shell Korn e um clone). O Zsh também possui um subconjunto de recursos, mas você precisará executá-lo no modo de emulação ksh, não no modo nativo do zsh.
Não listarei os recursos do POSIX (disponíveis em qualquer sh
shell moderno ), nem os recursos relativamente obscuros, nem os mencionados acima, para uso interativo. As observações são válidas a partir do bash 4.2, ksh 93u e mksh 40.9.20120630, conforme encontrado no Debian wheezy.
$'…'
(cadeias literais com interpolação de barra invertida) está disponível em ksh93 e mksh. `$" ... "(cadeias traduzidas) é específico do bash.
Mksh e ksh93 precisam ;&
passar por uma case
declaração, mas não ;;&
para testar casos subseqüentes. Mksh tem ;|
isso, e mksh recente permite ;;&
compatibilidade.
((…))
expressões e [[ … ]]
testes aritméticos são recursos do ksh. Alguns operadores condicionais são diferentes, consulte "expressões condicionais" abaixo.
Ksh e bash têm coprocessos, mas funcionam de maneira diferente.
Mksh e ksh93 suportam a function name {…}
sintaxe das definições de funções além do padrão name () {…}
, mas usando as function
regras de escopo das mudanças no ksh, portanto, mantenha a name () …
compatibilidade. As regras para caracteres permitidos nos nomes das funções variam; atenha-se a alfanuméricos e _
.
Ksh93 e mksh suportam expansão de chaves {foo,bar}
. O Ksh93 suporta intervalos numéricos, {1..42}
mas o mksh não.
Ksh93 e extração mksh apoio substring com ${VAR:offset}
e ${VAR:offset:length}
, mas não caso dobrar como ${VAR^}
, ${VAR,}
, etc. Você pode fazer a conversão caso typeset -l
e typeset -u
em ambos bash e ksh.
Eles suportam a substituição com ${VAR/PATTERN/STRING}
ou ${VAR/PATTERN//STRING}
. As regras de citação para STRING são um pouco diferentes, portanto, evite barras invertidas (e talvez outros caracteres) em STRING (crie uma variável e use-a ${VAR/PATTERN/$REPLACEMENT}
se a substituição contiver caracteres de citação).
Expansão Array ( ${ARRAY[KEY]}
, "${ARRAY[@]}"
, ${#ARRAY[@]}
, ${!ARRAY[@]}
) o trabalho em bash como em ksh.
${!VAR}
expandindo para ${OTHERVAR}
quando o valor de VAR
é OTHERVAR
(referência variável indireta) é específico do bash (o ksh faz algo diferente com ${!VAR}
). Para obter essa dupla expansão no ksh, você precisa usar uma referência de nome ( typeset -n VAR=OTHERVAR; echo "$VAR"
). ${!PREFIX*}
funciona da mesma maneira.
Substituição de processo <(…)
e >(…)
é suportado no ksh93, mas não no mksh.
Os padrões glob estendidos do ksh que precisam shopt -s extglob
ser ativados no bash estão sempre disponíveis no ksh93 e no mksh.
Mksh não suporta classes de personagens como [[:alpha:]]
.
Bash e ksh93 definem pseudo-arquivos e , mas mksh não./dev/tcp/HOST/PORT
/dev/udp/HOST/PORT
A expansão de curingas em um redirecionamento em scripts (como por var="*.txt"; echo hello >$a
escrito, para a.txt
se esse nome de arquivo for a única correspondência para o padrão) é um recurso específico do bash (outros shells nunca fazem isso em scripts).
<<<
as strings here funcionam no ksh como no bash.
O atalho >&
para redirecionar erros de sintaxe também é suportado pelo mksh, mas não pelo ksh93.
[[ … ]]
sintaxe de colchete duplo
A sintaxe de colchete duplo do ksh é suportada pelo ATT ksh93 e pelo mksh como no bash.
Operadores de arquivo
Ksh93, mksh e suporte do bash as mesmas extensões para POSIX, incluindo -a
como um sinônimo obsoleta de -e
, -k
(pegajosa), -G
(propriedade da egid), -O
(proprietário por euid), -ef
(mesmo arquivo), -nt
(mais recente do que), -ot
(acima de).
-N FILE
(modificado desde a última leitura) não é suportado pelo mksh.
Mksh não tem um operador de correspondência de regexp =~
. O Ksh93 possui esse operador e executa a mesma correspondência que no bash, mas não tem o equivalente BASH_REMATCH
a recuperar grupos correspondidos posteriormente.
Operadores de string
Ksh93 e mksh suportam os mesmos operadores de comparação de cadeias <
e >
bash, além do ==
sinônimo =
. Mksh não usa configurações de localidade para determinar a ordem lexicográfica, ele compara cadeias como cadeias de bytes.
Outros operadores
-v VAR
para testar se uma variável está definida é específico do bash. Em qualquer shell POSIX, você pode usar [ -z "${VAR+1}" ]
.
O conjunto de caracteres permitidos nos nomes alternativos não é o mesmo em todos os shells. Eu acho que é o mesmo que para funções (veja acima).
O Ksh93 possui um builtin
built-in chamado , mas não executa um nome como um comando interno . Use command
para ignorar aliases e funções; isso chamará um builtin, se houver, caso contrário, um comando externo (você pode evitar isso com PATH= command error_out_if_this_is_not_a_builtin
).
Isso é específico do bash. Você pode obter um efeito semelhante com .sh.fun
, .sh.file
e .sh.lineno
no ksh93. Em mksh, finalmente LINENO
.
declare
é um nome específico do bash para ksh's typeset
. Uso typeset
: ele também funciona no bash.
Mksh define local
como um alias para typeset
. No ksh93, você precisa usar typeset
(ou definir um alias).
Mksh não possui matrizes associativas (elas estão previstas para uma versão ainda não lançada).
Eu não acho que exista um equivalente exato do bash typeset -t
(função trace) no ksh.
Ksh93 não tem -e
.
Ksh93 e mksh processam as opções -e
e -n
como no bash. Mksh também entende -E
, o ksh93 não o trata como uma opção. A expansão da barra invertida está desativada por padrão em ksh93, ativada por padrão em mksh.
O Ksh não fornece uma maneira de desativar os comandos internos. Para evitar um builtin, procure o caminho do comando externo e chame-o explicitamente.
Ksh93 tem -a
mas não -l
. Mksh não tem nenhum.
Nem ksh93 nem mksh tem export -n
. Em typeset +x foo
vez disso, use em bash e ksh.
O Ksh não exporta funções através do ambiente.
let
é o mesmo no bash e no ksh.
Este é um recurso específico do bash. Você pode usar while read
loops ou substituição de comando para ler um arquivo e dividi-lo em uma matriz de linhas. Cuide IFS
e globbing. Aqui está o equivalente a mapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
é muito parecido. Eu acho que o ksh93 suporta todas as diretivas de formato do bash. mksh não suporta %q
ou %(DATE_FORMAT)T
; em algumas instalações, printf
não é um mksh embutido e chama o comando externo.
printf -v VAR
é específico do bash, o ksh sempre imprime na saída padrão.
Várias opções são específicas do bash, incluindo todas sobre o readline. As opções -r
, -d
, -n
, -N
, -t
, -u
são idênticos em bash, ksh93 e mksh.
Você pode declarar uma variável como somente leitura no Ksh93 e mksh com a mesma sintaxe. Se a variável for uma matriz, você precisará atribuir a ela primeiro e depois torná-la somente leitura com readonly VAR
. As funções não podem ser feitas somente leitura em ksh.
Todas as opções para set
e set -o
são recursos POSIX ou ksh.
shopt
é específico do bash. Muitas opções dizem respeito ao uso interativo de qualquer maneira. Para efeitos sobre globos e outros recursos ativados por algumas opções, consulte a seção “Opções” abaixo.
Esta variante de .
existe também no ksh. No bash e mksh, source
pesquisa o diretório atual depois PATH
, mas no ksh93, é um equivalente exato de .
.
O DEBUG
pseudo-sinal não é implementado no mksh. No ksh93, ele existe com uma maneira diferente de relatar informações, consulte o manual para obter detalhes.
No ksh, type
é um apelido para whence -v
. No mksh, type -p
não imprime o caminho para o executável, mas uma mensagem legível por humanos; você precisa usar whence -p COMMAND
em seu lugar.
Opções
shopt -s dotglob
- não ignore arquivos de ponto no globbing
Para emular a dotglob
opção no ksh93, você pode definir FIGNORE='@(.|..)'
. Eu não acho que exista algo assim no mksh.
shopt -s extglob
- padrões estendidos ksh de glob
A extglob
opção está efetivamente sempre ativada em ksh.
shopt -s failglob
- erro se um padrão glob não corresponder a nada
Eu não acho que isso exista no mksh ou no ksh93. Ele faz em zsh (comportamento padrão, a menos null_glob
ou csh_null_glob
são set).
O Ksh93 possui globbing recursivo com **/
, ativado com set -G
. Mksh não tem globbing recursivo.
shopt -s lastpipe
- execute o último comando de um pipeline no shell pai
O Ksh93 sempre executa o último comando de um pipeline no shell pai, que no bash requer que a lastpipe
opção seja definida. Mksh sempre executa o último comando de um pipeline em um subshell.
shopt -s nocaseglob
, shopt -s nocasematch
- padrões que não diferenciam maiúsculas de minúsculas
Mksh não possui correspondência de padrão que não diferencia maiúsculas de minúsculas. O Ksh93 o suporta padrão por padrão: prefixe o padrão com ~(i)
.
shopt -s nullglob
- expanda padrões que não correspondem a nenhum arquivo para uma lista vazia
Mksh não tem isso. O Ksh93 o suporta padrão por padrão: prefixe o padrão com ~(N)
.
Obviamente, a maioria das BASH_xxx
variáveis não existe no ksh. $BASHPID
pode ser emulado com o caro, mas portátil sh -c 'echo $PPID'
e foi adicionado recentemente ao mksh. BASH_LINE
está .sh.lineno
em ksh93 e LINENO
em mksh. BASH_SUBSHELL
está .sh.subshell
em ksh93.
Mksh e ksh93 fornecem o arquivo fornecido ENV
quando são inicializados.
EUID
e UID
não existe no ksh93. Mksh os chama USER_ID
e KSH_UID
; não tem GROUPS
.
FUNCNAME
e FUNCNEST
não existe em ksh. Ksh93 tem .sh.fun
e .sh.level
. As funções declaradas com function foo { …; }
(sem parênteses!) Têm seu próprio nome $0
.
GLOBIGNORE
existe no ksh93, mas com um nome e sintaxe diferentes: é chamado FIGNORE
e é um padrão único, não uma lista separada por dois-pontos. Use um @(…|…)
padrão. O Ksh substitui o FIGNORE
bash's, com uma sintaxe totalmente diferente.
Ksh93 e mksh não têm nada como HOSTTYPE
, MACHTYPE
e OSTYPE
. Nem SHELLOPTS
ou TIMEFORMAT
.
Mksh tem PIPESTATUS
, mas ksh93 não.
Mksh e ksh93 têm RANDOM
.