./ (barra) é um comando?

16

Núcleo da pergunta:

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

Contexto:

Eu 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 do arquivo, mas ainda não o havia executável (chmod + x).

ubuntubu
fonte
11
A ./parte do comando está dizendo "Procure no diretório atual e execute o comando 'truecrypt-7.2-setup-x86' daqui". Você precisa executar este comando no diretório em que descompactou o arquivo.
Charles Green
2
@Videonauth - Não realmente, pessoalmente, não acho que isso chegue ao nível de uma resposta.
Charles Green
11
@ Zanna Eu testei um script sem executar permissões, e o erro gerado foi um erro de permissão ausente, não um comando não encontrado.
Charles Green
2
@ubuntubu OK, muito bem, você se mudou para o diretório - bom. Pequeno comentário sobre a edição, no entanto. O comando deve ser chmod +x, o chmod -xé o oposto - ele remove as permissões executáveis
Sergiy Kolodyazhnyy
4
O título da pergunta é bem diferente do corpo; talvez isso deva ser consertado?
David Z

Respostas:

24

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

Seu shell e programas como sudotratarão um comando como um nome de caminho quando ele contém pelo menos um /caractere. Como .representa o diretório em que você está atualmente, ./truecrypt-7.2-setup-x86nomeia o arquivo truecrypt-7.2-setup-x86no diretório atual. Se esse arquivo não existir ou 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 $PATHsão pesquisados, como diz Sergiy Kolodyazhnyy . O diretório atual não é automaticamente procurou - e é não recomendado para colocar .em $PATH. Dessa forma, você não executa acidentalmente coisas que não esperava executar porque tinha cdd em um diretório que as contém.

Escrever ./antes do nome de um executável no diretório atual é a maneira comum de executá-lo, mas essa não é realmente uma sintaxe especial. Por exemplo, se você estragou tudo $PATHe precisava executar um comando como ls, poderia escrever /bin/ls. Não .é necessário nesse caso ou em geral; o que é necessário é um /lugar no nome do caminho para indicar que você quer dizer que é um nome de caminho.

Como .sempre é o diretório atual e /é apenas o separador de diretórios, a primeira coisa a fazer é verificar se o arquivo que você nomeou realmente existe no diretório atual. (Se isso acontecer, verifique suas permissões , como Charles Green explica . Mas se você extraiu o arquivo de um arquivo, ele normalmente já terá permissões executáveis, se pretender ser executado.)

Eliah Kagan
fonte
21

A parte ./ do comando está dizendo "Procure no diretório atual e execute o comando 'truecrypt-7.2-setup-x86' daqui". Você precisa executar este comando no diretório em que descompactou o arquivo.

Isso pode ser testado: Na mesma janela do terminal em que você está tentando o comando, insira o comando ls -l true*- se o arquivo estiver presente no diretório de trabalho atual, será exibida uma lista mostrando o arquivo (e várias informações adicionais).

Como Zanna observou nos comentários, seu arquivo pode não ter permissões de execução - isso pode ser corrigido facilmente. Como um 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 rFullBacke 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$

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


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

execute o comando

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

e então o comando

sudo ./truecrypt-7.2-setup-x86
Charles Green
fonte
11
Nem tanto. Ele lista rw-como sua permissão - o -antes é para set [gu] id e bits fixos.
Duncan X Simpson
@DuncanXSimpson Obrigado - atualizei um pouco a descrição das permissões, mas vou ignorar os bits setguid e sticky desta resposta!
Charles Green
8

Como funciona a chamada de comandos no shell

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 shell integrados, o shell procurará todos os locais listados na PATH variável de ambiente .

O que acontece se o comando que você deseja executar estiver no mesmo diretório em que você está localizado atualmente, mas esse diretório não estiver na lista de PATHdiretórios? É quando você precisa usar ./. É exatamente o mesmo que fazer /bin/bash- você está dizendo ao shell onde estava o comando desejado, um caminho completo para ele. E, no caso de ./, você está dizendo "shell 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 um conjunto de bits executável, então você precisará chmod +x ./my_file.

Portanto, as etapas importantes:

  1. cd onde você salvou o arquivo; se estiver dentro ~/Downloads, entãocd ~/Downloads
  2. Execute chmod +x ./truecrypt-7.2-setup-x86, isto diz "torne o arquivo truecrypt-7.2-setup-x86 que está neste diretório executável"
  3. E agora faça sudo ./truecrypt-7.2-setup-x86

Observe que o uso de ./não é um comportamento aleatório, mas na verdade é um padrão, especificado pelo padrão da Interface do sistema operacional portátil (também conhecido como POSIX) , consulte especificamente a seção "Pesquisa e execução de comandos".

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

NOTA : a mensagem de erro dada por sudoé obviamente enganosa, portanto, isso deve ser lembrado; no entanto, observe que esse não era o cerne da pergunta que o OP está fazendo.

Documentação e referências

Do bashmanual 4.3, seção "COMMAND EXECUTION":

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

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

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

Sergiy Kolodyazhnyy
fonte
Na verdade, a sudosaída é enganosa. Se você tentar o mesmo sem sudo, você vai ter outro erro de bash: Permission denied. E com razão, já que você não deu permissão ao script para executar (via chmod +x).
Ruslan
@Ruslan o fato de que a sudosaída é enganosa é verdade, mas esse é o erro que aparece. Isso pode ser algo a relatar aos desenvolvedores e deixá-los consertá-lo. Entretanto, esse não é o cerne da discussão - precisamos estabelecer o que o OP fez para produzir esse erro e orientá-los para o caminho certo. Seja enganoso ou não - esse não é o problema aqui.
Sergiy Kolodyazhnyy 27/10/19
De outra maneira, não é exatamente o mesmo que usar /bin/bash: não permite executar um script no qual você não tem permissão de execução. Quando você antecede o nome do script /bin/bash, o fato de /bin/bashser executável é tudo o que importa, pois é o comando que está sendo executado. Quando você não fizer isso, o próprio script está sendo executado, o que por sua vez leva a quer seu shell atual ou o que está no topo #!de linha que está sendo chamado
Monty Mais difícil
@MontyHarder /bin/bashé apenas um exemplo aqui. O fato de estarmos chamando /bin/bashe ./script.sh especificando o caminho para a coisa sendo executada - é o mesmo. Prefácio de um script com bash script.shou /bin/bash script.shé um tópico totalmente diferente, onde você executa um executável e o passa como argumento - que pode ser interrompido se a sintaxe for escrita para algo diferente do shell que você está chamando, digamos csh. /bin/bashé executável, mas o fato é que você ainda está especificando o caminho completo para ele.
Sergiy Kolodyazhnyy 27/10
2
@SergiyKolodyazhnyy Prefixar um nome de script com /bin/bashou mesmo apenas tambémbash é uma maneira comum de resolver a falta de permissões executáveis ​​no script. A especificação do caminho completo do script não resolve esse problema. Portanto, é um exemplo particularmente ruim neste caso específico. /bin/bash
Monty Mais difícil