C shell - C shell

Shell C
Tcsh ejecutándose en escritorio Mac OSX.png
tcsh e sh lado a lado em um desktop Mac OS X
Autor (es) original (is) Bill Joy
lançamento inicial 1978 ; 43 anos atrás ( 1978 )
Versão estável
6.20.00 / 24 de novembro de 2016 ; 4 anos atras ( 2016-11-24 )
Repositório Edite isso no Wikidata
Escrito em C
Sistema operacional BSD , UNIX , Linux , macOS
Modelo Shell Unix
Licença Licença BSD
C Shell em execução no Windows Services for UNIX

O shell C ( csh ou a versão melhorada, tcsh ) é um shell Unix criado por Bill Joy quando ele era um estudante de graduação na University of California, Berkeley, no final dos anos 1970. Ele foi amplamente distribuído, começando com o lançamento 2BSD do Berkeley Software Distribution (BSD), que Joy distribuiu pela primeira vez em 1978. Outros contribuidores iniciais para as idéias ou o código foram Michael Ubell, Eric Allman , Mike O'Brien e Jim Kulp.

O shell C é um processador de comando que normalmente é executado em uma janela de texto, permitindo ao usuário digitar e executar comandos. O shell C também pode ler comandos de um arquivo, chamado de script . Como todos os shells Unix, ele suporta caracteres curinga de nome de arquivo , piping , aqui documentos , substituição de comando , variáveis e estruturas de controle para teste de condição e iteração . O que diferenciava o shell C dos outros, especialmente na década de 1980, eram seus recursos interativos e estilo geral. Seus novos recursos tornaram o uso mais fácil e rápido. O estilo geral da linguagem parecia mais com C e era visto como mais legível.

Em muitos sistemas, como macOS e Red Hat Linux , csh é na verdade tcsh , uma versão aprimorada de csh. Freqüentemente, um dos dois arquivos é um link físico ou um link simbólico para o outro, de modo que qualquer um dos nomes se refere à mesma versão aprimorada do shell C.

No Debian e alguns derivados (incluindo Ubuntu ), existem dois pacotes diferentes: csh e tcsh. O primeiro é baseado na versão BSD original do csh e o último é o tcsh melhorado.

tcsh adicionou os conceitos de nome de arquivo e conclusão de comando e edição de linha de comando emprestados do sistema Tenex , que é a fonte do "t". Como ele apenas adicionava funcionalidade e não alterava o que estava lá, o tcsh permaneceu compatível com o shell C original. Embora tenha começado como um branch lateral da árvore de código-fonte original que Joy havia criado, tcsh é agora o branch principal para o desenvolvimento contínuo. tcsh é muito estável, mas novos lançamentos continuam a aparecer aproximadamente uma vez por ano, consistindo principalmente de pequenas correções de bugs.

Objetivos e recursos do design

Os principais objetivos do projeto para o shell C eram que ele se parecesse mais com a linguagem de programação C e fosse melhor para uso interativo.

Mais como C

O sistema Unix foi escrito quase exclusivamente em C, então o primeiro objetivo do shell C era uma linguagem de comando que fosse mais estilisticamente consistente com o resto do sistema. As palavras-chave, o uso de parênteses e a gramática de expressão interna do shell C e o suporte para matrizes foram todos fortemente influenciados por C.

Pelos padrões de hoje, o C shell pode não parecer muito mais com o C do que muitas outras linguagens de script populares. Mas, ao longo dos anos 80 e 90, a diferença era vista como notável, principalmente quando comparada ao shell Bourne (também conhecido como sh ), o shell então dominante escrito por Stephen Bourne no Bell Labs . Este exemplo ilustra mais convencionais do escudo C operadores de expressão e sintaxe .

Bourne shell

#!/bin/sh
if [ $days -gt 365 ]
then
   echo This is over a year.
fi

Shell C

#!/bin/csh
if ( $days > 365 ) then
   echo This is over a year.
endif

O Bourne sh carecia de uma gramática de expressão . A condição entre colchetes teve que ser avaliada pelos meios mais lentos de execução do programa de teste externo . O ifcomando de sh tomou suas palavras de argumento como um novo comando a ser executado como um processo filho . Se o filho saísse com um código de retorno zero , sh procuraria uma cláusula then (uma instrução separada, mas geralmente escrita junta na mesma linha com um ponto-e-vírgula) e executaria aquele bloco aninhado. Caso contrário, ele executaria o else. A vinculação física do programa de teste como " test" e " [" deu a vantagem de notação dos colchetes e a aparência de que a funcionalidade de teste fazia parte da linguagem sh. O uso de sh de uma palavra-chave invertida para marcar o final de um bloco de controle foi um estilo emprestado do ALGOL 68 .

