Eu quero escrever uma função bash que verifique se um arquivo tem certas propriedades e retorna verdadeiro ou falso. Então eu posso usá-lo em meus scripts no "se". Mas o que devo retornar?
function myfun(){ ... return 0; else return 1; fi;}
então eu uso assim:
if myfun filename.txt; then ...
claro que isso não funciona. Como pode ser isto alcançado?
function
palavras-chave,myfun() {...}
sufixosif
é o status de saída zero demyfun
: semyfun
sai com0
,then ...
é executado; se é algo maiselse ...
é executado.function
palavra-chave é um basismo, e causará erros de sintaxe em alguns outros shells. Basicamente, é desnecessário ou proibido, então por que usá-lo? Não é sequer útil como um destino grep, pois pode não estar lá (grep for()
).Respostas:
Use 0 para verdadeiro e 1 para falso.
Amostra:
Editar
No comentário de @ amichair, isso também é possível
fonte
[ -d "$1" ]
.Por que você deveria se importar com o que eu digo, apesar de haver uma resposta mais de 250 votada
Não é isso
0 = true
e1 = false
. É: zero significa nenhuma falha (sucesso) e diferente de zero significa falha (do tipo N) .Embora a resposta selecionada seja tecnicamente "verdadeira" , não coloque
return 1
** no seu código como falso . Terá vários efeitos colaterais infelizes.Aprenda alguma festa
O manual do bash diz (ênfase minha)
Portanto, nunca precisamos usar 0 e 1 para indicar Verdadeiro e Falso. O fato de fazer isso é essencialmente um conhecimento trivial, útil apenas para depurar código, entrevistar perguntas e surpreender os novatos.
O manual do bash também diz
O manual do bash também diz
Uau, espera. Pipeline? Vamos voltar ao manual do bash mais uma vez.
Sim. Eles disseram que 1 comando é um pipeline. Portanto, todas as três citações estão dizendo a mesma coisa.
$?
diz o que aconteceu por último.Minha resposta
Portanto, enquanto o @Kambus demonstrou que, com uma função tão simples, isso não
return
é necessário. Eu acho que era irrealisticamente simples comparado às necessidades da maioria das pessoas que lerão isso.Por que
return
?Se uma função retornará o status de saída do último comando, por que usar
return
? Porque faz com que uma função pare de executar.Pare a execução sob várias condições
O que temos aqui é ...
Line
04
é um retorno explícito [-ish] true, porque o RHS de&&
apenas é executado se o LHS for trueLinha
09
retorna verdadeiro ou falso, correspondendo ao status da linha08
Linha
13
retorna falsa por causa da linha12
(Sim, isso pode ser resolvido, mas o exemplo inteiro é artificial.)
Outro padrão comum
Observe como definir uma
status
variável desmistifica o significado de$?
. (É claro que você sabe o que$?
significa, mas alguém com menos conhecimento do que você terá que pesquisar no Google algum dia. A menos que seu código esteja negociando em alta frequência, mostre algum amor , defina a variável.) Mas a verdadeira desvantagem é que "se não existe status "ou vice-versa" se o status de saída "puder ser lido em voz alta e explicar seu significado. No entanto, esse último pode ser um pouco ambicioso, porque ver a palavraexit
pode fazer você pensar que está saindo do script, quando na realidade está saindo do$(...)
subshell.** Se você absolutamente insistir em usar
return 1
falso, sugiro que você use pelo menosreturn 255
. Isso fará com que seu futuro eu ou qualquer outro desenvolvedor que precise manter seu código questione "por que isso é 255?" Então eles estarão prestando atenção e terão uma chance melhor de evitar um erro.fonte
if
sucesso fazer isso,else
fazer aquilo". Sucesso em quê? Pode estar verificando se verdadeiro / falso, pode estar verificando uma sequência, número inteiro, arquivo, diretório, permissões de gravação, glob, regex, grep ou qualquer outro comando que esteja sujeito a falhas .true
efalse
comandos. Ou seja, a palavra-chave étrue
literalmente avaliada como um código de status 0. Além disso, as declarações if-then por natureza operam em booleanos, não em códigos de sucesso. Se ocorrer um erro durante uma operação booleana, ele não deve retornar verdadeiro ou falso, mas simplesmente interromper a execução. Caso contrário, você obtém falsos positivos (trocadilho).return 1
deve ser evitado. Supondo que eu tenha umavalidate
função, acho razoávelreturn 1
que a validação falhe. Afinal, esse é um motivo para interromper a execução de um script se ele não for tratado adequadamente (por exemplo, ao usarset -e
).return 1
é válido. Minha preocupação é com todos os comentários aqui dizendo "0 = verdadeiro 1 = falso é [inserir palavra negativa]". É provável que essas pessoas leiam seu código algum dia. Portanto, para eles, verreturn 255
(ou 42 ou mesmo 2) deve ajudá-los a pensar mais sobre isso e não confundi-lo como "verdadeiro".set -e
ainda vai pegá-lo.fonte
Cuidado ao verificar o diretório apenas com a opção -d!
se a variável $ 1 estiver vazia, o cheque ainda será bem sucedido. Para ter certeza, verifique também se a variável não está vazia.
fonte
$1
("$1"
), não precisará procurar uma variável vazia. O[[ -d "$1" ]]
iria falhar porque este""
não é um diretório.Encontrei um ponto (ainda não mencionado explicitamente?) Sobre o qual estava tropeçando. Ou seja, não como retornar o booleano, mas como avaliá-lo corretamente!
Eu estava tentando dizer
if [ myfunc ]; then ...
, mas isso é simplesmente errado. Você não deve usar os suportes!if myfunc; then ...
é a maneira de fazer isso.Como no @Bruno e outros, reiteramos
true
efalse
são comandos , não valores! Isso é muito importante para entender os booleanos nos scripts de shell.Neste post, expliquei e demonstrei usando variáveis booleanas : https://stackoverflow.com/a/55174008/3220983 . Eu sugiro fortemente verificar isso, porque é muito relacionado.
Aqui, fornecerei alguns exemplos de retorno e avaliação de booleanos a partir de funções:
Este:
Não produz saída de eco. (ou seja,
false
retorna falso)Produz:
(ou seja,
true
retorna verdadeiro)E
Produz:
Porque 0 (ou seja, verdadeiro) foi retornado implicitamente .
Agora, isso é o que estava me ferrando ...
Produz:
E
TAMBÉM produz:
Usar os colchetes aqui produziu um falso positivo ! (Eu deduzo que o resultado do comando "externo" é 0.)
A principal vantagem do meu post é: não use colchetes para avaliar uma função booleana (ou variável) como você faria para uma verificação de igualdade típica, por exemplo
if [ x -eq 1 ]; then...
!fonte
Use os comandos
true
oufalse
imediatamente antes do seu ereturn
, em seguida,return
sem parâmetros. Oreturn
usará automaticamente o valor do seu último comando.O fornecimento de argumentos para
return
é inconsistente, digite específico e propenso a erros se você não estiver usando 1 ou 0. E, como comentários anteriores declararam, usar 1 ou 0 aqui não é o caminho certo para abordar essa função.Resultado:
fonte
Pode funcionar se você reescrever isso
function myfun(){ ... return 0; else return 1; fi;}
como estefunction myfun(){ ... return; else false; fi;}
. Ou seja, sefalse
é a última instrução na função, você obtém resultado falso para toda a função, masreturn
interrompe a função com resultado verdadeiro de qualquer maneira. Acredito que seja verdade para o meu intérprete de festa, pelo menos.fonte
Encontrei a forma mais curta para testar a saída da função é simplesmente
fonte
Por razões de legibilidade do código, acredito que o retorno verdadeiro / falso deve:
return
seguida por outra palavra-chave (true
oufalse
)Minha solução é
return $(true)
oureturn $(false)
como mostrado:fonte
Seguindo @Bruno Bronosky e @mrteatime, ofereço a sugestão de que você escreva seu retorno booleano "para trás". É isso que eu quero dizer:
Isso elimina o feio requisito de duas linhas para cada declaração de retorno.
fonte