Estou programando um script de shell do Linux que imprimirá faixas de status durante sua execução somente se a ferramenta adequada, por exemplo figlet
, estiver instalada (isto é: acessível no caminho do sistema ).
Exemplo:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Gostaria que meu script funcionasse sem erros, mesmo quando nãofiglet
estiver instalado .
O que poderia ser um método prático ?
shell
scripting
executable
Sopalajo de Arrierez
fonte
fonte
figlet ... || true
.figlet || true
, mas, no seu caso, provavelmente uma função shell que não é possível imprimir com o Echos plain text Se nenhum banner puder ser impresso, é mais provável que você queira.Respostas:
Minha interpretação usaria uma função de invólucro com o mesmo nome da ferramenta; nessa função, execute a ferramenta real, se existir:
Então você pode ter
figlet arg1 arg2...
inalterado em seu script.O @Olorin criou um método mais simples: defina uma função de wrapper apenas se for necessário (se a ferramenta não existir):
Se você deseja que os argumentos
figlet
sejam impressos, mesmo que o figlet não esteja instalado, ajuste a sugestão de Olorin da seguinte maneira:fonte
command
vem? Não o tenho em minhas instalações (Red Hat 6.8 Enterprise e Cygwin64).command
é um shell POSIX Bourne embutido. Ele normalmente executa o comando fornecido, mas a-v
flag faz com que ele se comporte mais comotype
outro shell embutido.type -a command
irá mostrar-lhe.which
mostrará apenas executáveis nas suas$PATH
palavras-chave, não incorporadas, palavras-chave, funções ou aliases.which
não encontrar um nome alternativo aplicável, porque aliaseswhich
-se a executar/usr/bin/which
(!) e canalizá-lo uma lista de aliases do shell de olhar para (Claro\which
suprime o alias e usa apenas o programa, que não mostra aliases.)Você pode testar para ver se
figlet
existefonte
Uma maneira comum de fazer isso é com o
test -x
aka[ -x
. Aqui está um exemplo retirado de/etc/init.d/ntp
um sistema Linux:Essa variante depende de conhecer o caminho completo do executável. Em
/bin/lesspipe
que eu encontrei um exemplo que funciona em torno de que, combinando-x
eowhich
comando:Dessa forma, isso funcionará sem saber com antecedência onde está
PATH
obunzip
executável.fonte
which
. E mesmo quewhich
funcione, o usotest -x
de sua saída é bobo: se você obtiver um caminhowhich
, ele existe.test -x
faz mais do que apenas verificar se existe um arquivo (test -e
é para isso). Ele também verifica se o arquivo tem as permissões de execução definidas.which
.No início do seu script, verifique se
figlet
existe e, se não existir, defina uma função shell que não faz nada:type
verifica sefiglet
existe como um shell embutido, função, alias ou palavra-chave,>/dev/null 2>&1
descarta stdin e stdout para que você não obtenha nenhuma saída e, se ela não existir,figlet() { :; }
definefiglet
como uma função que não faz nada.Dessa forma, você não precisa editar todas as linhas do seu script que usam
figlet
ou verificar se elas existem toda vezfiglet
é chamado.Você pode adicionar uma mensagem de diagnóstico, se desejar:
Como bônus, como você não mencionou qual shell está usando, acredito que ele seja compatível com POSIX, portanto, ele deve funcionar na maioria dos shell.
fonte
type figlet >/dev/null 2>&1
comhash figlet 2>/dev/null
se você estiver usando bash. (O OP disse "se estiver no meu caminho".) #Outra alternativa - um padrão que eu já vi nos scripts de configuração automática do projeto:
No seu caso específico, você poderia até fazer,
Se você não conhece o caminho específico, pode tentar vários
elif
(veja acima) para tentar locais conhecidos ou apenas usar oPATH
para sempre resolver o comando:Em geral, ao escrever scripts, prefiro chamar apenas comandos em locais específicos especificados por mim. Não gosto da incerteza / risco do que o usuário final pode ter colocado na sua
PATH
, talvez por conta própria~/bin
.Se, por exemplo, eu estivesse escrevendo um script complicado para outras pessoas que possam remover arquivos com base na saída de um comando específico que estou chamando, eu não desejaria pegar acidentalmente algo no
~/bin
que possa ou não ser o comando Eu esperava.fonte
figlet
estivesse dentro/usr/local/bin
ou/home/bob/stuff/programs/executable/figlet
?O
type
comando bash localiza um comando, função, alias, palavra-chave ou interno (consultehelp type
) e imprime o local ou a definição. Ele também retorna um código de retorno representando o resultado da pesquisa; true (0) se encontrado. Portanto, o que estamos fazendo aqui é tentar encontrarfiglet
no caminho (-p
significa apenas procurar arquivos, não built-ins ou funções e também suprime mensagens de erro), descartando a saída (é o que> /dev/null
faz) e se ela retorna verdadeira (&&
) , ele será executadofiglet
.Isso é mais simples se
figlet
estiver em um local fixo:Aqui estamos usando o
test
comando (aka[
) para ver se/usr/bin/figlet
é executável (-x
) e se sim (&&
) executá-lo. Esta solução eu acho que é mais portátil do que usartype
que é um basismo que eu acredito.Você pode criar uma função que faça isso para você:
(As cotações são necessárias devido a espaços em potencial)
Então você faria:
fonte
o /, eu diria algo como
fonte
Você pode executar um teste, suprimindo qualquer saída e testar o código de êxito / falha. Escolha argumentos para o figlet para tornar este teste barato. -? ou --help ou --version são possibilidades óbvias.
Adicionado em resposta ao comentário abaixo: se você realmente deseja testar se o figlet existe, e não que seja utilizável, você faria
fonte
$?
é igual a 127 (no meu sistema linux). 127 é "comando não encontrado". Mas meu pensamento é que, para comandos racionais, secommand --help
falhar, a instalação será acionada o suficiente para que ela não esteja lá!--help
estar disponível. Os utilitários Posix não o possuem, por um lado, e as diretrizes posix realmente recomendam isso .at --help
falha comat: invalid option -- '-'
, por exemplo, e um status de saída130
no meu sistema.-?
--help
--version
... ou você pode descobrir o quefiglet -0 --illegal
existe e tratá-lo como seu indicador de sucesso (contanto que não seja 127, o que eu classificaria como sabotagem).