Por outro lado, o csh pode avaliar a expressão diretamente, o que a torna mais rápida. Ele também alegou melhor legibilidade: suas expressões usavam uma gramática e um conjunto de operadores copiados principalmente de C, nenhuma de suas palavras-chave foi invertida e o estilo geral também era mais parecido com C.

Aqui está um segundo exemplo, comparando scripts que calculam as primeiras 10 potências de 2.

Bourne shell

#!/bin/sh
i=2
j=1
while [ $j -le 10 ]
do
   echo '2 **' $j = $i
   i=`expr $i '*' 2`
   j=`expr $j + 1`
done

Shell C

#!/bin/csh
set i = 2
set j = 1
while ( $j <= 10 )
   echo '2 **' $j = $i
   @ i *= 2
   @ j++
end

Novamente, devido à falta de uma gramática de expressão, o script sh usa a substituição de comando e o comando expr . (Modern shell POSIX faz ter essa gramática: a declaração poderia ser escrito i=$((i * 2))ou : $((i *= 2)).)

Finalmente, aqui está um terceiro exemplo, mostrando os estilos diferentes para uma instrução switch .

Bourne shell

#!/bin/sh
for i in d*
do
   case $i in
      d?) echo $i is short ;;
      *) echo $i is long ;;
   esac
done

Shell C

#!/bin/csh
foreach i ( d* )
   switch ( $i )
      case d?:
         echo $i is short
         breaksw
      default:
         echo $i is long
   endsw
end

No script sh, " ;;" marca o final de cada caso, pois, caso contrário, sh não permite instruções nulas.

Melhorias para uso interativo

O segundo objetivo era que o C shell fosse melhor para uso interativo. Ele introduziu vários novos recursos que tornaram mais fácil, rápido e amigável usar a digitação de comandos em um terminal. Os usuários podiam fazer as coisas com muito menos pressionamentos de tecla e funcionava mais rápido. Os mais significativos desses novos recursos foram o histórico e os mecanismos de edição, aliases, pilhas de diretório, notação de til, cdpath, controle de trabalho e hash de caminho. Esses novos recursos provaram ser muito populares e muitos deles foram copiados por outros shells Unix.

História

O histórico permite que os usuários recuperem comandos anteriores e os executem novamente digitando apenas algumas teclas rápidas. Por exemplo, digitar dois pontos de exclamação (" !!") como um comando faz com que o comando imediatamente anterior seja executado. Outras combinações de teclas curtas, por exemplo, " !$" (significando "o argumento final do comando anterior"), permitem que pedaços de comandos anteriores sejam colados e editados para formar um novo comando.

Operadores de edição

A edição pode ser feita não apenas no texto de um comando anterior, mas também nas substituições de variáveis. Os operadores variam de uma simples pesquisa / substituição de string até a análise de um nome de caminho para extrair um segmento específico.

Apelido

Aliases permitem que o usuário digite o nome de um alias e faça com que o shell C o expanda internamente em qualquer conjunto de palavras que o usuário tenha definido. Para muitas situações simples, os aliases são executados com mais rapidez e são mais convenientes do que os scripts.

Pilha de diretórios

A pilha de diretórios permite que o usuário empurre ou pop o diretório de trabalho atual , tornando mais fácil ir e voltar entre diferentes locais no sistema de arquivos.

Notação de til

A notação Til oferece uma forma abreviada de especificar nomes de caminhos relativos ao diretório inicial usando o ~caractere " ".

Preenchimento de nome de arquivo

A tecla escape pode ser usada interativamente para mostrar possíveis conclusões de um nome de arquivo no final da linha de comando atual.

Cdpath

Cdpath estende a noção de um caminho de pesquisa para o cdcomando (alterar diretório): Se o diretório especificado não estiver no diretório atual , o csh tentará encontrá-lo nos diretórios cdpath.

Controle de trabalho

Bem na década de 1980, a maioria dos usuários só tinha terminais de modo de caractere simples que impediam várias janelas, então eles só podiam trabalhar em uma tarefa por vez. O controle de trabalho do C shell permitiu ao usuário suspender a atividade atual e criar uma nova instância do C shell, chamada de trabalho, digitando ^Z. O usuário pode então alternar entre os trabalhos usando o fgcomando. O trabalho ativo estava em primeiro plano. Outros jobs foram considerados suspensos (interrompidos) ou executados em segundo plano .

