Introdução

Bash é uma linguagem de comando que normalmente vem como um programa interpretador de linha de comando onde os usuários podem executar comandos de seu software de terminal. Por exemplo, podemos usar o terminal do Ubuntu para executar comandos Bash. Também podemos criar e executar arquivos de script Bash por meio do que é conhecido como script de shell.

Os programadores usam scripts de shell em muitos cenários de automação, como para processos de construção e CI/CD ou atividades relacionadas à manutenção de computador. Como uma linguagem de comando com recursos completos, o Bash oferece suporte a pipelines, variáveis, funções, instruções de controle e operações aritméticas básicas.

No entanto, o Bash não é uma linguagem de programação de uso geral amigável ao desenvolvedor. Ele não suporta OOP, estruturas como JSON, estruturas de dados comuns que não sejam arrays e string embutido ou métodos de manipulação de array. Isso significa que os programadores geralmente precisam chamar scripts Python ou Node separados do Bash para esses requisitos.

É aqui que chega o projeto zx . zx introduziu uma maneira de escrever scripts do tipo Bash usando JavaScript.

JavaScript, em comparação, tem quase todos os recursos embutidos de que os desenvolvedores precisam. O zx permite que os programadores escrevam scripts de shell com JavaScript, fornecendo APIs de invólucro para vários pacotes Node.js relacionados à CLI. Portanto, você pode usar zx para escrever scripts de shell do tipo Bash amigáveis ​​para o desenvolvedor.

Neste artigo, explicarei o zx e ensinarei como usá-lo em seus projetos.

Comparando Bash e zx

Bash é uma linguagem de comando interpretada de passagem única desenvolvida inicialmente por Brian Fox. Os programadores costumam usá-lo com a ajuda de Unix ou comandos do tipo Unix.

Na maioria das vezes, o Bash inicia processos separados para realizar diferentes subtarefas. Por exemplo, se você usar o comando expr para operações aritméticas, o interpretador Bash sempre gerará outro processo.

A razão é que expr é um programa de linha de comando que precisa de um processo separado para ser executado. Seus scripts de shell podem parecer complexos quando você adiciona mais lógica aos arquivos de script. Seus scripts de shell também podem ter um desempenho lento devido à geração de processos e interpretações adicionais.

O projeto zx implementa um executor de script de shell semelhante ao Bash, mas usando módulos JavaScript. Ele fornece uma API JavaScript assíncrona embutida para chamar outros comandos semelhantes ao Bash. Além disso, ele fornece funções de wrapper para vários auxiliares de linha de comando baseados em Node.js, como giz , minimista , fs-extra , OS e Readline .

Como funciona o zx?

Todo zx O arquivo de script de shell tem.mjs como extensão. Todas as funções integradas e wrappers para APIs de terceiros são pré-importados. Portanto, você não precisa usar instruções de importação adicionais em seus scripts de shell baseados em JavaScript.

O zx aceita scripts de entrada padrão, arquivos e como um URL. Ele importa seus comandos zx definidos como um módulo ECMAScript (MJS) para executar, e o processo de execução do comando usa Node.js API de processo filho .

Agora, vamos escrever alguns scripts de shell usando zx para entender melhor o projeto.

tutorial de script zx

Primeiro, você precisa instalar o pacote zx npm globalmente antes de começar a escrever scripts zx. Certifique-se de que já instalou o Node.js v14.8.0 ou superior.

Execute o seguinte comando no seu terminal para instalar o programa de linha de comando zx.

npm install-g zx

Digite zx em seu terminal para verificar se o programa foi instalado com sucesso. Você obterá uma saída como a abaixo.

O básico do zx

Vamos criar um script simples para obter o branch atual de um projeto Git.

Crie get_current_branch.mjs dentro de um de seus projetos e adicione o seguinte código.

#!/usr/bin/env zx const branch=await $ `git branch–show-current` console.log (` Branch atual: $ {branch} `)

A primeira linha é a linha shebang que diz ao executor do script do sistema operacional para escolher o interpretador correto. O $ é uma função que executa um determinado comando e retorna sua saída quando é usado com a palavra-chave await. Por fim, usamos console.log para exibir o branch atual.

Execute seu script com o seguinte comando para obter o branch Git atual do seu projeto.

zx./get_current_branch.mjs

Ele também mostrará todos os comandos que você executou porque zx ativa seu modo detalhado por padrão. Atualize seu script conforme abaixo para se livrar dos detalhes adicionais do comando.

#!/Usr/bin/env zx $.verbose=false const branch=await $ `git branch–show-current` console.log ( `Branch atual: $ {branch}`)

Você também pode executar o script sem o comando zx, graças à linha shebang superior.

chmod + x./get_current_branch.mjs./get_current_branch.mjs

Colorir e formatar

zx também expõe a API da biblioteca de giz. Portanto, podemos usá-lo para colorir e formatar, conforme mostrado abaixo.

#!/Usr/bin/env zx $.verbose=false let branch=await $ `git branch–show-current` console.log (`Branch atual: $ {giz.bgYellow.red.bold (branch)}`)

Mais métodos de coloração e formatação estão disponíveis em documentação oficial do giz .

Entradas do usuário e argumentos da linha de comando

O zx fornece a função de pergunta para capturar entradas do usuário a partir da interface da linha de comando. Você também pode habilitar o preenchimento de tabulação Unix tradicional com a opção de escolhas.

O script a seguir captura um nome de arquivo e um modelo do usuário. Depois disso, ele faz o scaffold de um arquivo usando a configuração inserida pelo usuário. Você pode usar o preenchimento de tabulação com a segunda pergunta.

