Quando o código de status é inútil, existe alguma maneira de construir um pipeline com base na saída do stdout?
Eu preferiria que a resposta não abordasse o caso de uso, mas a pergunta no escopo do script de shell. O que estou tentando fazer é encontrar o pacote mais específico disponível no repositório, adivinhando o nome com base nos códigos de país e idioma.
Tomemos, por exemplo, isso,
$PACKAGE1=hunspell-en-zz
$PACKAGE2=hunspell-en
O primeiro palpite é mais apropriado, mas pode não existir. Nesse caso, desejo return hunspell-en
( $PACKAGE2
) porque a primeira opção hunspell-en-zz
( $PACKAGE1
) não existe.
pipelines do apt-cache
O comando apt-cache
retorna sucesso (que é definido pelo shell como código de saída zero) sempre que o comando é capaz de executar (a partir dos documentos de apt-cache
)
apt-cache retorna zero em operação normal, decimal 100 em erro.
Isso dificulta o uso do comando em um pipeline. Normalmente, espero que o equivalente à pesquisa de pacotes de um 404 resulte em um erro (como aconteceria com curl
ou wget
). Quero pesquisar para ver se existe um pacote e, se não, voltar para outro pacote, se existir .
Isso não retorna nada, pois o primeiro comando retorna com êxito (então o rhs no ||
nunca é executado)
apt-cache search hunspell-en-zz || apt-cache search hunspell-en
apt-cache search
com dois argumentos
Isso não retorna nada, pois apt-cache
ANDs seus argumentos,
apt-cache search hunspell-en-zz hunspell-en
Dos documentos de apt-cache
Argumentos separados podem ser usados para especificar vários padrões de pesquisa que são juntos.
Portanto, como um desses argumentos claramente não existe, isso não retorna nada.
A questão
Qual é o idioma do shell para lidar com convenções como as encontradas em apt-cache
onde o código de retorno é inútil para a tarefa? E o sucesso é determinado apenas pela presença de saída no STDOUT?
Igual a
fazer encontrar falhar quando nada foi encontrado
ambos decorrem do mesmo problema. A resposta escolhida aqui menciona
find -z
que infelizmente não é a solução aplicável aqui e é específica para casos de uso. Não há menção de um idioma ou construção de um pipeline sem o uso de terminação nula (não é uma opção ativadaapt-cache
)
fonte
hunspell-en
existe? De qualquer forma, você pode usarapt-cache policy
e grep para^$PACKAGENAME:
.hunspell-ar
existem e não existem pacotes com nomes de países . Preciso encontrar o pacote mais preciso para um determinado país e idioma.find
é exatamente aapt-cache
esse respeito - código de retorno inútil, o sucesso é baseado na saída.-z
que, infelizmente, não é uma solução aqui, portanto o problema específico do caso de uso não é aplicável. E não há menção de um idioma ou a construção de um pipeline sem o uso de terminação nula (não opçãoapt-cache
)find
que eles sejam usados-print0
e cumprimentados-z
. Como o apt-cache não está fornecendo saída terminada em nulo, você não precisa-z
.Respostas:
Crie uma função que aceite um comando e retorne true se houver alguma saída.
Portanto, para este caso de uso, funcionará assim,
fonte
r printf '\n\n\n'
retornaria falso. Com conchas diferentes dezsh
,r printf '\0\0\0'
também retornaria falso. O mesmo aconteceriar printf '\0a\0b\0c'
com algumas conchas.Até onde eu sei, não existe uma maneira padrão de lidar com os casos em que o sucesso de um comando é determinado pela presença de saída. Você pode escrever soluções alternativas, no entanto.
Por exemplo, você pode salvar a saída do comando em uma variável e, em seguida, verificar se essa variável está vazia ou não:
Eu acho que isso responde à pergunta de uma maneira geral, mas se falamos sobre
apt-cache search
algumas soluções, vem à minha mente.Eu tenho um script que facilita o gerenciamento de pacotes. Algumas de suas funções são estas:
Isso permite fazer várias pesquisas em um único comando. Por exemplo:
Todas as funções pesquisam o banco de dados de uma maneira diferente, portanto os resultados podem variar dependendo da função que você usa:
fonte
Eu não chamaria isso de elegante, mas acho que pode fazer o trabalho:
Infelizmente não tenho uma máquina debian para testar. Incluí a
-n
opção "somente nomes"apt-cache
para tentar limitar os resultados da pesquisa, pois parece que você tem quase certeza do que está pesquisando.Pode ser executado como:
fonte
-q
opção silenciosa? A página de manual não é muito detalhada, mas talvez mude os valores de retorno?Muru esclareceu que nos comentários
grep
retornará um status 1 se não houver entrada. Assim, você pode adicionargrep .
ao fluxo e, se não houver entrada para corresponder ao padrão.
, ele mudará o código de status:Para o caso de uso que se parece com isso. No abaixo, não há,
-pl-pl
então ele volta e retornahunspell-pl
Ou,
Existe um
-en-US
por isso retornahunspell-en-us
.Veja também,
fonte
grep .
retorna true se a entrada contiver pelo menos uma linha (totalmente delimitada com algumas implementações) que contenha pelo menos um caractere (bem formado com a maioria das implementações) e, caso contrário, removerá as linhas vazias.grep '^'
funcionaria melhor para verificar se há alguma saída, embora com alguma implementação ainda possa retornar false se a entrada for uma linha não delimitada (e poderia remover essa linha, ou com outras implementações, retorne true, mas adicione a nova linha ausente). Algumas implementações grep também engasgam com o caráter NUL.Você pode definir um:
E depois:
Algumas
awk
implementações podem engasgar com caracteres NUL na entrada.Ao contrário
grep '^'
, seria garantido que o acima funcione em uma entrada que não termine com um caractere de nova linha, mas adicione a nova linha ausente.Para evitar isso e ser portátil para sistemas onde o
awk
NUL é bloqueado, você pode usarperl
:Com
perl
, você também pode definir uma variante que lida com arquivos arbitrários com mais facilidade:Isso limita o uso de memória (como arquivos que não têm caracteres de nova linha, como arquivos grandes e esparsos).
Você também pode criar variantes como:
ou:
(tenha em atenção que a definição de espaço em branco varia entre
awk
implementações, algumas onde estão limitadas a espaço e tabulação, outras onde também inclui caracteres de espaçamento vertical ASCII como CR ou FF, outras onde considera os espaços em branco da localidade)Idealmente, no Linux, você desejaria usar a
splice()
chamada do sistema para maximizar o desempenho. Não conheço um comando que o exponha, mas você sempre pode usarpython
'sctypes
:(observe que o
has_output
stdin ou stdout (ou ambos) deve ser um canal para osplice()
trabalho).fonte
Eu sugeriria usar funções internas muito básicas do shell:
Aqui está o caso de teste mais simples:
Então você pode usá-lo facilmente com a
||
construção à qual está acostumado:Essa função simples funcionará como você gostaria com seu
apt_cache
comportamento, independentemente do número de argumentos.fonte
ck_command echo 'asdf' | cat
não gera nada.