Hashing de caminho

O hashing de caminho acelera a busca do shell C por arquivos executáveis. Em vez de realizar uma chamada de sistema de arquivos em cada diretório de caminho, um por vez, até encontrar o arquivo ou esgotar as possibilidades, o shell C consulta uma tabela hash interna construída examinando os diretórios de caminho. Essa tabela geralmente pode dizer ao shell C onde encontrar o arquivo (se existir) sem ter que pesquisar e pode ser atualizada com o rehashcomando.

Visão geral do idioma

O shell C opera uma linha por vez. Cada linha é indexado em um conjunto de palavras separadas por espaços ou outros caracteres com significado especial, incluindo parênteses, tubagens e de entrada / saída de operadores de redirecionamento, ponto e vírgula, e E comercial.

Declarações básicas

Uma instrução básica é aquela que simplesmente executa um comando. A primeira palavra é considerada o nome do comando a ser executado e pode ser um comando interno, por exemplo,, echoou um comando externo. O resto das palavras são passadas como argumentos para o comando.

No nível da instrução básica, aqui estão alguns dos recursos da gramática:

Caracteres curinga

O shell C, como todos os shells Unix, trata qualquer argumento de linha de comando que contenha caracteres curinga como um padrão e o substitui pela lista de todos os nomes de arquivo correspondentes (consulte globbing ).

  • * corresponde a qualquer número de caracteres.
  • ? corresponde a qualquer caractere único.
  • [... ]corresponde a qualquer um dos caracteres entre colchetes. Intervalos são permitidos, usando o hífen.
  • [^... ]corresponde a qualquer caractere que não esteja no conjunto.

O shell C também introduziu várias conveniências de notação (às vezes conhecidas como globbing estendido ), desde que copiado por outros shells Unix.

  • abc{def,ghi}é a alternância (também conhecida como expansão de chave ) e se expande para abcdef abcghi .
  • ~ significa o diretório inicial do usuário atual.
  • ~usersignifica o diretório inicial do usuário .

Vários curingas no nível do diretório, por exemplo, " */*.c", são suportados.

Desde a versão 6.17.01, o caractere curinga recursivo à la zsh (por exemplo, " **/*.c" ou " ***/*.html") também é suportado com a globstaropção.

Dar ao shell a responsabilidade de interpretar curingas foi uma decisão importante no Unix. Isso significava que os curingas funcionariam com todos os comandos e sempre da mesma maneira. No entanto, a decisão se baseou na capacidade do Unix de passar longas listas de argumentos de maneira eficiente por meio da chamada de sistema exec que o csh usa para executar comandos. Por outro lado, no Windows , a interpretação do curinga é convencionalmente realizada por cada aplicativo. Este é um legado do MS-DOS, que só permitia que uma linha de comando de 128 bytes fosse passada para um aplicativo, tornando o caractere curinga pelo prompt de comando do DOS impraticável. Embora o Windows moderno possa transmitir linhas de comando de até aproximadamente 32 mil caracteres Unicode , o fardo da interpretação do curinga permanece com o aplicativo.

Redirecionamento de E / S

Por padrão, quando csh executa um comando, o comando herda os identificadores de arquivo stdio do csh para stdin , stdout e stderr , que normalmente apontam para a janela de console onde o shell C está sendo executado. Os operadores de redirecionamento i / o permitem que o comando use um arquivo para entrada ou saída.

  • > arquivo significa que o stdout será gravado no arquivo , sobrescrevendo-o se existir e criando-o se não existir. Os erros ainda chegam à janela do shell.
  • >& arquivo significa que tanto stdout quanto stderr serão gravados no arquivo , sobrescrevendo-o se existir e criando-o se não existir.
  • >> arquivo significa que o stdout será anexado no final do arquivo .
  • >>& arquivo significa que tanto stdout quanto stderr serão anexados ao final do arquivo .
  • < arquivo significa que o stdin será lido do arquivo .
  • << string é um documento aqui . Stdin irá ler as seguintes linhas até aquela que corresponde à string .

Juntando

Os comandos podem ser unidos na mesma linha.

  • ; significa executar o primeiro comando e depois o próximo.
  • &&significa executar o primeiro comando e, se for bem-sucedido com um código de retorno 0 , executar o próximo.
  • || significa executar o primeiro comando e, se falhar com um código de retorno diferente de zero, executar o próximo.

