Estou trabalhando em um sistema Ubuntu e atualmente é o que estou fazendo:
if ! which command > /dev/null; then
echo -e "Command not found! Install? (y/n) \c"
read
if "$REPLY" = "y"; then
sudo apt-get install command
fi
fi
É isso que a maioria das pessoas faria? Ou existe uma solução mais elegante?
command -v <command>
; nãowhich <command>
. Consulte também Verifique se existe um programa a partir de um script Bash .Respostas:
Para verificar se
packagename
foi instalado, digite:Você também pode usar um
dpkg-query
que tenha uma saída mais limpa para o seu propósito e aceite curingas também.Para descobrir qual pacote é o proprietário
command
, tente:Para obter mais detalhes, consulte o artigo Descubra se o pacote está instalado no Linux e no dpkg cheat sheet .
fonte
if
uso. Eu também estou procurando oif
uso.dpkg -s
retorna 1 nos pacotes ausentes e 0 caso contrário, como deveria. Como foi diferente nas versões anteriores (ou recentes)?dpkg -s
retorna zero se um pacote foi instalado e removido - nesse caso, éStatus: deinstall ok config-files
semelhante ou similar, então está "ok" - então, para mim, esse não é um teste seguro.dpkg-query -l
também não parece retornar um resultado útil neste caso.Para ser um pouco mais explícito, aqui está um script bash que verifica se há um pacote e o instala, se necessário. Obviamente, você pode fazer outras coisas ao descobrir que o pacote está ausente, como simplesmente sair com um código de erro.
Se o script for executado em uma GUI (por exemplo, é um script do Nautilus), você provavelmente desejará substituir a chamada 'sudo' por uma chamada 'gksudo'.
fonte
--force-yes
parece uma péssima ideia. Da página de manual: "Esta é uma opção perigosa que fará com que o apt-get continue sem avisar se estiver fazendo algo potencialmente prejudicial. Ele não deve ser usado, exceto em situações muito especiais. O uso de --force-yes pode potencialmente destruir seu sistema ! " Usá-lo em um script torna ainda pior.Este one-liner retorna 1 (instalado) ou 0 (não instalado) para o pacote 'nano'.
mesmo que o pacote não exista / não esteja disponível.
O exemplo abaixo instala o pacote 'nano' se não estiver instalado.
fonte
dpkg-query -W -f='${Status}' MYPACKAGE | grep -q -P '^install ok installed$'; echo $?
grep -P
de um regex simples como esse.if ! dpkg-query -W -f='${Status}' nano | grep "ok installed"; then apt install nano; fi
- Não há necessidade de usargrep -c
, basta usar o status de saída degrep
dpkg -s
uso programático com instalação automáticaGosto
dpkg -s
que ele saia com status1
se algum dos pacotes não estiver instalado, facilitando a automação:man dpkg
infelizmente não documenta o status de saída, mas acho que deve ser razoavelmente seguro confiar nele:Uma coisa a notar é que executando:
não remove necessariamente todos os arquivos imediatamente para alguns pacotes (mas remove outros, não sabe por quê?) e apenas marca o pacote para remoção.
Nesse estado, o pacote parece ainda ser utilizável e como seus arquivos ainda estão presentes, mas é marcado para remoção posteriormente.
Por exemplo, se você executar:
então:
as duas primeiras
echo $?
saídas0
, apenas a terceira produz1
a saída para o primeiro
dpkg -s certbot
contém:enquanto o segundo diz:
e só desaparece após a limpeza:
o arquivo
/etc/logrotate.d/certbot
ainda está presente no sistema depoisapt remove
, mas não depois--purge
.No entanto, o arquivo
/usr/lib/python3/dist-packages/certbot/reporter.py
ainda está presente mesmo depois--purge
.Eu não entendo o porquê, mas com o
hello
pacote o segundodpkg
depoisapt remove
mostra que ele já foi removido sem--purge
:As documentações também não são claras, por exemplo:
não removeu
certbot
quando foi marcado comodeinstall
, emboraman apt-get
pareça indicar que:Veja também:
Testado no Ubuntu 19.10.
apt
Pacote PythonExiste um pacote Python 3 pré-instalado chamado
apt
Ubuntu 18.04 que expõe uma interface apt do Python!Um script que verifica se um pacote está instalado e o instala se não puder pode ser visto em: Como instalar um pacote usando a API python-apt
Aqui está uma cópia para referência:
Verifique se um executável está no
PATH
lugarConsulte: Como posso verificar se existe um programa a partir de um script Bash?
fonte
sudo apt install hello; dpkg -s hello; echo $?; sudo apt remove hello; dpkg -s hello; echo $?
. Você pode fornecer mais detalhes?Eu ofereço esta atualização, pois o Ubuntu adicionou seu "Personal Package Archive" (PPA) exatamente quando esta pergunta foi respondida, e os pacotes PPA têm um resultado diferente.
Pacote de repositório Debian nativo não instalado:
Pacote PPA registrado no host e instalado:
Pacote PPA registrado no host, mas não instalado:
Também publicado em: /superuser/427318/test-if-a-package-is-installed-in-apt/427898
fonte
UpAndAdam escreveu:
Na minha experiência, você pode confiar nos códigos de saída do dkpg.
O código de retorno do dpkg -s é 0 se o pacote estiver instalado e 1 se não estiver, então a solução mais simples que encontrei foi:
Funciona bem para mim ...
fonte
apt-get remove <package>
,dpkg -s <package>
ainda retorna 0, mesmo que o pacote édeinstalled
Isso parece funcionar muito bem.
0
se não estiver instalado ou algum número,> 0
se instalado.fonte
grep | wc -l
é um antipadrão. Para verificar se existe algo, você quer simplesmentegrep -q
. Para contar as ocorrências (o que raramente é útil nesse tipo de cenário), usegrep -c
.dpkg -s zip | grep -c "Package: zip"
,? (usando zip como pacote de amostra)grep -q 'Package: zip'
retornar um código de saída que indica se o resultado foi ou não encontrado sem imprimir nada.Eu decidi um baseado na resposta de Nultyi :
Basicamente, a mensagem de erro de
dpkg --get-selections
é muito mais fácil de analisar do que a maioria das outras, porque não inclui status como "deinstall". Ele também pode verificar vários pacotes simultaneamente, algo que você não pode fazer apenas com códigos de erro.Explicação / exemplo:
Portanto, o grep remove os pacotes instalados da lista e o awk retira os nomes dos pacotes da mensagem de erro, resultando em
MISSING='python3-venv python3-dev jq'
, que pode ser trivialmente inserido em um comando de instalação.Não estou emitindo cegamente
apt-get install $PACKAGES
porque, como mencionado nos comentários, isso pode atualizar inesperadamente pacotes que você não estava planejando; não é realmente uma boa ideia para processos automatizados que se espera sejam estáveis.fonte
[[ ! -z $MISSING ]] && sudo apt-get install $MISSING
Eu descobri que todas as soluções acima podem produzir um falso positivo se um pacote estiver instalado e, em seguida, removido, mas o pacote de instalação permanece no sistema.
Para replicar: Instalar pacote
apt-get install curl
Remover pacote
apt-get remove curl
Agora teste as respostas acima.
O comando a seguir parece resolver essa condição:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'
Isso resultará em uma instalação definitiva ou não instalada
fonte
config-files
-, então acho que uma final| grep -q "installed"
é realmente necessária para obter um status de código de saída funcional.| grep -q '^installed$'
Parece que hoje em dia
apt-get
há uma opção--no-upgrade
que apenas faz o que o OP deseja:Página de manual de https://linux.die.net/man/8/apt-get
Portanto, você pode usar
e
package
será instalado apenas se não estiver.fonte
fonte
command -v <command>
; nãowhich <command>
. Consulte também Verifique se existe um programa a partir de um script Bash .Isso fará isso.
apt-get install
é idempotente.fonte
apt-get install
um pacote é indesejável onde o pacote já está instalado, mesmo que o próprio comando seja idempotente. No meu caso, estou instalando um pacote em um sistema remoto com o módulo bruto do Ansible, que relatará o sistema como sempre alterado se eu executarapt-get install
indiscriminadamente. Um condicional resolve esse problema.Usar:
Se não estiver instalado, mostrará:
Caso contrário, ele mostrará:
fonte
Esse recurso já existe no Ubuntu e Debian, no
command-not-found
pacote.fonte
command-not-found
é um auxiliar interativo, não uma ferramenta para garantir que você tenha as dependências desejadas. Obviamente, a maneira correta de declarar dependências é empacotar seu software em um pacote Debian e preencher aDepends:
declaração nodebian/control
arquivo do pacote corretamente.parece ser a maneira mais simples de fazer isso fora do dpkg e das ferramentas apt- * mais antigas
fonte
fonte
command -v <command>
; nãowhich <command>
. Consulte também Verifique se existe um programa a partir de um script Bash .Eu tinha um requisito semelhante ao executar o teste localmente, em vez de no docker. Basicamente, eu só queria instalar os arquivos .deb encontrados, se ainda não estavam instalados.
Eu acho que o único problema que vejo é que ele não verifica o número da versão do pacote, portanto, se o arquivo .deb for uma versão mais recente, isso não substituirá o pacote atualmente instalado.
fonte
Para o Ubuntu, o apt fornece uma maneira bastante decente de fazer isso. Abaixo está um exemplo para o google chrome:
apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable
Estou redirecionando a saída de erro para null, porque o apt adverte contra o uso de seu "cli instável". Eu suspeito que o pacote da lista seja estável, então acho que não há problema em jogar esse aviso fora. O -qq torna o apt super silencioso.
fonte
Este comando é o mais memorável:
Se estiver instalado, ele imprime:
Caso contrário, ele imprime
Isso foi testado no Ubuntu 12.04.1 (Precise Pangolin).
fonte
dpkg --get-selections <package-name>
não define o código de saída como diferente de zero quando o pacote não é encontrado.Muitas coisas foram ditas, mas para mim a maneira mais simples é:
fonte
No Bash:
Observe que você pode ter uma string com vários pacotes no PKG.
fonte
Eu uso da seguinte maneira:
fonte