function foo {
(cd $FOOBAR;
<some command>
if [$? -ne 0]
then
echo "Nope!"
else
echo "OK!"
fi
)
}
Estou tentando escrever uma função como a acima e colocá-la no meu arquivo .bashrc. Depois de originar o arquivo e executar, recebo:
Tempo total: 51 segundos -
flash: [1: comando não encontrado
OK!
Alguém pode me ajudar a entender o que fiz de errado?
$?
é igual a 0 com umaif
instrução é inútil,if
espera um comando e, se esse comando retornar0
, ele executa o código no bloco. assimif true; then echo hello; fi
ecoará Olá desde que o comandotrue
retornou0
.$?
mantém o status do último pipeline , que não é o comandotest
([
) naif
instrução O exemplo está testando sesome command
foi bem-sucedido. Você pode fazer o mesmo com&&
e||
, mas pode criar linhas longas e ilegíveis em comparação comif [ $? -eq 0 ]
. O mesmo argumento vale paraif some command
$?
expande, estou apontando que não há sentido emtest
ser usado; desde queif some command
faz a mesma coisa com uma instrução versus ter duas instruções separadas. se o comando já for longo, adicionar mais três caracteres não tornaria o 'ilegível' muito mais 'ilegível'.Respostas:
Adicione um espaço após o
[
e outro antes]
:[
é um builtin shell, é um comando comoecho
,read
,expr
... ele precisa de um espaço atrás dele, e requer uma correspondência]
.Escrita
[ $? -ne 0 ]
é realmente invocando[
e dando-lhe 4 parâmetros:$?
,-ne
,0
, e]
.Nota: o fato de você estar recebendo um erro ao dizer
[1: command not found
significa que$?
estava tendo o valor de1
.fonte
[
é um link paratest
também[
é um shell embutido e/usr/bin/[
raramente é usado.Ou você pode pular
$?
completamente. Se o seu comando forcmd
, o seguinte deve funcionar:fonte
É uma boa prática atribuir o valor de retorno a uma variável antes de usá-lo
Permite reutilizar o valor de retorno. por exemplo, em uma declaração if ... elif ... else ...
fonte
[
(Sem o espaço, ele se torna um erro de sintaxebash
) Desfará se você editar e corrigir o erro.$?
diretamente, pois isso será interrompido se você, ao editar o script posteriormente, colocar uma linha entre o comando e a$?
verificação.A única razão pela qual você deseja usar
$?
como argumentos para um[
comando (se esse[
comando é executado na parte da condição de umaif
instrução ou não) é quando você deseja discriminar um status de retorno específico, como:A sintaxe para todos aqueles
if
,while
,until
... declarações éQue é executado
cmd-list2
secmd-list1
for bem-sucedido oucmd-list3
não.O
[ "$?" -eq 0 ]
comando é no-op. Ele define$?
como 0 se$?
for 0 e$?
como diferente de zero se for diferente de zero.Se você deseja executar algo em caso de
cmd
falha, é:Geralmente, você não precisa mexer e
$?
muito menos saber qual valor significatrue
oufalse
. Os únicos casos são como eu disse acima, se você precisar discriminar um valor específico ou se precisar salvá-lo para mais tarde (por exemplo, devolvê-lo como o valor de retorno de uma função) como:Lembre-se também de que deixar uma variável sem aspas é o operador split + glob. Não faz sentido chamar esse operador aqui, portanto deve ser:
não
, muito menos[ $? -ne 0 ]
(que só chamaria o[$? -ne 0 ]
[
comando se$IFS
contivesse o primeiro caractere de$?
).Observe também que a maneira Bourne de definir uma função é ficar
function-name()
na frente de um comando. Esse é o caso em todas as Bourne como o escudo, excetobash
eyash
(e versões recentes doposh
), que só permitem um comando composto (comandos compostos sendo{...}
ou(...)
ou coisas comofor...done
,if...fi
...function foo { ... }
é aksh
sintaxe de definição da função. Não há motivo para você querer usá-lo aqui.Seu código pode ser gravado de forma portável (POSIXly):
Observe também que
cd
sem-P
tem um significado muito especial (lida com caminhos que contêm..
componentes de maneira diferente de qualquer outro comando), portanto, é melhor incluí-lo em scripts para evitar confusões.(essa função retorna
false
secd
falhar, mas não se<some command>
falhar).fonte
Acredito que o comando abaixo fará tudo o que você deseja em uma linha.
fonte