AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 780429
Accepted
Viscountess of the Junkyard
Viscountess of the Junkyard
Asked: 2024-07-19 17:18:19 +0800 CST2024-07-19 17:18:19 +0800 CST 2024-07-19 17:18:19 +0800 CST

Existe um equivalente a caniuse para comandos em sistemas posix?

  • 772

Estou pensando em usar uma chamada para jqum script de utilitário que estou escrevendo, em vez de analisar o JSON manualmente.

Para tornar o script o mais portátil possível, quero saber quais versões de Unix/Linux/MacOS/WSL/etc suportam este comando sem qualquer instalação de pacote adicional.

Da mesma forma, no passado, descobri que alguns scripts usam chamadas para wget, que estão faltando em pelo menos um tipo por padrão.

Isso me fez pensar: existe algum tipo de ferramenta que diga às pessoas se é "seguro" usar um comando arbitrário em seus scripts dessa maneira? Idealmente, ele agiria como o site caniuse, mostrando quais sabores principais suportam ou não um comando em seus shells padrão.

===

EDIT: Agradecendo ao usuário Kusalananda por apontar que meus exemplos não são comandos POSIX, mudei o título para evitar rotulá-los incorretamente como tal.

shell
  • 3 3 respostas
  • 646 Views

3 respostas

  • Voted
  1. Best Answer
    Stephen Kitt
    2024-07-19T17:39:02+08:002024-07-19T17:39:02+08:00

    Existem algumas ferramentas ou sites que podem ser usados ​​para descobrir qual versão de um projeto está disponível em diversas distribuições (incluindo sistemas não-Linux); consulte Existe uma ferramenta/site para comparar o status do pacote em diferentes distribuições Linux?

    É muito mais difícil afirmar categoricamente quais sistemas possuem um determinado pacote por padrão. Em alguns casos não existe um padrão realmente confiável; por exemplo, a maioria dos sistemas Debian terá wgetquando configurado inicialmente (porque é “padrão” lá), mas as imagens de contêiner Debian não o incluem por padrão e não há nada que o obrigue wget a ser instalado em um sistema Debian.

    Também não há necessidade de os usuários usarem o pacote do sistema (se houver) para fornecer um determinado binário. Eles também podem ter uma versão em pacote e uma versão instalada manualmente disponíveis, e olhar apenas para o pacote pode dar uma falsa impressão ( por exemplo , se você precisar de pelo menos uma versão específica e o pacote instalado for mais antigo, mas o usuário tiver um versão apropriada em seu caminho).

    Tudo isso significa que você não pode fazer nada melhor do que verificar a existência de um comando e falhar se não conseguir encontrar todos os comandos necessários, com links para instruções explicando como instalá-los.

    • 9
  2. Ángel
    2024-07-20T09:25:59+08:002024-07-20T09:25:59+08:00

    Quase nenhum comando estará presente por padrão em todas as versões sem instalação de pacote.

    Você pode considerar a seção de utilitários obrigatórios do padrão POSIX , mas embora muitos deles estejam presentes em todos os sistemas (grep, basename, cut, grep, cmp...) outros não são comuns ou precisam de pacotes separados (compress, pax, aqueles que lidam com arquivos SCSS...).

    Não há culpa em usar programas adicionais e exigir que eles estejam disponíveis.

    Um script genérico necessário jqpoderia começar com:

    if ! command -v jq 2> /dev/null; then
      echo "You need to install jq to use this program"
      exit 69  # EX_UNAVAILABLE
    fi
    

    Uma regra que às vezes uso ao escrever scripts gerais (ou seja, não aqueles onde eu já conheço o sistema e posso assumir que certos programas estão instalados) é considerar que aqueles pacotes que são considerados essenciais pelo Debian/Ubuntu estarão lá, e o resto pode não.

    Os essenciais são um conjunto de pacotes que "devem estar disponíveis e utilizáveis ​​no sistema em todos os momentos" ( veja o Manual de Políticas Debian sobre Pacotes Essenciais ).

    Os pacotes Debian podem usar programas essenciais sem declará-los. Em todos os outros casos, eles teriam que declarar a dependência. Como tal, se o programa estivesse sendo empacotado em um .deb, os utilitários não essenciais, como jqou wgetque você testa, são os mesmos que teriam que ser declarados no pacote, enquanto você poderia pular aqueles em, por exemplo, coreutils.

    Esta lista obviamente não é universal, e pode haver diferenças entre várias distros da família Debian (bem como versões mais recentes, incluindo programas que não eram essenciais em versões anteriores), mas acho que é boa o suficiente. Se estiver em um pacote essencial e em POSIX, provavelmente é seguro usá-lo diretamente. Se não for um pacote essencial, você sabe que pelo menos não estará disponível lá, então verifique.

    Algumas advertências:

    • Existem muitas distribuições Linux. Alguns são muito finos e não fornecem quase nada
    • WSL usa Ubuntu por padrão , mas pode estar usando uma distribuição diferente
    • O MacOS usa principalmente binários de usuário do FreeBSD. Muitas vezes desatualizado.

    Mais irritantes do que programas ausentes são aqueles com comportamento diferente/recursos ausentes que você pode querer usar.

    Por exemplo:

    • O Mac OS vem com o bash 3.2.57 (2007), para ter um bash moderno (e seus recursos) ele precisaria ser atualizado com o homebrew (use BASH_VERSIONse precisar verificar a versão do bash que está executando o seu script)
    • O sedcomando tem semântica ligeiramente diferente em seu -iparâmetro no Mac OS (que usa sed do FreeBSD) e na maioria dos Linux (usando GNU sed)
    • Às vezes, o que wgetvocê encontra é na verdade um miniaplicativo busybox (que não possui muitos recursos do wget GNU "normal")
    • Os recursos podem ter sido adicionados em uma versão recente e não na versão do programa distribuída por certas distros mais antigas.
    • Da mesma forma, você pode esperar que os recursos descritos como "extensões GNU" não estejam disponíveis no sistema operacional que não usa a versão GNU desse utilitário.

    Ter dependências não é ruim (provavelmente é até a escolha certa) e você não precisa oferecer suporte a todos os sistemas . Especialmente quando você não tem um sistema de teste para testá-lo. Você precisará traçar uma linha em algum lugar, muitas vezes haverá uma ou algumas configurações que você suporta, que são aquelas que você usa e pode testar, e um melhor esforço e uma expectativa geral para apoiar outras.

    • 2
  3. Austin Hemmelgarn
    2024-07-20T20:49:23+08:002024-07-20T20:49:23+08:00

    Não existe tal recurso atualmente. Eu realmente gostaria que houvesse, porque tornaria meu trabalho muito mais simples. A disponibilidade do pacote é resolvida (consulte https://repology.org/ para obter o melhor recurso atualmente para isso), mas não o que é instalado por padrão. Para muitas distribuições Linux isso não é excepcionalmente difícil de verificar mesmo sem instalar, apenas dá trabalho perseguir a árvore de dependências completa (por exemplo, para Arch Linux, veja as dependências do pacote base , embora você precise seguir as dependências para cada coisa depende). O que fica complicado é que a 'base' para uma determinada distribuição geralmente varia de acordo com o destino da instalação (muitas distros deixam uma série de coisas de fora nas imagens do Docker, por exemplo) e possivelmente a escolha do ambiente do usuário (obviamente você obtém um diferente conjunto de dependências folha se você optar por instalar uma GUI).

    Falando como alguém que escreve muitos scripts de shell para o trabalho, há algumas coisas que você pode fazer para ajudar a mitigar esses tipos de problemas:

    • Use command -vpara procurar comandos. Isso funciona praticamente em todos os lugares em que você se preocupa em oferecer suporte, pode ser trivialmente transformado em uma ifcondição (por exemplo: command -v jq >/dev/null 2>&1) ou usado para atribuir uma variável (por exemplo: `JQ_PATH="$(command -v jq 2>/ dev/null || true)") e evita a possibilidade de tentar invocar aliases definidos pelo usuário (o que quase nunca é o que você deseja fazer em um script portátil).
    • Python, embora não seja universal por si só (Alpine Linux e FreeBSD são exemplos triviais de sistemas que não vêm com Python por padrão), muitas vezes pode ser usado para contornar comandos 'ausentes'. Quase tudo que você pode fazer jqtambém pode ser feito com jsono módulo do Python e o print(). A interação HTTP/HTTPS básica pode ser feita facilmente com o Python urllib. readlinkpode ser emulado de maneira bastante trivial usando Python. E há muitos outros. A única ressalva é garantir que você lide com as diferenças de versão no próprio Python de maneira sensata, mas dependendo das plataformas de destino e do que exatamente você precisa fazer, isso pode não ser um problema. Observe que esta não é uma sugestão para escrever seus scripts em Python, mas para permitir a python -cexecução de pequenos trechos de código em vez de chamar programas equivalentes.
    • Do ponto de vista organizacional, quando mais de um comando puder ser usado com base no sistema ou em outros fatores, coloque a lógica para isso em uma função e chame a função em vez de colocá-la em linha no seu código. Isso fará maravilhas para ajudar a preservar sua sanidade e também garantirá que, se você precisar usar um comando mais de uma vez, será fácil fazê-lo.
    • Faça um esforço para decidir sobre uma política para quais plataformas você realmente oferece suporte. Isso pode ser tão simples como 'se for EOL upstream, não vou apoiá-lo'. Em seguida, reúna ambientes de teste para as principais plataformas que se enquadram na sua política de suporte (para Linux, testes em Alpine, Arch, Debian, Fedora, openSUSE, RHEL (ou CentOS Stream) e Ubuntu proporcionarão cobertura majoritária de usuários reais e cobertura indireta da maioria dos usuários que não usam essas distros (porque quase tudo, exceto NixOS e Gentoo, que tem uma participação decente no mercado, é baseado em uma dessas sete distros)).
    • Contanto que você não se importe com plataformas comerciais UNIX como AIX e Solaris, cerca de 95% das diferenças que você vê no comportamento de comandos comuns serão divididas em algum subconjunto de GNU, BSD, POSIX, Busybox e macOS. O Busybox geralmente será o filho problemático porque faltam muitas coisas que estão disponíveis em todos os outros quatro 'sabores' e tem uma semântica irritantemente diferente em vários casos. É cada vez mais importante suportá-lo por causa do Alpine Linux usá-lo por padrão (mas você não deve presumir que se estiver executando no Alpine que está usando o Busybox, a instalação da versão 'normal' de um comando substituirá a do Busybox lá) .
    • Especificamente para Linux, pode ser necessário diferenciar distros para descobrir caminhos para coisas específicas. A maneira canônica de fazer isso é consultar o arquivo os-release , que pode ser obtido diretamente em qualquer derivado do shell Bourne (incluindo bash e POSIX sh). Algumas plataformas não-Linux também estão começando a enviar arquivos com os mesmos campos personalizados para sua plataforma, portanto, também podem ser usados ​​em outros lugares (embora fora do Linux, unamegeralmente seja bom o suficiente).
    • 0

relate perguntas

  • Como funciona este comando? mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve