Apakah ./ (dot slash) sebuah perintah?

16

Inti dari pertanyaan:

Pertanyaan muncul ketika saya tidak dapat menginstal perangkat lunak, jadi saya benar-benar bertanya tentang. / Karena saya tidak tahu tentang hal itu dan output "perintah tidak ditemukan" membingungkan saya tentang apa sebenarnya perintah itu.

Konteks:

Saya ingin menginstal file truecrypt-7.2-setup-x86.

Instruksi mengatakan untuk menggunakan perintah:

sudo ./truecrypt-7.2-setup-x86

Tetapi hasilnya adalah:

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

UPDATE: untuk kelengkapan, dalam pengujian saya berada di folder file tetapi belum membuat file dapat dieksekusi (chmod + x).

ubuntubu
sumber
1
Bagian ./dari perintah mengatakan "Lihat di direktori saat ini, dan jalankan perintah 'truecrypt-7.2-setup-x86' dari sini". Anda perlu menjalankan perintah ini dari direktori tempat Anda membuka file.
Charles Green
2
@Videonauth - Tidak juga, secara pribadi saya tidak berpikir itu menimbulkan tingkat jawaban.
Charles Green
1
@Zanna Saya menguji skrip tanpa mengeksekusi izin, dan kesalahan yang dilemparkan adalah kesalahan izin yang hilang, bukan perintah yang tidak ditemukan.
Charles Green
2
@ubuntubu OK, sangat baik, Anda sudah pindah ke direktori - bagus. Komentar kecil pada hasil edit. Perintahnya seharusnya chmod +x, chmod -xsebaliknya - menghapus izin yang dapat dieksekusi
Sergiy Kolodyazhnyy
4
Judul pertanyaan sangat berbeda dari badan; mungkin itu harus diperbaiki?
David Z

Jawaban:

24

./bukan perintah. Perintahnya adalah ./truecrypt-7.2-setup-x86.

Shell dan program-program seperti Anda sudoakan memperlakukan perintah sebagai pathname ketika mengandung setidaknya satu /karakter. Karena .mewakili direktori apa pun Anda saat ini, ./truecrypt-7.2-setup-x86nama file truecrypt-7.2-setup-x86di direktori saat ini. Jika tidak ada file seperti itu, atau ada tetapi file tidak dapat dijalankan, maka Anda akan mendapatkan pesan kesalahan.

Ketika sebuah perintah tidak mengandung garis miring, direktori yang terdaftar di $PATHmencarinya, seperti kata Sergiy Kolodyazhnyy . Direktori saat ini tidak secara otomatis mencari - dan itu tidak dianjurkan untuk menempatkan .di $PATH. Dengan begitu, Anda tidak secara tidak sengaja menjalankan hal-hal yang tidak Anda harapkan untuk dijalankan karena Anda kebetulan memiliki cdd ke direktori yang memuatnya.

Menulis di ./depan nama yang dapat dieksekusi di direktori saat ini adalah cara umum untuk menjalankannya, tetapi ini sebenarnya bukan sintaks khusus. Misalnya, jika Anda mengacaukan $PATHperintah Anda dan Anda perlu menjalankan perintah ls, Anda bisa menulis /bin/ls. Tidak .diperlukan dalam kasus itu atau secara umum; yang dibutuhkan adalah suatu /tempat di pathname untuk menandakan bahwa maksud Anda itu adalah pathname.

Karena .selalu direktori saat ini dan /hanya pemisah direktori, hal pertama yang harus dilakukan adalah memeriksa apakah file yang Anda beri nama benar-benar ada di direktori saat ini. (Jika ya, maka periksa izinnya , seperti dijelaskan Charles Green . Tetapi jika Anda mengekstrak file dari arsip, maka biasanya sudah memiliki izin yang dapat dieksekusi jika dimaksudkan untuk dijalankan.)

Eliah Kagan
sumber
21

Bagian ./ dari perintah mengatakan "Lihat di direktori saat ini, dan jalankan perintah 'truecrypt-7.2-setup-x86' dari sini". Anda perlu menjalankan perintah ini dari direktori tempat Anda membuka file.

Ini dapat diuji: Di ​​jendela terminal yang sama di mana Anda mencoba perintah, masukkan perintah ls -l true*- jika file ada di direktori kerja saat ini, maka daftar yang menunjukkan file (dan banyak informasi tambahan) akan ditampilkan.

Seperti yang Zanna catat dalam komentar, file Anda mungkin tidak memiliki izin untuk dieksekusi - ini dapat diperbaiki dengan mudah. Sebagai kasus uji, direktori saya menunjukkan

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

dan file "rFullBack" mencantumkan '-rw-' sebagai izin saya, untuk membaca dan menulis file. Saya dapat menjalankan perintah chmod +x rFullBackdan perubahan direktori listing ke

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

Di sana izin saya sekarang '-rwx', menunjukkan saya dapat menjalankan file.


Singkatnya, jika file tersebut ada di direktori Anda

jalankan perintah

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

dan kemudian perintah

sudo ./truecrypt-7.2-setup-x86
Charles Green
sumber
1
Tidak terlalu. Ini daftar rw-sebagai izin Anda - -sebelum untuk set [gu] id dan bit lengket.
Duncan X Simpson
@DuncanXSimpson Terima kasih - Saya memperbarui sedikit deskripsi izin, tapi saya akan mengabaikan bit setguid dan sticky untuk jawaban ini!
Charles Green
8

Bagaimana cara memanggil perintah di shell bekerja

