Abusar del operador ternario, ((test)) && cmd1 || cmd2
o [ test ] && cmd1 || cmd2
, tanto como sea posible.
Ejemplos (los recuentos de longitud siempre excluyen la línea superior):
t="$something"
if [ $t == "hi" ];then
cmd1
cmd2
elif [ $t == "bye" ];then
cmd3
cmd4
else
cmd5
if [ $t == "sup" ];then
cmd6
fi
fi
Al usar solo operadores ternarios, esto se puede acortar fácilmente a:
t="$something"
[ $t == "hi" ]&&{
cmd1;cmd2
}||[ $t == "bye" ]&&{
cmd3;cmd4
}||{
cmd5
[ $t == "sup" ]&&cmd6
}
Como nyuszika7h señaló en los comentarios, este ejemplo específico podría acortarse aún más usando case
:
t="$something"
case $t in "hi")cmd1;cmd2;;"bye")cmd3;cmd4;;*)cmd5;[ $t == "sup" ]&&cmd6;esac
Además, prefiera los paréntesis a las llaves tanto como sea posible. Como los paréntesis son metacaracteres y no una palabra, nunca requieren espacios en ningún contexto. Esto también significa ejecutar tantos comandos en una subshell como sea posible, porque las llaves (es decir, {
y }
) son palabras reservadas, no metacaracteres, y por lo tanto deben tener espacios en blanco en ambos lados para analizar correctamente, pero los metacaracteres no lo hacen. Supongo que ya sabe que las subcapas no afectan el entorno principal, por lo que suponiendo que todos los comandos de ejemplo se puedan ejecutar de forma segura en una subcapa (lo cual no es típico en ningún caso), puede acortar el código anterior a esto :
t=$something
[ $t == "hi" ]&&(cmd1;cmd2)||[ $t == "bye" ]&&(cmd3;cmd4)||(cmd5;[ $t == "sup" ]&&cmd6)
Además, si no puede hacerlo, usar paréntesis aún puede minimizarlo. Una cosa a tener en cuenta es que solo funciona para enteros, lo que lo hace inútil para los propósitos de este ejemplo (pero es mucho mejor que usar -eq
para enteros).
Una cosa más, evite las comillas siempre que sea posible. Usando ese consejo anterior, puedes minificarlo aún más. Ejemplo:
t=$something
[ $t == hi ]&&(cmd1;cmd2)||[ $t == bye ]&&(cmd3;cmd4)||(cmd5;[ $t == sup ]&&cmd6)
En condiciones de prueba, prefiera corchetes simples a corchetes dobles tanto como sea posible, con algunas excepciones. Deja caer dos caracteres de forma gratuita, pero en algunos casos no es tan robusto (es una extensión de Bash; vea un ejemplo a continuación). Además, use el argumento de igual simple en lugar del doble. Es un personaje libre para soltar.
[[ $f == b ]]&&: # ... <-- Bad
[ $f == b ]&&: # ... <-- Better
[ $f = b ]&&: # ... <-- Best. word splits and pathname-expands the contents of $f. Esp. bad if it starts with -
Tenga en cuenta esta advertencia, especialmente al verificar la salida nula o una variable indefinida:
[[ $f ]]&&: # double quotes aren't needed inside [[, which can save chars
[ "$f" = '' ]&&: <-- This is significantly longer
[ -n "$f" ]&&:
En todos los aspectos técnicos, este ejemplo específico sería mejor con case
... in
:
t=$something
case $t in hi)cmd1;cmd2;;bye)cmd3;cmd4;;*)cmd5;[ $t == sup ]&&cmd6;esac
PD: Aquí hay una lista de metacaracteres reconocidos en Bash independientemente del contexto (y puede separar palabras):
EDITAR: Como señaló manatwork, la prueba de paréntesis doble solo funciona para enteros. Además, indirectamente, descubrí que necesitas tener espacios en blanco alrededor del ==
operador. Corregí mi publicación anterior.
También era demasiado vago para volver a calcular la longitud de cada segmento, así que simplemente los eliminé. Debería ser fácil encontrar una calculadora de longitud de cadena en línea si es necesario.
sh
y qué shell permite estafor
sintaxis? está expresamente permitido enzsh
.