#!/Usr/bin/env zx $.verbose=false let filename=await question (‘Qual é o nome do arquivo?’) Let template=await question (‘Qual é o seu modelo preferido?’, {Choices: [“function”,”class”]//Ativa o preenchimento da guia.}) Let content=””if (template==”function”) {content=`function main () {console.log (“Teste”); } `; } else if (template==”class”) {content=`class Main {constructor () {console.log (“Test”); }} `; } else {console.error (`Modelo inválido: $ {template}`) process.exit (); } fs.outputFileSync (filename, content)

Um objeto de argumentos de linha de comando analisados ​​está disponível como a constante argv global. A análise é feita usando o módulo Node.js minimista.

Dê uma olhada no exemplo a seguir que captura dois valores de argumento da linha de comando.

#!/Usr/bin/env zx $. verbose=false const size=argv.size; const isFullScreen=argv.fullscreen; console.log (`size=$ {size}`); console.log (`fullscreen=$ {isFullScreen}`);

Execute o arquivo de script acima conforme mostrado abaixo para verificar o suporte do argumento da linha de comando.

./yourscript.mjs–size=100×50–fullscreen

Solicitações de rede

Programadores frequentemente use o comando curl para fazer solicitações HTTP com scripts Bash. zx oferece um wrapper para o módulo node-fetch e expõe a API do módulo específico como buscar. A vantagem é que zx não gera vários processos para cada solicitação de rede como o Bash faz com curl-porque o pacote node-fetch usa APIs HTTP padrão do Node para enviar solicitações de rede.

Vamos fazer uma solicitação HTTP simples para se familiarizar com a API de solicitações de rede do zx.

#!/usr/bin/env zx $.verbose=false let response=await fetch (‘https://cheat.sh’); if (response.ok) {console.log (await response.text ()); }

O script zx acima irá baixar e mostrar o conteúdo do URL específico com a ajuda do módulo node-fetch. Ele não gera um processo separado, como as chamadas de rede de Bash.

Construindo pipelines de comando

No script de shell, pipelines se referem a vários comandos executados sequencialmente. Freqüentemente, usamos o conhecido caractere de barra vertical (|) dentro de nossos scripts de shell para passar a saída de um processo para outro. zx oferece duas abordagens diferentes para construir pipelines.

Podemos usar o | caractere com os comandos definidos de forma semelhante ao script Bash-ou podemos usar o método de cadeia.pipe () da API integrada do zx. Verifique como os pipelines são implementados de ambas as maneiras no script de exemplo a seguir.

#!/Usr/bin/env zx $.verbose=false//Um ​​pipeline usando | deixe saudação=aguarde $ `echo”Olá, mundo”| tr'[l]'[L] `console.log (` $ {greeting} `)//O mesmo pipeline, mas com o método.pipe () greeting=await $` echo”Hello World”`.pipe ($` tr'[l]'[L] `) console.log (` $ {greeting} `)

Casos de uso avançado

Além do suporte a script de shell baseado em JavaScript, zx oferece suporte a vários outros recursos úteis.

Por padrão, zx usa um interpretador Bash para executar comandos. Podemos mudar o shell padrão modificando a variável de configuração $.shell. O script a seguir usa o shell sh em vez de bash.

$.shell=’/usr/bin/sh’$.prefix=’set-e;’$ `echo”Seu shell é $ 0″`//Seu shell é/usr/bin/sh

Você pode usar o programa de linha de comando zx para executar trechos de código de um arquivo Markdown específico escrito em JavaScript. Se você fornecer um arquivo Markdown, o programa de linha de comando zx analisará e executará blocos de código.

Vejamos um exemplo. Baixe este arquivo Markdown de exemplo do zx GitHub e salve-o como markdown.md. Depois disso, execute o seguinte comando para executar blocos de código.

zx markdown.md

O programa de linha de comando zx também pode executar scripts a partir de um URL. Forneça um link para seu script zx da mesma forma que você forneceria um nome de arquivo. O seguinte script remoto exibirá uma mensagem de saudação.

zx https://raw.githubusercontent.com/shalithasuranga/zx-scripting-examples/main/greeting.mjs

Você pode importar a função $ do seu nó com base em aplicativos da web também. Então, é possível executar comandos do back-end do seu aplicativo da web.

Importe a função $ do zx conforme mostrado abaixo para chamar os comandos do sistema operacional de outros arquivos de origem JavaScript.

import {$} from’zx’await $ `whoami`

Usando zx com TypeScript

zx também tem definições de TypeScript, embora o suporte completo ainda esteja por vir. Portanto, os programadores podem usar todas as APIs embutidas do zx com TypeScript. Podemos fornecer arquivos TypeScript diretamente como arquivos zx para o programa de linha de comando zx. Em seguida, o zx irá transpilar e executar os arquivos de origem do TypeScript fornecidos.

Além disso, é possível usar o zx em seus aplicativos da web baseados no TypeScript para executar os comandos do sistema operacional.

Conclusão

O script Bash é uma ótima maneira de automatizar seus processos de desenvolvimento. Mas, quando o script Bash se torna complexo, às vezes você precisa escrever scripts separados com outras linguagens de programação.

O projeto zx fornece uma maneira fácil de escrever scripts do tipo Bash com JavaScript e TypeScript . Ele oferece APIs mínimas semelhantes ao Bash para dar uma sensação de script de shell ao que estamos fazendo-mesmo se estivermos escrevendo um arquivo-fonte em JavaScript.

Além disso, zx motiva os desenvolvedores a escrever scripts de shell baseados em JavaScript sem ponto-e-vírgula para tornar os scripts zx e Bash sintaticamente semelhantes.

No entanto, zx não é um substituto do Bash-ele usa um interpretador de linha de comando (Bash por padrão) internamente para executar comandos de qualquer maneira.