Existe um comando Unix padrão que faz algo semelhante ao meu exemplo abaixo
$ <cmd here> 56
$ echo Return code was $?
Return code was 56
$
<cmd here>
deve ser algo que possa ser executado em fork e deixa 56 como o código de saída quando o processo é encerrado. Os componentes internos exit
e return
shell não são adequados para o que estou procurando, pois afetam o próprio invocador ao sair dele. <some cmd>
deve ser algo que eu possa executar em contextos não shell - por exemplo, invocar a partir de um script Python com subprocess
.
Por exemplo, /usr/bin/false
sempre sai imediatamente com o código de retorno 1, mas eu gostaria de controlar exatamente o que é esse código de retorno. Eu poderia alcançar os mesmos resultados escrevendo meu próprio script de wrapper
$ cat my-wrapper-script.sh # i.e., <some cmd> = ./my-wrapper-script.sh
#!/usr/bin/bash
exit $1
$ ./my-wrapper-script.sh 56
$ echo $?
56
mas espero que exista um comando Unix padrão que possa fazer isso por mim.
fonte
exit
é o único que consigo pensar, mas tende a acabar com o seu shell.bash -c 'exit 56'
oubash -c "exit $1"
pode funcionar para você.(exit 56)
?true
efalse
built-ins, se você precisa de retornar 0 ou 1.Respostas:
A
return
função de base iria funcionar, e evita a necessidade de abrir e fechar outro shell, (como por Tim Kennedy comentário 's ):Saída:
usando
exit
em um subshell:Com cascas que não sejam
ksh93
, isso implica bifurcar um processo extra, portanto, é menos eficiente do que o descrito acima.bash
/zsh
/ksh93
único truque:(isso também implica um processo extra (e IPC com um pipe)).
zsh
Funções lambda de:fonte
<some cmd>
seja uma coisa executável ()./bin/sh -c ...originalcommand...
Não há comando UNIX padrão apenas para retornar um valor específico. Os utilitários principais do GNU fornecem
true
efalse
somente.No entanto, você pode facilmente implementar isso como
ret
:Compilar:
E corra:
Impressões:
Se você precisar que isso funcione em qualquer lugar (onde o bash está disponível, ou seja) sem instalar nenhuma ferramenta extra, você provavelmente precisará recorrer ao seguinte comando, como @TimKennedy sugerido nos comentários:
Observe que o intervalo válido de valores de retorno é 0..255 inclusive .
fonte
true
efalse
estão no Unix (e até no POSIX) também, não apenas no GNU.Se você precisar que o status de saída seja definido por um comando executado. Não existe um comando dedicado para esse 1 , mas você pode usar o intérprete de qualquer idioma que possua a capacidade de sair com um status de saída arbitrário.
sh
é o mais óbvio:Na maioria das
sh
implementações, isso é limitado aos códigos de saída de 0 a 255 (sh
aceitará valores maiores, mas poderá truncá-lo ou até causar um sinal para o processo ser executadosh
como ksh93 nos códigos de 257 a 320).Um código de saída pode ser qualquer
int
valor inteiro ( ), mas observe que você precisa recuperá-lo com awaitid()
interface para que o valor não seja truncado para 8 bits (no Linux, ele ainda é truncadowaitid()
também). Por isso, é raro (e não é uma boa ideia) usar códigos de saída acima de 255 (use 0-123 para operação normal).Alternativamente:
(aqueles não truncam o código de saída para 8 bits).
Com o NetBSD
find
, você pode:1
exit
é o comando padrão para fazer isso, mas, sendo um embutido especial do shell , não é necessário que também exista um comando com esse nome no sistema de arquivos, como para embutidos regulares, e a maioria dos sistemas não inclui umfonte
Salve isso em um arquivo chamado
returncode.c
egcc -o returncode returncode.c
fonte
argv[argc-1]
, em vez deargv[1]
, e por que você não está reclamando seargc>2
. (2) Eu estaria inclinado a fazer oargv[1]
teste antes doargv[0]
teste, permitindo que o usuário dissessetrue 56
oufalse 56
nãoreturncode 56
. Você não dá uma mensagem seargv[0]
for uma palavra eargc>0
- isso pode ser confuso. (3) Eu sou obcecado pela facilidade de uso, então eu usaria emstrcasecmp
vez destrcmp
. (4) Eu costumo validar parâmetros e não usar o valor de retornoatoi
sem verificar. Para um programa 2 ¢ como esse, acho que não importa.true
nemfalse
processa qualquer argumento em sistemas Linuxargv[0]
; os programas/bin/true
e/bin/false
são executáveis diferentes, com códigos de saída codificados. Você escreveu um programa que pode ser instalado como ambostrue
efalse
(ligada), que é inteligente. Mas a pergunta pergunta como obter um status de saída especificado pelo usuário. Seu programa responde a essa pergunta, mas somente se ele estiver instalado com um nome de arquivo diferente. Enquanto você estiver olhando deargv
qualquer maneira, acredito que fazer da maneira que sugiro manteria o nível de inteligência, evitando a necessidade de um terceiro link.Eu não tinha exatamente certeza se o seu único problema com o
exit
comando era sair do shell atual, mas se sim, um subshell pode funcionar.Eu testei isso no Cygwin Bash agora e funciona para mim.
Edit: Desculpe, eu perdi a parte de executá-lo fora de um contexto de shell. Nesse caso, isso não ajudaria sem envolvê-lo em um
.sh
script e executá-lo em seu ambiente.fonte
$(exit 42)
tenta executar a saídaexit 42
como um comando simples que faz pouco sentido (também não funcionariayash
).(exit 42)
(também é executadoexit
em um subshell, mas deixa sua saída em branco) faria mais sentido e seria mais portátil (mesmo para o csh ou o shell Bourne).