Boas, xente.
A semana pasada pasei por un comentario en HN do 2019. O usuario estaba experimentando cuns script pra facer algunhas contas directamente no terminal bash.
TLDR: Clica aquí pra saltar a historia e ir directamente ao código.
O que o usuario propoñía era usar algo coma isto, baseado no comando dc (os comentarios son meus).
$ . calc.sh # Cargar funcións
$ * 4 5 # Multiplica 4 e 5
20
$ / 21 3 # Divide 21 por 3
7
Isto soaba interesante. Persoalmente, cando teño que facer algunhas contas abro un terminal e invoco ao Python, e facelo directamente sen ter que lanzar Python parecía útil.
Pero, se tivera que facer un cambio pequeno… a algunha xente lle resulta intuitiva a notación Polaca , pero pra isto preferiría ter unha notación mais habitual. Algo coma:
$ C 4 * 5
20
$ C 21 / 3
7
Esa e a idea, o comando se chamaría C
e os argumentos deben ser o mais naturais posible.
O xeito máis sinxelo de facelo é escreber unha función bash que invoque o interprete de Python de transparentemente, algo coma…
C () {
python -c "print($*)"
}
Pero hai un problema! Con isto podemos facer algunhas contas, pero os produtos (*
) serían expandidos a nomes de ficheiros:
# Simulemos un directorio con algúns ficheiros
$ mkdir test
$ cd test
$ touch fname1
$ touch fname2
# Se invocamos a función, o '*' será reemplazado por nomes de ficheiro
$ C 4 * 5
File "<string>", line 1
print(4 fname1 fname2 5)
^
SyntaxError: invalid syntax
Podemos pensar en desactivar a expansión dentro da nosa función. Pero a expansión ocorre antes de que o comando se execute, así que non podemos solucionalo dentro da función.
Algo que semella unha función, e que pode facer cousas antes de expandir os argumentos e un alias.
__calc () {
python -c "print($*)"
set +f # Re-activar a expansión de ficheiros
}
alias C='set -f; __calc '
De este xeito, o alias executa set -f
, e con isto desactiva a expansión,
antes de que se evalúen os argumentos de función __calc
.
$ C 4 * 5
20
$ echo *
fname1 fname2
Vale, agora imos probar a importar a libraría matemática de Python…
__calc () {
python -c "from math import *; print($*)"
set +f # Re-activar a expansión de ficheiros
}
alias C='set -f; __calc '
E usémola pra facer algúns cálculos:
$ C sqrt( 999 )
bash: syntax error near unexpected token `('
Vaia, iso non pinta ben. Veredes, en bash o carácter (
é interpretado coma o
comezo dunha subshell, e isto (ao contrario da expansión dos nomes de ficheiro)
non pode ser deshabilitado.
Pra ser honesto, non atopei unha solución pra isto, pero podo ofrecervos dúas opcións:
Primeira, simplemente usemos comiñas:
$ C "sqrt( 999 )"
31.606961258558215
A outra e aceptar os parámetros con outros caracteres, que reemplazaremos por parénteses []
→ ()
:
Resultado
__calc () {
local __calc_CMD=$(echo "$*"|tr "[]" "()")
python -c "from math import *; print($__calc_CMD)"
set +f # Re-activar a expansión de ficheiros
}
alias C='set -f; __calc '
E con isto xa podemos facer os cálculos directamente no terminal:
$ C sqrt [ 3 + [ 3 * 4 ] / 2 ]
3.0
Iso é todo, ahí queda a idea. Leémonos!