Ao executar um programa C a.out
, usando o terminal Ubuntu, por que eu sempre preciso digitar ./
antes a.out
, em vez de apenas escrever a.out
? Existe solução para isso?
Ao executar um programa C a.out
, usando o terminal Ubuntu, por que eu sempre preciso digitar ./
antes a.out
, em vez de apenas escrever a.out
? Existe solução para isso?
Respostas:
Quando você digita o nome de um programa, como a.out
o sistema, procura o arquivo no seu PATH. No meu sistema, PATH está definido como
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
O seu provavelmente é semelhante. Para verificar, entre echo $PATH
em um terminal.
O sistema examina esses diretórios na ordem indicada e, se não conseguir encontrar, o programa produz um command not found
erro.
Anexar o comando com ./
efetivamente diz "esqueça o PATH, quero que você procure apenas no diretório atual".
Da mesma forma, você pode dizer ao sistema para procurar apenas em outro local específico, acrescentando o comando a um caminho relativo ou absoluto, como:
../
significa no diretório pai, por exemplo, ../hello
procure hello no diretório pai.
./Debug/hello
: "procure hello
no subdiretório Debug do meu diretório atual."
ou /bin/ls
: "procure ls
no diretório /bin
"
Por padrão, o diretório atual não está no caminho porque é considerado um risco de segurança. Veja Por que é. não está no caminho por padrão? no Superusuário por que.
É possível adicionar o diretório atual ao seu PATH, mas pelos motivos apresentados na pergunta vinculada, eu não o recomendaria.
.
ao seu PATH
(como os outros 2 respostas atualmente sugerem), devido ao risco de segurança mencionados nesta resposta.
.
aqui, você pode usar um caminho completo ou relativo para um executável, por exemplo, /home/user/foo/a.out
ou./build/a.out
.
é especial porque significa "meu diretório atual" e, portanto, qualquer diretório em que o usuário se encontre com privilégios de leitura e execução. Isso é potencialmente mais perigoso do que adicionar um caminho específico totalmente qualificado.
.
não possui status especial, é apenas um caminho que poderia começar /
e ./blah
funcionaria tão bem com cat
ou grep
como um prompt do bash.
A razão para isso é simples.
Suponha que você tenha um comando com o mesmo nome de um aplicativo no diretório atual. A execução do comando no shell chamaria seu aplicativo em vez do comando interno. Isso seria uma preocupação de segurança, se nada mais.
Ao exigir o ./
uso inicial, o shell sabe que você deseja executar o aplicativo com o nome especificado e não um comando interno com esse nome.
./
executa arquivos que não estão no seu $PATH
, em vez disso, executa o arquivo no diretório atual (ou outro via ./home/stefano/script.sh
). Agora, PATH é uma variável de ambiente que contém todos os locais onde o bash pode procurar programas executáveis, sem ter o caminho completo (absoluto) para eles.
Essa separação é necessária para evitar a execução do arquivo errado. Ou seja, se você tiver um arquivo chamado ls
no diretório inicial, ele não estará no PATH impedirá que o bash o confunda com o real ls
. A variável PATH também define a ordem da pesquisa:
exec
syscall (um método especial do Kernel, como os programas são iniciados), o sistema procura o arquivo percorrendo cada um dos diretórios do seu PATH. Depois que o programa é encontrado, mesmo que esteja em vários diretórios, a pesquisa é interrompida e o primeiro encontrado é executado.Para executar um arquivo, você precisará definir o bit executável nas permissões:
Como você já está na linha de comando, basta digitar chmod +x finename
.
Ou você pode definir as permissões clicando com o botão direito do mouse no arquivo e selecionando Propriedades :
Agora você pode copiar o arquivo para qualquer um dos diretórios no PATH, para ver quais estão lá - e eles são definidos por usuário - echo $PATH
.
stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Se você criar um arquivo executável cat
e movê-lo para /usr/local/sbin
, ele será executado em vez do apropriado cat
, no qual reside /bin
. Você pode descobrir onde estão seus arquivos usando type cat
e whereis cat
.
gcc
, que define automaticamente o bit de execução.
./
antes de executar um programa?No terminal, sempre que você digitar o nome de um aplicativo, digamos gedit
, o terminal irá procurar em alguns diretórios (predefinidos) que contêm aplicativos (os binários dos aplicativos). Os nomes desses diretórios estão contidos em uma variável chamada PATH
. Você pode ver o que há nessa variável executando echo $PATH
. Veja os diretórios separados por :
? Esses são os diretórios que o terminal vão pesquisar, se você acabou de digitar gedit
, nautilus
ou a.out
. Como você pode ver, o caminho do seu a.out
programa não está lá. Ao fazê-lo ./a.out
, você está dizendo ao terminal "procure no diretório atual e execute a.out
, e não entre PATH
.
Se você não quiser digitar ./
todas as vezes, precisará adicionar a.out
o diretório $PATH
. Nas instruções a seguir, assumirei que o caminho para a.out
é /path/to/programs/
, mas você deve alterá-lo para o caminho atual.
Basta adicionar a seguinte linha ao final do arquivo ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Efetue logout e logon novamente. Agora você poderá executar a.out
sem ./
nenhum diretório.
Se você tiver outros programas em outros diretórios, basta adicioná-los à linha acima. No entanto, aconselho que você tenha um diretório chamado "myPrograms", por exemplo, e coloque todos os seus programas nele.
Nota: mude
userName
para o nome de usuário atual do Ubuntu.
E se você tiver outros programas que deseja executar? E eles estão todos em pastas diferentes? Bem, uma solução "mais organizada" seria criar uma pasta chamada bin
no diretório Home e adicionar links simbólicos (atalhos) nessa pasta. Aqui está como:
mkdir /home/userName/bin
bin
no seu diretório inicial.ln -s /path/to/programs/a.out /home/userName/bin
a.out
programa em bin
.Efetue logout e logon novamente. Agora você poderá executar a.out
sem ./
nenhum diretório.
Agora, sempre que você tiver outro programa em qualquer outro lugar, digamos que o programa b.in
na sua área de trabalho, tudo o que você precisa fazer é: ln -s /home/userName/Desktop/b.in /home/userName/bin
e você poderá executá-lo sem ./
o mesmo.
Nota: graças ao comentário de @ Joe , quando você faz backups, os links simbólicos precisam ser tratados especialmente. Por padrão,
rsync
não os processa, portanto, quando você restaura, eles não estão lá.
Como George apontou em sua resposta, isso ajuda você a observar que você está executando um arquivo no diretório de trabalho atual ( pwd
).
Lembro-me de fazer essa pergunta ao meu veterano há muito tempo, ele disse que eu deveria adicionar .
ao meu caminho para que, quando o fizer a.out
, procure no diretório atual e o execute. Nesse caso, não preciso fazer ./a.out
.
Mas, pessoalmente, eu recomendaria contra isso. Isso nunca aconteceu comigo, mas se você estiver em um diretório de rede alienígena ou algo assim, e um arquivo executável malicioso chamado ls
existir lá, ter .
no seu caminho é uma péssima idéia. Não que você encontre esse problema com muita frequência, apenas dizendo.
.
a $PATH
. Idéia muito perigosa.
Além de outras respostas, aqui a parte essencial da man bash
qual explica isso bem:
EXECUÇÃO DE COMANDO Após um comando ser dividido em palavras, se resultar em um simples comando e uma lista opcional de argumentos, as seguintes ações são ocupado. Se o nome do comando não contiver barras, o shell tentará localizar isto. Se existir uma função shell com esse nome, essa função será invocado como descrito acima em FUNCTIONS. Se o nome não corresponder a , o shell o procura na lista de componentes internos do shell. E se for encontrada uma correspondência, esse builtin é chamado. Se o nome não for uma função shell nem um builtin, e não contiver barras, o bash procura em cada elemento do PATH por um diretório con- mantendo um arquivo executável com esse nome.
Um './' faz sentido quando você executa um programa conhecido por você e específico, por exemplo, o seu próprio. Este programa deve estar presente no seu diretório atual. Um './' não faz sentido quando você executa um comando padrão que está em algum lugar do $ PATH. Um comando "qual comando executar" informa onde o comando executar está no $ PATH.
$ gcc hello.c -o /path/to/someplace/hello
produzirá um executável em algum local. Se esse local estiver no seu caminho, você poderá executar o arquivo. Você pode criar um script se quiser criar um rótulo para a ação "compile esse código-fonte usando o gcc e coloque um executável em algum local que esteja no seu caminho"
Eu sugiro que você crie um novo diretório chamado "testbin" ou algo desse tipo e o coloque no seu caminho para manter os diretórios de caminho existentes limpos.
./
elimina a pesquisa desnecessária de um caminho. ./
força a procurar apenas no diretório atual. Se não dermos ./
, ele procurará vários caminhos definidos no sistema /usr/bin
, como /usr/sbin/
, etc.
"./" significa que você deseja executar um arquivo no diretório atual; é um atalho para digitar todo o caminho, por exemplo:
[root@server ~]#/path/to/file/file.pl
é o mesmo que:
[root@server file]#./file.pl
no exemplo anterior, você passou pelo diretório e seus subdiretórios para o local do arquivo e usou "./" para executar o arquivo no diretório atual.
aquele antes dele " [root @ server ~] # / caminho / para / arquivo / arquivo.pl " também executará o arquivo se você tiver preguiça de "cd" no caminho para o local do arquivo.
É muito simples e tem muitos usos.
/usr/bin
. Por exemplo, o Python 2.7, o Python 2.6 está instalado, mas / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Se você estiver no caminho /usr/local/bin
e executar o Python, ele sempre executará o Python 2.7. A especificação .
assumirá o executável da pasta atual.
.
- sempre representa executar a partir do diretório atual. E ..
sempre significa executa do diretório anterior.