Tubulação

Os comandos podem ser conectados usando um tubo, o que faz com que a saída de um comando seja alimentada na entrada do próximo. Ambos os comandos são executados simultaneamente .

  • |significa conectar stdout a stdin do próximo comando. Os erros ainda chegam à janela do shell.
  • |& significa conectar stdout e stderr ao stdin do próximo comando.

Executar simultaneamente significa "em paralelo". Em um sistema com vários núcleos (processador múltiplo), os comandos canalizados podem literalmente ser executados ao mesmo tempo, caso contrário, o planejador no sistema operacional divide o tempo entre eles.

Dado um comando, por exemplo, " a | b", o shell cria um pipe , então inicia ambos ae bcom stdio para os dois comandos redirecionados de forma que agrava seu stdout na entrada do pipe enquanto blê stdin da saída do pipe. Pipes são implementados pelo sistema operacional com uma certa quantidade de buffer para que apossa gravar por um tempo antes que o pipe seja preenchido, mas assim que o pipe preencher, qualquer nova gravação será bloqueada dentro do sistema operacional até que bleituras suficientes para desbloquear novas gravações. Se btentar ler mais dados do que os disponíveis, ele bloqueará até ater escrito mais dados ou até que o tubo feche, por exemplo, se asair.

Substituição de variável

Se uma palavra contém um cifrão, " $", os seguintes caracteres são considerados o nome de uma variável e a referência é substituída pelo valor dessa variável. Vários operadores de edição, digitados como sufixos para a referência, permitem a edição do nome do caminho (por exemplo, " :e" para extrair apenas a extensão) e outras operações.

Citando e escapando

Os mecanismos de cotação permitem que outros caracteres especiais, como espaços em branco, curingas, parênteses e cifrões, sejam considerados como texto literal .

  • \ significa tomar o próximo caractere como um caractere literal comum.
  • "string" é uma citação fraca. Espaços em branco fechados e curingas são considerados literais, mas as substituições de variáveis ​​e comandos ainda são realizadas.
  • 'string' é uma citação forte. Toda a string incluída é considerada literal.

Substituição de comando

A substituição de comando permite que a saída de um comando seja usada como argumento para outro.

  • `comando` significa pegar a saída do comando , analisá-la em palavras e colá-la de volta na linha de comando.

Execução em segundo plano

Normalmente, quando o shell C inicia um comando, ele espera que o comando termine antes de fornecer ao usuário outro prompt, sinalizando que um novo comando pode ser digitado.

  • comando & significa iniciar o comando em segundo plano e solicitar imediatamente um novo comando.

Subshells

Um subshell é uma cópia filho separada do shell que herda o estado atual, mas pode então fazer alterações, por exemplo, no diretório atual, sem afetar o pai.

  • ( comandos ) significa executar comandos em um subshell.

Estruturas de controle

O shell C fornece estruturas de controle para teste de condição e iteração . As estruturas de controle de teste de condição são as instruções if e switch. As estruturas de controle de iteração são as instruções while, foreach e repeat.

declaração if

Existem duas formas de declaração if . A forma abreviada é digitada em uma única linha, mas pode especificar apenas um único comando se a expressão for verdadeira.

if ( expression ) command

A forma longa usa as palavras-chave then, else e endif para permitir que blocos de comandos sejam aninhados dentro da condição.

if ( expression1 ) then
    commands
else if ( expression2 ) then
    commands
    ...
else
    commands
endif

Se as palavras-chave else e if aparecem na mesma linha, csh as encadeia, em vez de aninha-las; o bloco é terminado com um único endif.

declaração switch

A instrução switch compara uma string com uma lista de padrões, que pode conter caracteres curinga. Se nada corresponder, a ação padrão, se houver, será executada.

switch ( string )
    case pattern1:
        commands
        breaksw
    case pattern2:
        commands
        breaksw
        ...
    default:
        commands
        breaksw
endsw

declaração while

A instrução while avalia uma expressão. Se for verdade, o shell executa os comandos aninhados e, em seguida, repete enquanto a expressão permanecer verdadeira.

while ( expression )
    commands
end

declaração foreach

A instrução foreach pega uma lista de valores, geralmente uma lista de nomes de arquivos produzida por curinga e, em seguida, para cada um, define a variável de loop para esse valor e executa os comandos aninhados.

foreach loop-variable ( list-of-values )
    commands
end

repetir declaração

A instrução repeat repete um único comando um número inteiro de vezes.

repeat integer command

