¿Existe un comando estándar de Unix que haga algo similar a mi ejemplo a continuación?
$ <cmd here> 56
$ echo Return code was $?
Return code was 56
$
<cmd here>
debe ser algo que se pueda ejecutar con fork y deje 56 como código de salida cuando el proceso finalice. Los builtins exit
y return
shell no son adecuados para lo que estoy buscando porque afectan al shell invocador al salir de él. <some cmd>
debería ser algo que pueda ejecutar en contextos que no sean de shell, por ejemplo, invocar desde un script Python con subprocess
.
Por ejemplo, /usr/bin/false
siempre sale inmediatamente con el código de retorno 1, pero me gustaría controlar exactamente qué es ese código de retorno. Podría lograr los mismos resultados escribiendo mi propio script de envoltura
$ 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
pero espero que exista un comando estándar de Unix que pueda hacer esto por mí.
fuente
exit
es el único que se me ocurre, pero tiende a terminar con su caparazón.bash -c 'exit 56'
obash -c "exit $1"
podría funcionar para ti.(exit 56)
?true
efalse
incorporados si necesitas devolver 0 o 1.Respuestas:
Una
return
función basada funcionaría y evita la necesidad de abrir y cerrar otro shell (según el comentario de Tim Kennedy ):Salida:
utilizando
exit
en una subshell:Con otros caparazones distintos
ksh93
, eso implica bifurcar un proceso adicional, por lo que es menos eficiente que el anterior.bash
/zsh
/ksh93
solo truco:(eso también implica un proceso adicional (e IPC con una tubería)).
zsh
Las funciones lambda de:fuente
<some cmd>
sea una cosa ejecutable ()./bin/sh -c ...originalcommand...
No existe un comando UNIX estándar para devolver un valor específico. Las utilidades principales de GNU proporcionan
true
yfalse
solo.Sin embargo, puede implementarlo fácilmente usted mismo como
ret
:Compilar:
Y correr:
Huellas dactilares:
Si necesita que esto funcione en todas partes (donde está disponible bash, es decir) sin instalar ninguna herramienta adicional, probablemente deba recurrir al siguiente comando como sugirió @TimKennedy en los comentarios:
Tenga en cuenta que el rango válido de valores de retorno es 0..255 inclusive .
fuente
true
yfalse
están en Unix (e incluso POSIX) también, no solo en GNU.Si necesita que los comandos ejecutados establezcan el estado de salida. No hay un comando dedicado para ese 1 , pero puede usar el intérprete de cualquier idioma que tenga la capacidad de salir con un estado de salida arbitrario.
sh
es el más obvio:Con la mayoría de las
sh
implementaciones, eso se limita a los códigos de salida 0 a 255 (sh
aceptará valores mayores pero puede truncarlo o incluso hacer que se envíe una señal al proceso que se ejecutash
como con ksh93 para los códigos 257 a 320).Un código de salida puede ser cualquier
int
valor entero ( ), pero tenga en cuenta que necesita recuperarlo con lawaitid()
interfaz para que el valor no se trunca a 8 bits (en Linux, sin embargo, también se truncawaitid()
). Por eso es raro (y no es una buena idea) usar códigos de salida superiores a 255 (use 0-123 para el funcionamiento normal).Alternativamente:
(esos no truncan el código de salida a 8 bits).
Con NetBSD
find
, puedes hacer:1
exit
es el comando estándar para hacer eso, pero al ser un intérprete de comandos especial de shell , no hay ningún requisito de que también haya un comando con ese nombre en el sistema de archivos, como para las incorporaciones regulares, y la mayoría de los sistemas no incluirán unofuente
Guarde esto en un archivo llamado
returncode.c
ygcc -o returncode returncode.c
fuente
argv[argc-1]
lugar deargv[1]
, y por qué no te quejas siargc>2
. (2) Me inclinaría a hacer laargv[1]
prueba antes de laargv[0]
prueba, permitiendo al usuario decirtrue 56
o enfalse 56
lugar dereturncode 56
. No da un mensaje siargv[0]
es una palabra yargc>0
eso podría ser confuso. (3) Estoy obsesionado con la facilidad de uso, por lo que usaría enstrcasecmp
lugar destrcmp
. (4) Tiendo a validar los parámetros y no usar el valor de retorno deatoi
sin verificarlo. Para un programa de 2 ¢ como este, supongo que no importa.true
nifalse
procesa ningún argumento en sistemas Linuxargv[0]
; los programas/bin/true
y/bin/false
son ejecutables diferentes, con códigos de salida codificados. Has escrito un programa que se puede instalar como ambostrue
yfalse
(vinculado), lo cual es inteligente. Pero la pregunta pregunta cómo obtener un estado de salida especificado por el usuario. Su programa responde a esa pregunta, pero solo si está instalado con un nombre de archivo diferente. Mientras lo veas deargv
todos modos, creo que hacerlo de la manera que sugiero mantendría el nivel de inteligencia, evitando la necesidad de un tercer enlace.No estaba exactamente seguro de si su único problema con el
exit
comando era salir del shell actual, pero si es así, un subshell podría funcionar.Probé esto en Cygwin Bash justo ahora y funciona para mí.
Editar: Lo siento, me perdí la parte de ejecutarlo fuera de un contexto de shell. En ese caso, esto no ayudaría sin envolverlo dentro de un
.sh
script y ejecutarlo desde su entorno.fuente
$(exit 42)
intenta ejecutar la salida deexit 42
como un comando simple que tiene poco sentido (tampoco funcionaría conyash
).(exit 42)
(también se ejecutaexit
en un subshell, pero deja solo su salida) tendría más sentido y sería más portátil (incluso para csh o el shell Bourne).