A combinação de um ponto seguido por uma barra é comumente usada para preceder comandos ou scripts no Linux e em outros sistemas operacionais UNIX.
Ainda que esta característica seja um tanto confusa ou chata para novos usuários, ela existe por uma boa razão e pode ser interessante saber qual é esta razão.
O que acontece é que os comandos em sistemas UNIX ou GNU/Linux são do tipo embutidos (memorizados) ou arquivos executáveis.
No primeiro caso, temos comandos como o cd, echo, kill, ls, pwd etc. Estes são parte da shell, em execução — e, portanto, ela é sempre capaz de localizá-los.
No segundo caso, a shell precisa de ajuda para encontrar os comandos dos arquivos executáveis.
Estes arquivos podem ser tanto scripts (programas em Python, Perl, Bash etc.) como programas compilados.
Um programa compilado é um programa cujo código fonte (ou seja, seu código original, legível por humanos) tenha sido convertido em um arquivo executável, em linguagem de máquina e está pronto para rodar de imediato, sem que suas instruções precisem passar por uma interpretação prévia.
Uma shell é um programa que provê uma interface entre o usuário e o sistema — ela pode ser gráfica ou pode ser um terminal, onde você interage com o sistema em modo texto (que nem os hackers nos filmes).
O emulador de terminal ou o console é uma forma de interagir com a shell do seu sistema. A principal função da shell é ler os comandos que são digitados e executá-los.
Um script é um programa curto, escrito em uma linguagem de programação que é lido por um interpretador (Python, Perl, PHP, Bash etc.), que executa suas instruções.
Quando um texto é fornecido na linha de comandos da shell e, você pressiona Enter, esta assume que forneceu um comando.
A partir daí, a shell imediatamente verifica se a primeira string (sequência de caracteres) dada é um dos comandos embutidos dela ou um dos arquivos executáveis (que ficam guardados em diretórios apropriados).
A shell sabe quais são os diretórios de executáveis, por que eles estão armazenados em uma variável de ambiente do sistema, chamada PATH.
A variável de ambiente PATH é escrita em letras maiúsculas.
Em inglês, a palavra quer dizer “caminho”.
Sua função é informar ao sistema onde se encontram os comandos ou programas de que ele precisa.
Se nenhuma destas condições for atendida, a busca continuará nos diretórios listados na variável de ambiente PATH do usuário.
Ao ser encontrado, o comando é executado, desde que não haja qualquer outro problema.
Se não for encontrado, o usuário recebe uma mensagem de erro: “comando não encontrado” ou “command not found“.
Muitos usuários trabalham, na maior parte do tempo, em seus diretórios home e nos seus subdiretórios — por uma questão de conveniência e/ou segurança.
Contudo, o padrão do sistema operacional é não incluir estes diretórios na variável de ambiente PATH.
Portanto, se o usuário criar um script ou compilar um programa dentro de seu próprio diretório e tentar executá-lo, digitando seu nome, ele irá obter uma mensagem de erro.
Este problema pode ser facilmente resolvido com o uso de ‘./’ (um ponto e uma barra) — em inglês, é chamado de dot slash.
Trata-se, meramente, de uma forma abreviada de informar à shell que o caminho absoluto do arquivo que se está tentando executar é o diretório atual (aquele em que o usuário está trabalhando).
O uso de ./ antes de comandos locais é uma questão de segurança
Arquivos comuns, no diretório atual, podem ser acessados com uma referência simples, se acompanhados de um comando. Veja alguns exemplos:
ls Downloads/ cat lshw.log
Não há necessidade de indicar o caminho absoluto do arquivo, neste caso.
Mas, quando há a necessidade de executar alguma coisa fora dos caminhos usuais, o sistema requer que você informe exatamente o que deseja executar.
Este é um mecanismo de segurança.
Se houver algum programa malicioso, neste diretório, com este nome, ele simplesmente será ignorado e o sistema informará que não encontrou o comando.
É possível incluir o diretório /home do usuário no PATH. Basta incluir ‘.’ (ponto) na variável de ambiente PATH.
Ao fazer isto, todo os seus programas e scripts passarão a ser executados direto, sem a necessidade de indicar o caminho deles com um ‘./’.
Mas esta prática, obviamente, não é recomendada — ela põe a segurança do seu sistema em risco.
Se você fizer isto, a shell, pela ordem, irá procurar primeiro dentro do seu diretório de trabalho os comandos de execução. O que significa que, se houver um comando ‘ls’ (ou qualquer outro) lá dentro, ele é que será executado.
Se você necessita executar várias vezes seus scripts e está se incomodando com este “obstáculo de segurança”, há maneiras mais inteligentes e seguras de contorná-lo.
Como alterar a variável de ambiente PATH
Uma forma profissional de lidar com esta situação, em segurança, é criar um subdiretório no seu diretório local, para guardar seus scripts e seus programas compilados.
É seguro, então, informar este diretório específico ao PATH.
Você pode ver o conteúdo da variável de ambiente $PATH com o comando echo:
echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Portanto, crie um subdiretório, no seu home, chamado ‘bin’, e o inclua no PATH. Assim:
mkdir bin export PATH=$PATH:$HOME/bin echo $PATH
Note, ao final da linha, o novo diretório ‘/home/justincase/bin’ foi incluído:
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/justincase/bin
Esta alteração só vale para a sessão atual.
Se você quiser torná-la permanente, inclua a linha export PATH=$PATH:$HOME/bin
ao final do arquivo ‘.bashrc’.
Seja cuidadosa(o) e brinque com segurança.
Referências
http://www.linfo.org/dot_slash.html
http://stackoverflow.com/questions/6331075/why-do-you-need-dot-slash-before-script-name-to-run-it-in-bash
2 replies on “Por que precisamos usar ./ antes do nome de um script para executá-lo no Linux?”
De qualquer forma, na verdade, sempre evito dar permissões de execução à scripts. Talvez seja só algo pessoal, mas evito. Sempre que posso utilizo o próprio interpretador, algo como:
~~~
$ bash shell.bash
$ python script.py
$ source ~/.zshrc
~~~
Ou a forma longa deles. Isso pode me evitar cair na falha de wrong enviroment ou de comandos sem caminho explícito.
Parabéns pela explicação Elias. Muito bom…