Tidak, ini bukan perintah. Cara kerja shell adalah ketika Anda mengetikkan satu baris teks, kata pertama akan diperlakukan sebagai perintah, dan jika perintah tersebut bukan salah satu dari shell yang ada di dalam maka shell akan melihat semua lokasi yang terdaftar dalam PATH variabel lingkungan .

Apa yang terjadi jika ketika perintah yang ingin Anda jalankan berada di direktori yang sama dengan Anda saat ini tetapi direktori itu tidak ada dalam daftar PATHdirektori? Saat itulah Anda perlu menggunakan ./. Ini dengan cara yang persis sama dengan melakukan /bin/bash- Anda memberi tahu shell di mana perintah yang Anda inginkan berada, jalur penuh untuk itu. Dan dalam kasus ./ Anda mengatakan untuk shell "lihat di direktori ini". Jadi bagian yang penting adalah Anda harus berada di direktori yang sama di mana file tersebut berada.

Tentu saja, untuk benar-benar menjalankan executable, ia harus memiliki bit set yang dapat dieksekusi, jadi Anda harus melakukannya chmod +x ./my_file.

Jadi langkah-langkah penting:

  1. cd tempat Anda menyimpan file; jika ada di ~/Downloads, makacd ~/Downloads
  2. Jalankan chmod +x ./truecrypt-7.2-setup-x86, ini mengatakan "buat file truecrypt-7.2-setup-x86 yang ada di direktori ini dapat dieksekusi"
  3. Dan sekarang lakukan sudo ./truecrypt-7.2-setup-x86

Perhatikan bahwa penggunaan ./bukan perilaku acak, tetapi sebenarnya merupakan standar, yang ditentukan oleh standar Antarmuka Sistem Pengoperasian Portabel (alias POSIX) , secara khusus lihat bagian "Perintah Pencarian dan Eksekusi".

Mereproduksi kesalahan

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

CATATAN : pesan kesalahan yang diberikan sudojelas menyesatkan sehingga ini adalah sesuatu yang harus diingat; namun harap dicatat bahwa ini bukan inti dari pertanyaan yang diajukan OP.

Dokumentasi dan referensi

Dari bash4.3 manual, bagian "COMMAND EXECUTION":

Jika namanya bukan fungsi shell atau builtin, dan tidak mengandung garis miring, bash mencari setiap elemen PATH untuk direktori yang berisi file yang dapat dieksekusi dengan nama itu.

Dari Mengapa Anda perlu ./ (dot-slash) sebelum nama skrip untuk menjalankannya di bash? :

Ini berfungsi dengan ./ karena POSIX menentukan bahwa nama perintah yang mengandung / akan digunakan sebagai nama file secara langsung, menekan pencarian di $ PATH. Anda bisa menggunakan path lengkap untuk efek yang sama persis, tetapi ./ lebih pendek dan lebih mudah untuk ditulis.

Sergiy Kolodyazhnyy
sumber
Sebenarnya sudooutput menyesatkan. Jika Anda mencoba yang sama tanpa sudo, Anda akan mendapatkan kesalahan lain dari bash: Permission denied. Dan memang seharusnya begitu, karena Anda belum memberikan izin skrip untuk mengeksekusi (via chmod +x).
Ruslan
@Ruslan fakta bahwa sudooutput menyesatkan memang benar, tapi itulah kesalahan yang muncul. Itu mungkin sesuatu untuk dilaporkan kepada pengembang dan biarkan mereka memperbaikinya. Namun ini bukan inti dari diskusi - kami perlu menetapkan apa yang telah dilakukan OP untuk menghasilkan kesalahan seperti itu, dan membimbing mereka ke jalan yang benar. Apakah itu menyesatkan - itu bukan masalah di sini.
Sergiy Kolodyazhnyy
Dengan cara lain, ini tidak persis sama dengan menggunakan /bin/bash: Ini tidak memungkinkan Anda untuk mengeksekusi skrip di mana Anda tidak memiliki izin eksekusi. Ketika Anda membuka pengantar nama skrip /bin/bash, fakta yang /bin/bashdapat dieksekusi adalah yang terpenting, karena itu adalah perintah yang dieksekusi. Ketika Anda tidak melakukan itu, skrip itu sendiri sedang dieksekusi, yang pada gilirannya mengarah ke shell Anda saat ini atau apa pun yang ada di #!baris teratas yang dipanggil
Monty Harder
@MontyHarder /bin/bashhanyalah contoh di sini. Fakta bahwa kita sedang menelepon /bin/bashdan ./script.sh dengan menentukan jalan menuju hal yang dieksekusi - itu sama. Prakata naskah dengan bash script.shatau /bin/bash script.shyang sama sekali topik yang berbeda, di mana Anda menjalankan executable dan lulus script untuk itu sebagai argumen - yang dengan cara dapat pecah jika sintaks ditulis untuk sesuatu yang lain dari shell Anda panggil sedang, mengatakan csh. /bin/bashdieksekusi baik-baik saja, tetapi kenyataannya adalah bahwa Anda masih menentukan path lengkap untuk itu.
Sergiy Kolodyazhnyy
2
@SergiyKolodyazhnyy prakata nama skrip dengan /bin/bashatau bahkan hanya bashmerupakan juga cara yang umum untuk mengatasi kekurangan hak akses executable pada script. Menentukan jalur skrip lengkap tidak menyelesaikan masalah itu. Jadi /bin/bashadalah contoh yang sangat buruk dalam kasus khusus ini.
Monty Harder