Por que usamos ./filename
para executar um arquivo no linux?
Por que não basta inseri-lo como outros comandos gcc
, ls
etc …
Comentários
Resposta
No Linux, UNIX e sistemas operacionais relacionados, .
denota o diretório atual. Já que você deseja executar um arquivo em seu diretório atual e nesse diretório não está em seu $PATH
, você precisa do ./
bit para informar ao shell onde o executável é. Portanto, ./foo
significa executar o executável chamado foo
que está neste diretório.
Você pode usar type
ou which
para obter o caminho completo de todos os comandos encontrados em seu $PATH
.
Comentários
- É muito comum executar programas no diretório atual. Por que ' o shell também não pesquisa lá? Ele pesquisa primeiro em., Depois em $ PATH.
- também existem
alias
es que podem atrapalhar, não apenas$PATH
. - @Michael segurança e sanidade: se pesquisasse em
.
primeiro, seria um problema de segurança, você ou outra pessoa poderia substituirls
por exemplo (um vírus / trojen simples: faça um arquivo zip com um executável chamadols
nele, enquanto alguém está pesquisando, eles executam este executável, que …). Se ele pesquisou.
pela última vez, você pode passar muito tempo enlouquecendo sem saber por que seu programa não está funcionando (por exemplo, você cria um programa chamado teste, em vez de executar o programa que ele executa o programa de teste de sistemas. Que não produz saída). - @jcubic que ' é uma má ideia. Veja o comentário acima. No passado, o DOS fazia buscas no diretório atual e esse comportamento era transportado para o cmd do Windows, o que introduz muitos problemas de segurança. A MS corrigiu isso no PowerShell e agora você deve usar. \ Para executar o programa no diretório atual
- @ ctrl-alt-delor: Quando eu estava na universidade no final dos anos 80 ' s, essa era uma tática comum (proibida). Escrever um programa " ls " e deixá-lo em sua pasta de início para o caso de outra pessoa bisbilhotar. O programa foi chamado de " get shell " IIRC. Ele tentaria obter as credenciais do usuário que está executando o comando – e talvez imprimir uma lista de diretórios falsa para deixá-los sem saber.
Resposta
A resposta literal é a que outros deram: porque o diretório atual não está em sua $PATH
.
Mas por quê? Resumindo, é por segurança. Se você estiver procurando no diretório inicial de outra pessoa (ou / tmp) e digite apenas gcc
ou ls
, você deseja saiba que você está executando o verdadeiro, não uma versão maliciosa que seu amigo brincalhão escreveu que apaga todos os seus arquivos. Outro exemplo seria test
ou [
, que pode sobrescrever esses comandos em scripts de shell, se seu shell não os tiver como integrados.
Ter .
como última entrada em seu caminho é um pouco mais seguro, mas existem outros ataques que fazem uso disso. Um fácil é explorar erros de digitação comuns, como sl
ou ls-l
. Ou encontre um comando comum que por acaso não esteja instalado neste sistema – vim
, por exemplo, uma vez que os administradores de sistemas têm probabilidade acima da média de digitar isso.
Isso soa muito teórico? É em grande parte , mas definitivamente pode acontecer na realidade, especialmente em sistemas multiusuário. Na verdade, aqui está um exemplo deste site onde um administrador mudou para um diretório inicial de usuários e encontrou ps
para ser mascarado por um executável com esse nome.
Comentários
- Basta ter caminhos absolutos no
PATH
variável de ambiente.
Resposta
Se você quer dizer, por que você precisa./ no início – é porque (ao contrário do Windows), o diretório atual não faz parte do seu caminho por padrão. Se você executar:
$ ls
seu shell procura ls
nos diretórios de sua variável de ambiente PATH (echo $PATH
para vê-lo) e executa o primeiro executável chamado ls
que encontrar. Se você digitar:
$ a.out
o shell fará o mesmo – mas provavelmente não encontrará um executável chamado a.out. Você precisa informar ao shell onde a.out está – está no diretório atual (.), então o caminho é ./a.out
.
Se você está perguntando por que é chamado “a.out”, é apenas o nome do arquivo de saída padrão para gcc. Você pode alterá-lo com o arg da linha de comando -o. Por exemplo:
$ gcc test.c -o test $ ./test
Comentários
- Obrigado.Minha dúvida é por que você precisa ./ no início …. Usei "." (para apontar o diretório atual), mas por que " / " depois disso?
- / é o separador de caminho no Linux, então você o usa para separar o diretório (.) do nome do arquivo (a.out). Sem ele você tem .a.out, que é válido nome do arquivo por si só. (Tente
touch .a.out; ls -lA
para ver isso.) - é assim que você especifica o caminho no Unix,
<dir>/<file>
então você está basicamente dizendo para executar um arquivo no diretório atual, que é indicado por./test
- Red Hat Linux 9? É hora de atualizar!
- No Windows 10, o PowerShell é o shell padrão agora e também requer
./
para executar um executável no caminho atual
Resposta
Você pode tentar adicionar :.
à sua variável $ PATH.
Tente ALT + F2 e digite: gksudo gedit /etc/environment
se estiver executando Linux / GTK (isso é o que você tem se estiver usando o Ubuntu).
NO ENTANTO, Eu recomendo fortemente que você NÃO faça isso. É muito ruim, ruim e ruim.
Sabe, esse tipo de coisa funciona assim desde 1970. Há uma razão pela qual o diretório atual não está incluído no $ PATH.
.
é o diretório atual
.something
seria um arquivo oculto (digite “ALT +” para fazer eles aparecem no Nautilus ou tente “ls -la
“.
./someProgram.sh
é o que você digita para EXECUTAR um programa executável .sh no diretório atual.
.somethingElse
significaria que você tem um executável oculto no diretório atual, o que é uma má ideia.
Resposta
A regra mais completa é na verdade: se houver barra /
está no caminho, não pesquise PATH
Antes de entrarmos a lógica, você deve primeiro saber sobre este fato: executando um dos seguintes:
bin/someprog
ou:
ou:
cd bin ./myexec
execute bin/someprog
sem pesquisar o PATH
variável pelo mesmo motivo: todos de bin/someprog
, /bin/someprog
e ./someprog
tem uma barra /
neles.
someprog
sozinho não tem uma barra /
e, portanto, pesquisa apenas em PATH
.
POSIX 7 especifica esta regra em: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
PATH
[…] Se o nome do caminho procurado contém um
<slash>
, a busca pelos prefixos do caminho não deve ser realizada .
Justificativa para a /
regra POSIX PATH
Suponha que executando:
someprog
pesquisaria:
- relativo ao CWD primeiro
- relativo ao PATH depois
Então, se você quisesse executar /bin/someprog
de sua distro, e você fez:
someprog
às vezes funcionava, mas em outras falharia, porque você pode estar em um diretório que contém outro programa someprog
não relacionado.
Portanto, você logo aprenderia que isso não é confiável e acabaria sempre usando caminhos absolutos quando você deseja usar PATH, portanto, anulando o propósito de PATH.
É também por isso que ter caminhos relativos em seu PATH é uma ideia realmente ruim. Estou olhando para você, node_modules/bin
.
Por outro lado, suponha que executando:
./someprog
pesquisaria:
- em relação ao PATH primeiro
- em relação ao CWD depois de
Então, se você acabou de baixar um script someprog
de um repositório git e queria executá-lo do CWD, você nunca teria certeza de que este é o programa real que seria executado, porque talvez sua distro tenha um:
/bin/someprog
que está em seu PATH de algum pacote que você instalou depois de beber muito depois do Natal do ano passado.
Portanto, mais uma vez, você seria forçado a sempre executar scripts locais relativos ao CWD com caminhos completos para saber o que está executando:
"$(pwd)/someprog"
o que também seria extremamente irritante.
Outra regra que você pode se sentir tentado a sugerir é:
caminhos relativos usam apenas PATH, caminhos absolutos apenas CWD
mas mais uma vez isso força os usuários a sempre use abso caminhos lute para scripts não PATH com "$(pwd)/someprog"
.
A regra de pesquisa de caminho /
oferece uma solução simples de lembrar para o problema sobre:
- barra: não use
PATH
- sem barra: use apenas
PATH
o que torna super fácil saber sempre o que você está executando, contando com o fato de que os arquivos no diretório atual podem ser expressos como ./somefile
ou somefile
, e por isso dá um significado especial a um deles.
Às vezes, é um pouco irritante que você não possa pesquisar para some/prog
em relação a PATH
, mas não vejo uma solução mais sã para isso.
./command_name
para executar um comando no Linux? "