10 pontos por GN⁺ 2024-01-22 | 1 comentários | Compartilhar no WhatsApp
  • Fica mais fácil chamar o shell a partir de Javascript/Typescript
  • Multiplataforma, podendo ser usado em Linux/Windows/macOS
    • Implementa internamente comandos e recursos comuns: globbing, variáveis de ambiente, redirection, piping
  • Embora JavaScript seja a linguagem de script mais popular do mundo, executar shell scripts ainda é algo difícil.
  • É possível fazer tarefas parecidas usando a função spawnSync do módulo child_process ou a função readdir de fs/promises, mas isso não é tão simples quanto os shell scripts tradicionais.

Problemas de compatibilidade entre shells tradicionais e JavaScript

  • Shells como bash e sh são usados há décadas, mas não funcionam bem em JavaScript.
  • O zsh do macOS, o bash do Linux e o cmd do Windows têm sintaxes e comandos diferentes, causando problemas de compatibilidade.
  • O npm vinha usando uma abordagem em que a comunidade preenchia os comandos ausentes com implementações em JavaScript.

Comandos que não funcionam no Windows

  • O comando rm -rf não funciona no Windows, por isso a implementação JavaScript multiplataforma chamada rimraf é baixada 60 milhões de vezes por semana.
  • A definição de variáveis de ambiente difere entre plataformas, e no Windows é preciso usar cross-env.
  • O comando which no Windows é usado como where, e um pacote para isso também é baixado 60 milhões de vezes por semana.

O problema do tempo de inicialização do shell

  • O tempo necessário para iniciar um shell é de cerca de 7 ms em uma máquina Linux x64 Hetzner com Arch Linux.
  • Ao executar um único comando, o tempo para iniciar o shell pode ser maior que o tempo para executar o próprio comando.
  • Executar muitos comandos em um loop pode sair caro.

A necessidade de polyfills

  • De 2009 a 2016, quando JavaScript ainda era relativamente novo e experimental, fazia sentido a comunidade criar polyfills para os recursos ausentes.
  • Mas, em 2024, o JavaScript no servidor já está maduro e amplamente adotado, e o ecossistema JavaScript entende melhor as necessidades atuais do que antes.

Apresentando o Bun Shell

  • Bun Shell é uma nova linguagem e interpretador experimental embutido no Bun, que permite executar shell scripts multiplataforma em JavaScript e TypeScript.
  • Com o Bun Shell, é possível usar variáveis JavaScript em shell scripts, e todas as variáveis de template são escapadas para reforçar a segurança.
  • Bun Shell tem uma sensação parecida com JavaScript comum, e permite redirecionar o stdout para um buffer ou arquivo, ou fazer pipe para outros comandos.
  • É possível usar comandos embutidos como cd, echo e rm, e tudo funciona em Windows, macOS e Linux.
  • Bun Shell foi projetado para substituir shell scripts simples e, ao usar Bun no Windows, aciona o bun run a partir de package.json em "scripts".
  • Também pode ser usado como um interpretador independente de shell scripts.

Como instalar

  • Bun Shell já vem embutido no Bun, então basta ter o Bun v1.0.24 ou superior instalado para começar a usar.
  • Se o Bun não estiver instalado, é possível instalá-lo com curl ou npm.

Opinião do GN⁺

  • Bun Shell apresenta uma abordagem inovadora para resolver os problemas de compatibilidade entre shell scripts tradicionais e JavaScript.
  • O suporte multiplataforma e a facilidade de uso permitem que desenvolvedores tenham uma experiência de scripting consistente em diferentes ambientes.
  • Ferramentas como essa refletem a maturidade do ecossistema JavaScript e devem contribuir para aumentar a produtividade dos desenvolvedores em um ambiente tecnológico em rápida mudança.

