0

I wrote a small program in bash and would like to make it executable from anywhere on my computer using a custom command. In addition, my program uses a small internal database that I would also like to have "embedded" in the program. Below is an example of my problem and what I have tried so far.

Suppose my program returns the capital of a Brazilian state selected by the user. The program folder has 3 files. An internal base called capitals.csv:

Capitais,Estados,Siglas dos Estados,Regiões
Rio Branco,Acre,AC,Norte
Maceió,Alagoas,AL,Nordeste
Macapá,Amapá,AP,Norte
Manaus,Amazonas,AM,Norte
Salvador,Bahia,BA,Nordeste
Fortaleza,Ceará,CE,Nordeste
Brasília,Distrito Federal,DF,Centro-Oeste
Vitória,Espírito Santo,ES,Sudeste
Goiânia,Goiás,GO,Centro-Oeste
São Luís,Maranhão,MA,Nordeste
Cuiabá,Mato Grosso,MT,Centro-Oeste
Campo Grande,Mato Grosso do Sul,MS,Centro-Oeste
Belo Horizonte,Minas Gerais,MG,Sudeste
Belém,Pará,PA,Norte
João Pessoa,Paraíba,PB,Nordeste
Curitiba,Paraná,PR,Sul
Recife,Pernambuco,PE,Nordeste
Teresina,Piauí,PI,Nordeste
Rio de Janeiro,Rio de Janeiro,RJ,Sudeste
Natal,Rio Grande do Norte,RN,Nordeste
Porto Alegre,Rio Grande do Sul,RS,Sul
Porto Velho,Rondônia,RO,Norte
Boa Vista,Roraima,RR,Norte
Florianópolis,Santa Catarina,SC,Sul
São Paulo,São Paulo,SP,Sudeste
Aracaju,Sergipe,SE,Nordeste
Palmas,Tocantins,TO,Norte

One python file:

#get_capital.py
import pandas as pd
import sys
from unidecode import unidecode

df=pd.read_csv("capitais.csv")

df["Estados"] = [unidecode(k.lower()) for k in df["Estados"]]
user_state = unidecode(sys.argv[1].lower())
answer = df[df["Estados"]==user_state]["Capitais"].to_list()[0]

print("A capital de {} é {}".format(user_state.title(), answer))

And, finally, a bash file:

#!/usr/bin/bash
python get_capital.py $1

An example of execution would be:

bash stack.sh bahia

Output:

A capital de Bahia é Salvador

What I've tried so far:

I read here that it is possible to create a kind of hyperlink to the bash file so that it can be called from anywhere on the computer. To do this, I just type:

 sudo ln -s PATH / stack.sh /usr/bin/stack.sh

Where PATH is the path where my bash file is currently located.

This works, but it's still not what I want for two reasons. First, I still need to use the word bash before the file name. I know I can create a binary using chmod +x stack.sh (see this question for more details on this). However, what I would like to do is just use a custom command as stack instead of ./stack. In addition, although the hyperlink works and I can access my bash file from anywhere on the computer, my program itself only works in its original folder since the csv file is only there.

Anyway, how do I "package" these files in a folder that is accessible from anywhere on my computer and that can be called up using a custom command?

Lucas
  • 1,166
  • 2
  • 14
  • 34
  • 1
    Begin the script with `#!/usr/bin/bash` and make it executable, then you can run it without `bash` – Barmar Nov 12 '20 at 00:55
  • Ok. I already know that too. I'll edit my question to make it more clear. My problem is that I wan to acess both the bash file and the data globally – Lucas Nov 12 '20 at 00:57
  • Use an absolute path to the data file. – Barmar Nov 12 '20 at 00:58
  • It's not easy to get the actual directory that the script is located in. – Barmar Nov 12 '20 at 00:59
  • 1
    ...however, _if_ that's your only question, it's a duplicate (of [How to get the source directory of a bash script from within the script itself](https://stackoverflow.com/questions/59895/how-to-get-the-source-directory-of-a-bash-script-from-within-the-script-itself)). If there's a separate, non-duplicative question you mean to ask, please [edit] to ask that question explicitly. – Charles Duffy Nov 12 '20 at 01:11
  • Thanks @CharlesDuffy this is indeed what I want. It's in fact duplicate. – Lucas Nov 12 '20 at 01:16

0 Answers0