Cuando el código de estado es inútil, ¿hay alguna forma de construir una tubería basada en la salida de stdout?
Prefiero que la respuesta no aborde el caso de uso, sino la pregunta en el ámbito de las secuencias de comandos de shell. Lo que intento hacer es encontrar el paquete más específico disponible en el repositorio adivinando el nombre en función de los códigos de país e idioma.
Toma por ejemplo esto,
$PACKAGE1=hunspell-en-zz
$PACKAGE2=hunspell-en
La primera suposición es más apropiada pero puede no existir. En este caso, quiero devolver hunspell-en
( $PACKAGE2
) porque la primera opción hunspell-en-zz
( $PACKAGE1
) no existe.
tuberías de apt-cache
El comando apt-cache
devuelve el éxito (que se define como shell como código de salida cero) siempre que el comando pueda ejecutarse (desde los documentos de apt-cache
)
apt-cache devuelve cero en operación normal, decimal 100 en error.
Eso hace que usar el comando en una tubería sea más difícil. Normalmente, espero que el equivalente de búsqueda de paquetes de un 404 produzca un error (como sucedería con curl
o wget
). Quiero buscar para ver si existe un paquete, y si no, recurrir a otro paquete si existe .
Esto no devuelve nada, ya que el primer comando devuelve el éxito (por lo que el rhs ||
nunca se ejecuta)
apt-cache search hunspell-en-zz || apt-cache search hunspell-en
apt-cache search
con dos argumentos
Esto no devuelve nada, ya que apt-cache
sus argumentos Y
apt-cache search hunspell-en-zz hunspell-en
De los documentos de apt-cache
Se pueden usar argumentos separados para especificar múltiples patrones de búsqueda que se unen.
Entonces, como uno de esos argumentos claramente no existe, esto no devuelve nada.
La pregunta
¿Cuál es el idioma de shell para manejar convenciones como las que se encuentran en las apt-cache
que el código de retorno es inútil para la tarea? ¿Y el éxito está determinado solo por la presencia de salida en STDOUT?
Similar a
hacer encontrar falla cuando no se encontró nada
Ambos provienen del mismo problema. La respuesta elegida allí menciona
find -z
que lamentablemente no es una solución aplicable aquí y es específica del caso de uso. No se menciona una expresión idiomática o la construcción de una tubería sin usar terminación nula (no es una opción activadaapt-cache
)
fuente
hunspell-en
existe? De todos modos, puedes usarapt-cache policy
y grep para^$PACKAGENAME:
.hunspell-ar
existen y no hay paquetes de nombres de países. Necesito encontrar el paquete más preciso para un país e idioma determinados.find
es comoapt-cache
a este respecto: código de retorno inútil, el éxito se basa en la salida.-z
que, lamentablemente, no es una solución aquí, por lo que el problema específico del caso de uso no es aplicable. Y no se menciona una expresión idiomática o la construcción de una tubería sin usar terminación nula (no es una opciónapt-cache
)find
ser utilizado-print0
y muy útil-z
. Dado que apt-cache no está dando salida terminada en nulo, no es necesario-z
.Respuestas:
Cree una función que tome un comando y devuelva verdadero si tiene algún resultado.
Entonces para este caso de uso funcionará así,
fuente
r printf '\n\n\n'
devolvería falso. Con conchas que no seanzsh
,r printf '\0\0\0'
también devolvería falso. Lo mismo haríar printf '\0a\0b\0c'
con algunos proyectiles.Hasta donde yo sé, no hay una forma estándar de lidiar con aquellos casos en los que el éxito de un comando está determinado por la presencia de salida. Sin embargo, puede escribir soluciones alternativas.
Por ejemplo, puede guardar la salida del comando en una variable y luego verificar si esa variable está vacía o no:
Creo que esto responde a la pregunta de manera general, pero si hablamos de
apt-cache search
algunas soluciones me vienen a la mente.Tengo un script que facilita la gestión de paquetes. Algunas de sus funciones son estas:
Estos le permiten realizar múltiples búsquedas en un solo comando. Por ejemplo:
Cada función busca en la base de datos de manera diferente, por lo que los resultados pueden variar según la función que utilice:
fuente
No lo llamaría elegante, pero creo que podría hacer el trabajo:
Lamentablemente, no tengo una máquina Debian para probar. He incluido la
-n
opción de "solo nombres"apt-cache
para tratar de limitar los resultados de búsqueda, ya que parece que está casi seguro de lo que está buscando.Se puede ejecutar como:
fuente
-q
opción silenciosa? La página del manual no es muy detallada pero ¿cambia los valores de retorno?Muru aclaró que esto en los comentarios
grep
devolverá un estado de 1 si no hay entrada. Por lo tanto, puede agregargrep .
a la secuencia y si no hay entrada para que coincida con el patrón.
, cambiará el código de estado:Para el caso de uso que se ve así. En el siguiente, no hay,
-pl-pl
por lo que retrocede y vuelvehunspell-pl
O,
Hay un
-en-US
por lo que vuelvehunspell-en-us
.Ver también,
fuente
grep .
devuelve verdadero si la entrada contiene al menos una línea (completamente delimitada con algunas implementaciones) que contiene al menos un carácter (bien formado con la mayoría de las implementaciones) y, de lo contrario, eliminará las líneas vacías.grep '^'
funcionaría mejor para verificar que hay algo de salida, aunque con alguna implementación aún podría devolver falso si la entrada es una línea no delimitada (y podría eliminar esa línea, o con otras implementaciones, devolver verdadero pero agregar la nueva línea faltante). Algunas implementaciones grep también se ahogan con el carácter NUL.Podrías definir un:
Y entonces:
Algunas
awk
implementaciones pueden ahogarse con los caracteres NUL en la entrada.Al contrario
grep '^'
, se garantizaría que lo anterior funcione en una entrada que no termine en un carácter de nueva línea, pero agregaría la nueva línea faltante.Para evitar eso y ser portátil a sistemas donde se
awk
ahoga NUL, puede usarperl
en su lugar:Con
perl
, también podría definir una variante que maneje archivos arbitrarios con más gracia:Eso limita el uso de memoria (como para archivos que no tienen caracteres de nueva línea como archivos grandes y dispersos).
También puede crear variantes como:
o:
(tenga en cuenta que la definición de espacio en blanco varía entre las
awk
implementaciones, algunas donde está limitado al espacio y la pestaña, otras donde también incluye caracteres de espaciado vertical ASCII como CR o FF, algunas donde considera los espacios en blanco de la configuración regional)Idealmente, en Linux, desearía utilizar la
splice()
llamada del sistema para maximizar el rendimiento. No conozco un comando que lo exponga, pero siempre puedes usarpython
'sctypes
:(tenga en cuenta que
has_output
el stdin o stdout (o ambos) tiene que ser una tubería parasplice()
que funcione).fuente
Sugeriría utilizar funciones integradas muy básicas del shell:
Aquí está el caso de prueba más simple:
Entonces podría usarlo fácilmente con la
||
construcción a la que está acostumbrado:Esta función simple funcionará como desee con su
apt_cache
comportamiento, sea cual sea el número de argumentos.fuente
ck_command echo 'asdf' | cat
no genera nada.