Variáveis

O shell C implementa variáveis ​​de shell e de ambiente . Variáveis ​​de ambiente, criadas usando a setenvinstrução, são sempre strings simples, passadas para qualquer processo filho , que recupera essas variáveis ​​por meio do envp[]argumento para main().

Variáveis ​​de shell, criadas usando as instruções setou @, são internas ao C shell. Eles não são passados ​​para processos filho. Variáveis ​​de shell podem ser strings simples ou matrizes de strings. Algumas das variáveis ​​do shell são predefinidas e usadas para controlar várias opções internas do shell C, por exemplo, o que deve acontecer se um curinga não corresponder a nada.

Nas versões atuais do csh, as strings podem ter comprimento arbitrário, podendo chegar a milhões de caracteres.

Expressões

O shell C implementa uma gramática de expressão de inteiro de 32 bits com operadores emprestados de C, mas com alguns operadores adicionais para comparações de strings e testes de sistema de arquivos, por exemplo, testar a existência de um arquivo. Os operadores devem ser separados por espaços em branco de seus operandos. As variáveis ​​são referenciadas como $nome .

A precedência de operador também é emprestada de C, mas com regras de associatividade de operador diferentes para resolver a ambigüidade do que vem primeiro em uma sequência de operadores de precedência iguais. Em C, a associatividade é da esquerda para a direita para a maioria dos operadores; no shell C, é da direita para a esquerda. Por exemplo,

// C groups from the left
int i = 10 / 5 * 2;
printf( "%d\n", i ); // prints 4
i = 7 - 4 + 2;
printf( "%d\n", i ); // prints 5
i = 2 >> 1 << 4;
printf( "%d\n", i ); // prints 16
# C shell groups from the right
@ i = 10 / 5 * 2
echo $i # prints 1
@ i = 7 - 4 + 2
echo $i # prints 1
@ i = ( 2 >> 1 << 4 )
echo $i # prints 0

Os parênteses no exemplo de shell C são para evitar que os operadores de deslocamento de bits sejam confundidos como operadores de redirecionamento de E / S. Em qualquer um dos idiomas, os parênteses sempre podem ser usados ​​para especificar explicitamente a ordem de avaliação desejada, mesmo que apenas para maior clareza.

Recepção

Embora o próprio Stephen Bourne reconhecesse que o csh era superior ao seu shell para uso interativo, ele nunca foi tão popular para scripts. Inicialmente, e durante a década de 1980, não era possível garantir a presença do csh em todos os sistemas Unix, mas o sh poderia, o que o tornou uma escolha melhor para quaisquer scripts que precisassem ser executados em outras máquinas. Em meados da década de 1990, o csh estava amplamente disponível, mas o uso do csh para scripts enfrentou novas críticas do comitê POSIX , que especificou que deveria haver apenas um shell preferido, o KornShell , para fins interativos e de script. O shell C também enfrentou críticas de outros sobre os alegados defeitos de sintaxe do shell C, recursos ausentes e implementação deficiente.

  • Defeitos de sintaxe: eram geralmente simples, mas inconsistências desnecessárias na definição da linguagem. Por exemplo, os comandos set, setenve aliasfizeram basicamente a mesma coisa, a saber, associar um nome a uma string ou conjunto de palavras. Mas todos os três tinham diferenças leves, mas desnecessárias. Um sinal de igual foi exigido para a, setmas não para setenvou alias; parênteses foram necessários em torno de uma lista de palavras para um set, mas não para setenvou alias, etc. Da mesma forma, as if, switche as construções de laço usar desnecessariamente diferentes palavras-chave ( endif, endswe end) para terminar os blocos aninhados.
  • Recursos ausentes: os mais comumente citados são a falta de capacidade de manipular os identificadores de arquivo stdio de forma independente e o suporte para funções. Enquanto as funções do shell Bourne careciam apenas de variáveis ​​locais, os aliases do Csh - o análogo mais próximo no Csh das funções - eram restritos a linhas únicas de código, embora a maioria das construções de controle de fluxo exigissem que as novas linhas fossem reconhecidas. Como resultado, os scripts Csh não podiam ser funcionalmente divididos como os próprios programas C, e projetos maiores tendiam a mudar para o script de shell Bourne ou o código C.
  • A implementação: que usou um analisador ad hoc , recebeu as críticas mais sérias. No início da década de 1970, a tecnologia do compilador estava suficientemente madura para que a maioria das novas implementações de linguagem usasse um analisador de cima para baixo ou de baixo para cima capaz de reconhecer uma gramática totalmente recursiva . Não se sabe por que um design ad hoc foi escolhido em vez do C shell. Pode ser simplesmente que, como Joy disse em uma entrevista em 2009, "Quando comecei a fazer essas coisas com o Unix, não era um programador muito bom." O design ad hoc significava que a linguagem C shell não era totalmente recursiva. Havia um limite para a complexidade de um comando que ele poderia controlar.