1 comentários

 
GN⁺ 2024-01-22
Comentários no Hacker News
  • We've implemented many common commands and features like globbing, environment variables, redirection, piping, and more.

    • Essa nova implementação de shell inclui comandos e recursos comuns, como globbing, variáveis de ambiente, redirecionamento, piping etc.
    • Ainda assim, falta confiança quanto à compatibilidade com shells existentes e com implementações do coreutils.
    • Não está claro se o objetivo é compatibilidade com o padrão POSIX ou com o shell Bourne, nem se há suporte a extensões do GNU.
    • Faltam detalhes sobre o que acontece quando o sistema já tem GNU coreutils e se futuras adições de comandos embutidos podem causar mudanças inesperadas.
    • Aponta-se que substituir um shell compatível com Bourne, como o ZShell, por esse shell não é desejável na maioria das situações.
    • No ecossistema JS, já é necessário escrever comandos compatíveis com vários shells, então padronizar um subconjunto útil de shells compatíveis com Bourne poderia fazê-los funcionar como pretendido em todas as plataformas, mantendo quase 100% de compatibilidade com o que já funciona na maioria delas.
  • Love that bun just implements anything that could be useful.

    • Avalia positivamente o fato de o Bun simplesmente implementar tudo que possa ser útil.
  • This looks exactly like zx by Google. And that's probably a good thing.

    • Essa implementação de shell parece muito com o zx do Google. E isso provavelmente é uma coisa boa.
  • $ hyperfine --warmup 3 'bash -c "echo hello"' 'sh -c "echo hello"' -N

    • Aponta que, no Arch Linux, /bin/sh é um link simbólico para o bash, então na prática estão medindo a mesma coisa.
    • Em sistemas como o Debian, /bin/sh é o dash, que é várias vezes mais rápido que o bash tanto na inicialização quanto no desempenho geral.
  • I work on Bun - happy to answer any questions/feedback

    • Como desenvolvedor do Bun, diz estar à disposição para responder perguntas ou receber feedback.
  • This is neat, but a) it strikes me that what's powerful about shell scripting is that it lets you easily wrangle multiple independent utilities that don't need to be contained within the shell stdlib (maybe I'm missing something but I didn't see any emphasis on that), and b) that embedding a language as a string inside another language is very rarely a good UX.

    • O ponto forte do shell scripting é permitir orquestrar facilmente várias utilidades independentes, sem que elas precisem estar contidas na stdlib do shell, e isso não parece receber destaque aqui.
    • Também aponta que embutir uma linguagem como string dentro de outra quase nunca oferece uma boa experiência de uso.
    • Ainda assim, a portabilidade desse shell de fato resolve um problema importante.
  • For something which works across all JS runtimes (Deno, Node) and achieves basically the same, check out the popular JS library Execa[1]. Works like a charm!

    • Recomenda a biblioteca JS Execa[1], que funciona em todos os runtimes JS (Deno, Node) e oferece basicamente a mesma proposta.
  • Another alternative is the ZX shell[2] JS library. Tho haven't tested it.

    • A biblioteca JS ZX shell[2] também pode ser uma alternativa, embora ele não a tenha testado.
  • I love Bun. I no longer use Node for development. Hardly any gotchas anymore. It's just faster all over. Especially bun test. Highly recommended. Thank you @Jarred!

    • Diz gostar muito do Bun e que não usa mais Node para desenvolvimento.
    • Afirma que quase não há mais pegadinhas e que ele é mais rápido em tudo, especialmente bun test.
    • Recomenda fortemente e agradece ao @Jarred.
  • I didn't know, but apparently you can execute a function in JS without parentheses using upticks (`), e.g:

    • Descobriu que em JS é possível executar uma função sem parênteses usando crases (`), por exemplo.
    • Observa que o Bun também usa a função com cifrão ($) para executar comandos de shell, o que seria uma das esquisitices sintáticas do JS.
  • Great, it's approaching the ergonomics of what Perl has offered for decades. And Perl still does it better.

    • Avalia que esse shell está se aproximando da ergonomia que o Perl oferece há décadas, embora o Perl ainda faça isso melhor.