Perintah tidak ditemukan saat menggunakan sudo

146

Saya memiliki skrip yang dipanggil foo.shdi folder rumah saya.

Ketika saya menavigasi ke folder ini, dan masuk ./foo.sh, saya dapatkan

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

Ketika saya menggunakan sudo ./foo.sh, saya mengerti

sudo: foo.sh: command not found.

Mengapa ini terjadi dan bagaimana saya bisa memperbaikinya?

Neko
sumber

Jawaban:

151

Izin ditolak

Untuk menjalankan skrip file harus memiliki set bit izin yang dapat dieksekusi .

Untuk memahami izin file Linux, Anda dapat mempelajari dokumentasi untuk chmodperintah tersebut. chmod , singkatan dari mode perubahan , adalah perintah yang digunakan untuk mengubah pengaturan izin file.

Untuk membaca dokumentasi chmod untuk sistem lokal Anda, jalankan man chmodatau info chmoddari baris perintah. Setelah membaca dan memahami Anda harus dapat memahami output dari menjalankan ...

ls -l foo.sh

... yang akan mencantumkan izin MEMBACA, MENULIS dan MENGEKSEKUSI untuk pemilik file, pemilik grup, dan semua orang lain yang bukan pemilik file atau anggota grup yang dimiliki file tersebut (grup izin terakhir kadang-kadang disebut sebagai sebagai "dunia" atau "lainnya")

Berikut ringkasan tentang cara memecahkan masalah Izin Ditolak dalam kasus Anda.

$ 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 

Pemilik telah membaca dan menulis akses rw tetapi - menunjukkan bahwa izin yang dapat dieksekusi hilang

The chmodperintah perbaikan itu. (Grup dan lainnya hanya memiliki izin baca yang ditetapkan pada file, mereka tidak dapat menulis atau menjalankannya)

$ 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
   ^  ^  ^

foo.sh sekarang dapat dieksekusi sejauh menyangkut Linux.

Menggunakan hasil sudo di Command tidak ditemukan

Saat Anda menjalankan perintah menggunakan sudo, Anda menjalankannya secara efektif sebagai superuser atau root.

Alasan bahwa pengguna root tidak menemukan perintah Anda kemungkinan PATHvariabel lingkungan untuk root tidak termasuk direktori di mana foo.shberada . Karenanya perintah tidak ditemukan.

Variabel lingkungan PATH berisi daftar direktori yang dicari perintah. Setiap pengguna menetapkan variabel PATH mereka sendiri sesuai dengan kebutuhan mereka. Untuk melihat apa yang sudah diatur untuk dijalankan

env | grep ^PATH

Berikut ini beberapa contoh keluaran dari menjalankan envperintah di atas pertama sebagai pengguna biasa dan kemudian sebagai pengguna root menggunakan 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

Perhatikan bahwa, walaupun serupa, dalam hal ini direktori yang terdapat dalam PATH pengguna yang tidak memiliki hak istimewa (rkielty) dan pengguna super tidak sama .

Direktori tempat foo.shtinggal tidak ada dalam variabel PATH dari pengguna root, karenanya perintah tidak ditemukan kesalahan.

Rob Kielty
sumber
1
@Nakilon jika Anda memasukkannya ke dalam pertanyaan dengan perincian lengkap, saya seharusnya dapat memecahkan masalah untuk Anda lebih lanjut. Masalahnya adalah kemungkinan shell mana (shell perintah pertama Anda atau shell yang diluncurkan oleh sudo) telah mengevaluasi $ PWD
Rob Kielty
6
@ Rob: jadi bagaimana satu make sudoIni PATHsama dengan pengguna?
Tom
1
@Rob: Saya telah menemukan cara untuk sementara (lihat jawaban saya di bawah).
Tom
1
Saya suka cara Anda menjelaskan! Terima kasih :)
Kasparov92
1
@ Tom, Anda dapat mengubah secure_path di / etc / sudoers
DennisLi
98

Solusi lain yang saya lihat di sini sejauh ini didasarkan pada beberapa definisi sistem, tetapi sebenarnya mungkin untuk sudomenggunakan arus PATH(dengan envperintah) dan / atau seluruh lingkungan (dengan -Eopsi) hanya dengan menjalankannya dengan benar :

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

Bahkan, seseorang dapat membuat alias dari situ:

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

(Dimungkinkan juga untuk memberi nama alias itu sendiri sudo, menggantikan yang asli sudo.)

Tom
sumber
3
Saya suka solusi ini, Tom, karena Anda secara sadar bekerja dengan doa sudo yang berbeda. Sangat penting untuk memperhatikan variabel PATH apa yang digunakan setiap saat dengan cara apa pun (dan ada banyak) yang telah diatur.
Rob Kielty
4
Saya percaya bahwa ini adalah solusi yang benar dan paling standar untuk command not foundmasalah yang dihadapi di distro Ubuntu. Terima kasih sobat.
Omar Tariq
Anda dapat menambahkan alias ke Anda ./bashrcuntuk menyimpannya di antara sesi
George
19

Periksa secure_path pada sudo

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

Jika $PATHsedang diganti, gunakan visudodan edit/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
codemonkee
sumber
Terima kasih! Itu membantu memecahkan misteri sudo yang tidak dapat menjalankan perintah.
Evgeny Goldin
7
  1. Pastikan Anda telah menjalankan izin pada skrip. yaituchmod +x foo.sh
  2. Periksa apakah baris pertama skrip itu adalah #!/bin/shatau semacamnya.
  3. Untuk sudo Anda berada di direktori yang salah. periksa dengansudo pwd
Ed Heal
sumber
5

Anda juga dapat membuat tautan lunak ke skrip Anda di salah satu direktori ( /usr/local/binmisalnya) di PATH pengguna super. Kemudian akan tersedia untuk sudo.

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

Lihat jawaban ini untuk mengetahui direktori mana yang akan dijadikan tautan lunak.

TrigonaMinima
sumber
2

Tampaknya linux akan mengatakan "command not found" bahkan jika Anda secara eksplisit memberikan path ke file tersebut.

[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

Ini adalah kesalahan yang agak menyesatkan, namun mungkin secara teknis benar. File bukan perintah sampai file tersebut dapat dieksekusi, dan karenanya tidak dapat ditemukan.

Jeff MacDonald
sumber
1

Ok ini solusi saya: di ~ / .bash_aliases cukup tambahkan yang berikut ini:

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

Voila! Sekarang Anda dapat menjalankan skrip Anda sendiri dengan sudo atau ditetapkan sebagai ROOT tanpa harus melakukan ekspor PATH = $ PATH: / home / your_user / bin setiap saat.

Perhatikan bahwa saya harus eksplisit ketika menambahkan PATH saya karena HOME untuk superuser adalah / root

Fernando D Jaime
sumber
1

Coba chmod u+x foo.shalih-alih chmod +x foo.shjika Anda mengalami masalah dengan panduan di atas. Ini bekerja untuk saya ketika solusi lain tidak.

Apa yang ada di Pencarian Google
sumber
1

Ada jawaban bagus di atas. Jika, setelah mencobanya, Anda masih dapat command not foundmencoba lagi dengan seluruh path file:

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