Comando não encontrado ao usar sudo

146

Eu tenho um script chamado foo.sh na minha pasta pessoal.

Quando navego para esta pasta e entro ./foo.sh, recebo

-bash: ./foo.sh: Permission denied.

Quando uso sudo ./foo.sh, recebo

sudo: foo.sh: command not found.

Por que isso acontece e como posso corrigi-lo?

Neko
fonte

Respostas:

151

Permissão negada

Para executar um script, o arquivo deve ter um bit de permissão executável definido .

Para entender completamente as permissões de arquivo do Linux, você pode estudar a documentação do chmodcomando. chmod , uma abreviação do modo de mudança , é o comando usado para alterar as configurações de permissão de um arquivo.

Para ler a documentação do chmod para o seu sistema local, execute man chmodou info chmodna linha de comandos. Depois de ler e entender, você deve entender a saída da execução ...

ls -l foo.sh

... que listará as permissões READ, WRITE e EXECUTE para o proprietário do arquivo, o proprietário do grupo e todos os outros que não são o proprietário do arquivo ou um membro do grupo ao qual o arquivo pertence (esse último grupo de permissões às vezes é referido como "mundo" ou "outro")

Aqui está um resumo de como solucionar o erro de permissão negada no seu caso.

$ ls -l foo.sh                    # Check file permissions of foo
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
 ^^^ | ^^^   ^^^^^^^ ^^^^^
  |  |  |       |       | 
Owner| World    |       |
     |          |    Name of
   Group        |     Group
             Name of 
              Owner 

O proprietário possui acesso de leitura e gravação rw, mas o - indica que a permissão do executável está ausente

O chmodcomando corrige isso. (O grupo e outros apenas têm permissão de leitura definida no arquivo, eles não podem gravar ou executá-lo)

$ chmod +x foo.sh               # The owner can set the executable permission on foo.sh
$ ls -l foo.sh                  # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh
   ^  ^  ^

O foo.sh agora é executável no que diz respeito ao Linux.

Usando resultados do sudo no comando não encontrado

Quando você executa um comando usando o sudo, está efetivamente executando-o como superusuário ou raiz.

O motivo pelo qual o usuário root não está encontrando seu comando é provável que a PATHvariável de ambiente para root não inclua o diretório em que foo.shestá localizado . Portanto, o comando não foi encontrado.

A variável de ambiente PATH contém uma lista de diretórios que são procurados por comandos. Cada usuário define sua própria variável PATH de acordo com suas necessidades. Para ver o que está definido para executar

env | grep ^PATH

Aqui está um exemplo de saída da execução do envcomando acima primeiro como um usuário comum e depois como usuário root usando o sudo

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

rkielty@rkielty-laptop:~$ sudo env | grep ^PATH
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

Observe que, embora semelhantes, neste caso, os diretórios contidos no PATH, o usuário não privilegiado (rkielty) e o superusuário não são os mesmos .

O diretório em que foo.shreside não está presente na variável PATH do usuário raiz, portanto, o comando não encontrou erro.

Rob Kielty
fonte
1
@ Nakilon, se você colocar isso em uma pergunta com todos os detalhes, eu devo solucionar o problema para você. A questão é provável que a Shell (o seu primeiro shell de comando ou o shell lançado pela sudo) avaliou $ PWD
Rob Kielty
6
@ Rob: Então, como se faz sudoé PATHo mesmo que o utilizador?
Tom
1
@ Rob: Eu encontrei uma maneira, entretanto, (veja minha resposta abaixo).
Tom
1
Eu gosto do jeito que você explicou! Obrigado :)
Kasparov92
1
@ Tom você pode mudar a secure_path em / etc / sudoers
DennisLi
98

As outras soluções que eu vi aqui até agora são baseadas em algumas definições de sistema, mas é possível sudousar a corrente PATH(com o envcomando) e / ou o resto do ambiente (com a -Eopção) apenas invocando-a corretamente :

sudo -E env "PATH=$PATH" <command> [arguments]

De fato, pode-se criar um pseudônimo:

alias mysudo='sudo -E env "PATH=$PATH"'

(Também é possível nomear o próprio alias sudo, substituindo o original sudo.)

Tom
fonte
3
Gosto dessa solução, Tom, porque você está trabalhando conscientemente com uma chamada de sudo diferente. É importante estar ciente de qual variável PATH está em uso o tempo todo, de qualquer maneira (e há muitas) em que está configurada.
Rob Kielty
4
Acredito que esta é a solução correta e mais padronizada para o command not foundproblema enfrentado na distribuição do Ubuntu. Obrigado cara.
Omar Tariq
você pode adicionar o alias ao seu ./bashrcpara salvá-lo entre as sessões
George
19

Verificar se há secure_path no sudo

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin

Se $PATHestiver sendo substituído, use visudoe edite/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
codemonkee
fonte
Obrigado! Isso ajudou a resolver um mistério de sudo não ser capaz de executar comandos.
Evgeny Goldin
7
  1. Verifique se você possui permissão de execução no script. iechmod +x foo.sh
  2. Verifique se a primeira linha desse script é #!/bin/shou algo parecido.
  3. Para o sudo, você está no diretório errado. verificar comsudo pwd
Ed Heal
fonte
5

Você também pode criar um link flexível para o seu script em um dos diretórios ( /usr/local/binpor exemplo) no PATH do superusuário. Ele estará disponível para o sudo.

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo

Dê uma olhada nesta resposta para ter uma idéia de qual diretório colocar o link virtual.

TrigonaMinima
fonte
2

Parece que o linux dirá "comando não encontrado", mesmo que você forneça explicitamente o caminho para o arquivo.

[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
sudo: /tmp/uid.sh: command not found
1
[veeam@jsandbox ~]$ chmod +x /tmp/uid.sh
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
0

É um erro um tanto enganador, mas provavelmente é tecnicamente correto. Um arquivo não é um comando até seu executável e, portanto, não pode ser encontrado.

Jeff MacDonald
fonte
1

Ok, esta é a minha solução: em ~ / .bash_aliases basta adicionar o seguinte:

# ADDS MY PATH WHEN SET AS ROOT
if [ $(id -u) = "0" ]; then
   export PATH=$PATH:/home/your_user/bin 
fi

Voila! Agora você pode executar seus próprios scripts com sudo ou definir como ROOT sem precisar exportar PATH = $ PATH: / home / your_user / bin toda vez.

Observe que eu preciso ser explícito ao adicionar meu PATH, pois HOME para superusuário é / root

Fernando D Jaime
fonte
1

Tente em chmod u+x foo.shvez de chmod +x foo.shse tiver problemas com os guias acima. Isso funcionou para mim quando as outras soluções não.

O que há em uma Pesquisa do Google
fonte
1

Existem excelentes respostas acima. Se, depois de experimentá-los, você ainda command not foundtentar novamente com todo o caminho do arquivo:

sudo /home/user/path/to/foo.sh
IggyM
fonte