Is ./ (ponto barra) um comando?

16

Núcleo da questão:

A questão surgiu enquanto eu não pude instalar o software, então estou genuinamente perguntando sobre ./ porque eu não sabia sobre isso e a saída "comando não encontrado" estava me confundindo sobre o que realmente era o comando.

Contexto:

Gostaria de instalar o arquivo truecrypt-7.2-setup-x86 .

As instruções dizem para usar o comando:

sudo ./truecrypt-7.2-setup-x86

Mas a saída é:

sudo: ./truecrypt-7.2-setup-x86: command not found

UPDATE: para completar, no teste eu estava na pasta de arquivos mas ainda não tinha feito o arquivo executável (chmod + x).

    
por ubuntubu 27.10.2017 / 14:56

3 respostas

24

./ não é um comando. O comando é ./truecrypt-7.2-setup-x86 .

Seu shell e programas como sudo tratarão um comando como um nome do caminho quando ele contiver pelo menos um caractere / . Como . representa o diretório em que você está atualmente, ./truecrypt-7.2-setup-x86 nomeia o arquivo truecrypt-7.2-setup-x86 no diretório atual. Se não houver tal arquivo, ou houver, mas o arquivo não puder ser executado, você receberá uma mensagem de erro.

Quando um comando não contém uma barra, os diretórios listados em $PATH são pesquisados. , como Sergiy Kolodyazhnyy diz . O diretório atual não é pesquisado automaticamente - e é não recomendado colocar . em $PATH . Dessa forma, você não executa acidentalmente as coisas que não esperava executar porque passou a ter cd d em um diretório que as contenha.

Escrevendo ./ antes do nome de um executável no diretório atual o caminho comum para executá-lo, mas isso não é realmente uma sintaxe especial. Por exemplo, se você estragou o $PATH e precisou executar um comando como ls , pode escrever /bin/ls . Nenhum . é necessário nesse caso ou em geral; o que é necessário é um / em algum lugar no caminho para significar que você quer dizer que é um nome de caminho.

Como . é sempre o diretório atual e / é apenas o separador de diretório, a primeira coisa a fazer é verificar se o arquivo que você nomeou realmente existe no diretório atual. (Em caso afirmativo, verifique suas permissões , como Charles Green explica . Mas se você extraiu o arquivo de um arquivo, então normalmente já terá permissões executáveis se for destinado a ser executado.)

    
por Eliah Kagan 27.10.2017 / 16:15
21

A parte ./ do comando diz "Procure no diretório atual e execute o comando 'truecrypt-7.2-setup-x86' daqui". Você precisa executar este comando no diretório onde você descompactou o arquivo.

Isso pode ser testado: Na mesma janela de terminal em que você está tentando o comando, digite o comando ls -l true* - se o arquivo estiver presente no diretório de trabalho atual, então uma listagem mostrando o arquivo (e um monte de informação) será exibida.

Como Zanna observou nos comentários, seu arquivo pode não ter permissões de execução - isso pode ser corrigido facilmente. Como caso de teste, meu diretório mostra

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

e o arquivo "rFullBack" lista '-rw-' como minha permissão para ler e gravar o arquivo. Eu posso executar o comando chmod +x rFullBack e a lista de diretórios muda para

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

As minhas permissões agora são '-rwx', indicando que posso executar o arquivo.

Em suma, se o arquivo existir no seu diretório

execute o comando

chmod +x ./truecrypt-7.2-setup-x86

e depois o comando

sudo ./truecrypt-7.2-setup-x86
    
por Charles Green 27.10.2017 / 15:24
8

Como os comandos de chamada no shell funcionam

Não, não é um comando. A maneira como os shells funcionam é quando você digita uma linha de texto, a primeira palavra será tratada como comando e, se o comando não for um dos comandos internos do shell, o shell examinará todos os locais listados em PATH variável de ambiente.

O que acontece se o comando que você deseja executar estiver no mesmo diretório que você localizou atualmente, mas esse diretório não estiver na lista de diretórios PATH ? É aí que você precisa usar ./ . É exatamente o mesmo que fazer /bin/bash - você está dizendo ao shell onde o comando desejado está localizado, um caminho completo para ele. E no caso de ./ você está dizendo para "procurar neste diretório". A parte mais importante é que você precisa estar no mesmo diretório em que o arquivo está localizado.

É claro que, para realmente executar um executável, ele deve ter o bit executável definido, então você precisará chmod +x ./my_file .

Então, os passos importantes:

  1. cd onde você salvou o arquivo; se estiver em ~/Downloads , então cd ~/Downloads
  2. Execute chmod +x ./truecrypt-7.2-setup-x86 , isso significa "criar arquivo-verdade-7.2-setup-x86 que está no diretório deste executável"
  3. E agora sudo ./truecrypt-7.2-setup-x86

Observe que o uso de ./ não é um comportamento aleatório, mas, na verdade, é um padrão, especificado por Padrão de Interface do Sistema Operacional Portátil (também conhecido como POSIX) , veja especificamente a seção "Pesquisa e Execução de Comando".

Reproduzindo o erro

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

OBSERVAÇÃO : a mensagem de erro dada por sudo é obviamente enganosa, então isso é algo que deve ser mantido em mente; no entanto, por favor, note que este não foi o núcleo da questão que o OP está pedindo.

Documentação e referências

Do manual bash 4.3, seção "EXECUÇÃO DO COMANDO":

  

Se o nome não for nem uma função do shell nem um builtin e não contiver barras, o bash pesquisará cada elemento do PATH em um diretório que contenha um arquivo executável com esse nome.

De Por que você precisa de ./ (ponto-barra) antes do nome do script para executá-lo bash? :

  

Funciona com ./ porque POSIX especifica que um nome de comando que contém um / será usado como um nome de arquivo diretamente, suprimindo uma pesquisa em $ PATH. Você poderia ter usado o caminho completo para o mesmo efeito, mas ./ é mais curto e mais fácil de escrever.

    
por Sergiy Kolodyazhnyy 27.10.2017 / 15:35