Funcionou para a maioria dos comandos digitados interativamente, mas para os comandos mais complexos que um usuário pode escrever em um script, ele pode falhar facilmente, produzindo apenas uma mensagem de erro enigmática ou um resultado indesejável. Por exemplo, o shell C não podia suportar a tubulação entre as estruturas de controle. Tentar canalizar a saída de um foreachcomando para grepsimplesmente não funcionou. (A solução, que funciona para muitas das reclamações relacionadas ao analisador, é dividir o código em scripts separados. Se o foreachfor movido para um script separado, a tubulação funciona porque os scripts são executados bifurcando uma nova cópia do csh que herda os identificadores stdio corretos.)

Outro exemplo é o comportamento indesejado nos fragmentos a seguir. Ambos parecem significar, "Se 'meuarquivo' não existir, crie-o escrevendo 'meutexto' nele." Mas a versão à direita sempre cria um arquivo vazio porque a ordem de avaliação do shell C é procurar e avaliar os operadores de redirecionamento de E / S em cada linha de comando à medida que a lê, antes de examinar o resto da linha para ver se ela contém uma estrutura de controle.

# Works as expected
if ( ! -e myfile ) then
   echo mytext > myfile
endif
# Always creates an empty file
if (! -e myfile) echo mytext > myfile
# Workaround
if (! -e myfile) eval "echo mytext > myfile"

A implementação também é criticada por suas mensagens de erro notoriamente fracas, por exemplo, "0 evento não encontrado", que não fornece informações úteis sobre o problema.

Influência

Shell de Hamilton C de 64 bits em uma área de trabalho do Windows 7 .

O shell C foi extremamente bem-sucedido na introdução de um grande número de inovações, incluindo o mecanismo de histórico , aliases , notação de til , conclusão de nome de arquivo interativo, uma gramática de expressão embutida no shell e mais, que desde então foram copiados por outros shells Unix. Mas, em contraste com sh , que gerou um grande número de clones desenvolvidos de forma independente, incluindo ksh e bash , apenas dois clones csh são conhecidos. (Como o tcsh foi baseado no código csh originalmente escrito por Bill Joy, ele não é considerado um clone.)

Em 1986, Allen Holub escreveu On Command: Writing a Unix-Like Shell para MS-DOS , um livro que descreve um programa que ele escreveu chamado "SH", mas que na verdade copiava o design da linguagem e os recursos do csh, não do sh. Disquetes complementares contendo código-fonte completo para SH e para um conjunto básico de utilitários do tipo Unix (cat, cp, grep, etc.) estavam disponíveis por $ 25 e $ 30, respectivamente, do editor. As estruturas de controle, gramática de expressão, mecanismo de história e outros recursos no SH de Holub eram idênticos aos do C shell.

Em 1988, os Laboratórios Hamilton começaram a enviar o shell Hamilton C para OS / 2 . Ele incluía um clone csh e um conjunto de utilitários do tipo Unix. Em 1992, o shell Hamilton C foi lançado para Windows NT . A versão do Windows continua a ter suporte ativo, mas a versão OS / 2 foi descontinuada em 2003. Uma referência rápida do início de 1990 descreveu a intenção como "total conformidade com toda a linguagem C shell (exceto controle de tarefas )", mas com melhorias no design da linguagem e adaptação às diferenças entre Unix e um PC. A melhoria mais importante foi um analisador de cima para baixo que permitiu que estruturas de controle fossem aninhadas ou canalizadas, algo que o shell C original não podia suportar, devido ao seu analisador ad hoc. Hamilton também adicionou novos recursos de linguagem, incluindo procedimentos internos e definidos pelo usuário, variáveis ​​locais estruturadas em blocos e aritmética de ponto flutuante. A adaptação para um PC incluiu suporte para o nome de arquivo e outras convenções em um PC e o uso de threads em vez de garfos (que não estavam disponíveis no OS / 2 ou no Windows) para atingir o paralelismo , por exemplo, na configuração de um pipeline.

Veja também

Referências

Leitura adicional

links externos