.sh menentukan ekstensi?

12

Mengapa beberapa sistem akan menjalankan .shfile hanya dengan menentukan nama file tanpa ekstensi dan yang lain memerlukan ekstensi nama plus? Dalam kasus saya, saya mencoba menulis serangkaian perintah mengikuti instruksi ini .

Saya menetapkan ekstensi sekarang tetapi bisa menjalankan perintah tanpa .shakan lebih disukai.

Philip Kirkbride
sumber
4
Menggunakan .shsebagai ekstensi dalam banyak keadaan dianggap praktik buruk: Ini bertentangan dengan bagaimana perintah lain dinamai (Anda tidak menjalankan ls.elf), itu sering menyesatkan (jika Anda foo.shmulai dengan #!/bin/bash, maka menjalankan sh foo.shakan menjalankannya dengan juru bahasa yang berbeda dari yang dibangun untuk ), dan jika Anda menulis ulang foo.shmenjadi program Python, menggunakan ekstensi itu berarti Anda harus memilih antara menyimpan nama yang sekarang menyesatkan dan menulis ulang setiap program yang menyebutnya.
Charles Duffy
2
... di mana itu adalah praktik terbaik adalah pustaka shell, bukan perintah dengan +xset - di mana foo.shpustaka yang dapat bersumber ke setiap shell POSIX, foo.bashdapat bersumber ke bash, foo.kshke ksh, dll.
Charles Duffy

Jawaban:

39

Anda bingung. The .shekstensi hanya petunjuk untuk manusia, dan sama sekali tidak berpengaruh pada bagaimana sistem menangani file. Unix / Linux tidak membuat Secrets.pdf.exekesalahan Windows .

Inilah yang terjadi ketika Anda mengetik foo:

  1. Pengalihan untuk STDIN, STDOUTdan STDERRdiatur.

  2. Shell memeriksa tabel hash internal untuk melihat apakah ia sudah mengetahui $PATHentri foo. Jika tidak ada, shell mencari direktori di $PATH, mencari file bernama fooyang memiliki bit Execute diatur dalam izin file itu. fooKemenangan pertama .

  3. Jika dua byte pertama dari file fooyang #!, string berikutnya adalah nama seorang penerjemah untuk menjalankan. Dengan demikian #!/bin/bashmemperkenalkan skrip Bash, #!/usr/bin/perlmemperkenalkan skrip Perl, dll.

  4. Jika file dimulai dengan \177ELF, itu adalah biner yang dapat dieksekusi, dan ld.somemulainya.

Baca man execvedan man ld.sountuk penjelasan yang lebih rinci.

waltinator
sumber
15
Ya, di Linux Anda dapat mengklik dua kali Secrets.pdf tanpa petunjuk dari nama bahwa itu sebenarnya dapat dieksekusi;)
OrangeDog
1
@OrangeDog Saya tahu Anda bercanda, tapi saya merasa seperti saya harus menunjukkan bahwa bit executable ( chmod +x) cukup banyak menyelesaikan ini, kan?
wchargin
3
@WChargin Itu tergantung seberapa baik filesystem Anda (mis. Share jaringan yang dipasang atau partisi NTFS mungkin secara optimis mengatur xbit pada semuanya) dan dari mana file itu berasal (proses apa pun dengan kontrol direktori bisa diakali untuk menetapkan izin) . Jadi, ini meredakannya , tapi saya tidak akan mengatakan itu menyelesaikannya .
IMSoP
2
@WChargin, belum, tapi saya pikir maksudnya bahwa biasanya manajer file tidak menunjukkan bit executable, yaitu tidak ada "petunjuk kepada manusia" seperti ekstensi.
Paul Draper
1
Saya tidak pernah salah mengklik Secrets.pdf.exekarena saya selalu menonaktifkan hide file extensionfitur bodoh
phuclv
12

Poin utamanya adalah: Ekstensi tidak relevan dalam sistem sistem mirip Unix apa pun. Nama file hanya nama dan tidak berpengaruh pada apakah skrip atau kompilasi yang dapat dieksekusi dapat dijalankan . Seorang programmer dapat menambahkan .shekstensi untuk menunjuk bahwa suatu file adalah skrip shell, atau .pyuntuk skrip python, tetapi tidak seperti Windows, unix mana pun tidak peduli dengan penamaan, ia peduli dengan izin.

Yang penting adalah izin yang dapat dieksekusi diberikan ke file. Yang bisa Anda tanyakan

ls -l /path/to/file

Menjalankan executable

Untuk menjalankan skrip umumnya ada beberapa cara.

  • Jika direktori Anda saat ini sama dengan skrip, dan skrip memiliki izin yang dapat dieksekusi, Anda dapat menjalankannya seperti itu ./my_script_name. Direktori .berarti saat ini.
  • Jika direktori Anda saat ini berbeda dan skrip memiliki izin yang dapat dieksekusi, Anda dapat menjalankannya dengan menentukan jalur lengkap: /home/user/bin/my_script_name

(Dua metode di atas bergantung pada memiliki izin yang dapat dieksekusi ditetapkan; apakah file merupakan bagian dari $PATHvariabel atau tidak tidak relevan. Kehadiran #!baris juga penting; tanpanya, skrip akan dieksekusi oleh shell saat ini yang telah Anda buka. Jika saya memiliki cshskrip tanpa garis itu, dan coba jalankan dengan bash ./my_script.csh, itu akan gagal)

  • Jika skrip Anda berada di direktori yang merupakan bagian dari $PATHvariabel Anda, Anda dapat menjalankannya hanya dengan memanggil nama. Anda dapat memanggil chmodperintah di baris perintah hanya dengan mengetik namanya karena ada di /binfolder. /binselalu menjadi bagian dari $PATHvariabel. Dalam hal ini izin yang dapat dieksekusi dan lokasi masalah skrip
  • Menentukan penerjemah sebagai perintah dan skrip sebagai argumen. Script cara itu akan berfungsi sebagai file input untuk penerjemah.
  • Sumber file. The . filename.shatau source filename.shakan membuat script diperlakukan seolah-olah itu adalah input keyboard, yaitu seolah-olah itu diketik ke baris perintah langsung. Dalam hal ini, izin dan lokasi yang dapat dieksekusi tidak masalah

Contohnya

Contoh # 1, berjalan dengan interpreter, untuk mengeksekusi izin

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

Contoh # 2, berjalan dengan ./set izin yang dapat dieksekusi, set baris shebang.

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

Contoh # 3, berjalan tanpa set garis shebang (gagal, karena bash tidak dapat membaca skrip python; tidak ada garis shebang mengasumsikan shell saat ini sebagai interpreter)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

Contoh # 4, menjalankan skrip yang memiliki izin yang dapat dieksekusi mengatur folder formulir yang merupakan bagian dari $PATHvariabel

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

Contoh # 5, menghapus ekstensi, masih berjalan karena ekstensi tidak penting, tetapi memiliki izin dan merupakan bagian dari $PATH:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c
Sergiy Kolodyazhnyy
sumber
Saya menjalankan perintah dan saya mendapatkan '-rwxr-x ---'. Apa yang saya ingin nilai dibaca dan bagaimana saya bisa mengubahnya?
Philip Kirkbride
Atau Anda mengatakan saya harus mengganti nama 'nama file.sh' menjadi 'nama file'?
Philip Kirkbride
1
@PhilipKirkbride Name tidak relevan. Bagaimana Anda menjalankan perintah Anda? Dimana itu ? Apakah direktori itu di bagian dari Anda PATH?
Sergiy Kolodyazhnyy
@ PhilipKirkbride Biarkan saya memperluas jawaban saya sebentar lagi untuk membuatnya lebih jelas.
Sergiy Kolodyazhnyy
1
Lihatlah man chmoduntuk melihat cara mengatur izin
Nick Mertin
6

Penjelasan yang bagus sudah ada di sini. Saya hanya ingin menambahkan bahwa idealnya Anda tidak harus menggunakan ekstensi file untuk executable.

Biasanya Anda perlu mencapai sesuatu yang relatif mudah dan Anda mulai dengan skrip shell kecil. Seiring waktu Anda mulai menambahkan lebih banyak fungsionalitas ke skrip Anda, sampai tiba saatnya menjadi tidak dapat dipelihara atau Anda memerlukan beberapa fungsionalitas yang tidak dapat Anda capai dengan mudah dengan skrip shell dan berpikir tentang menulis ulang skrip shell ini dalam bahasa lain (python , perl, ...?).

Menulis ulang dari awal biasanya dianggap sebagai kesalahan, tetapi untuk skrip mungkin masuk akal karena biasanya skrip itu tidak terlalu besar atau memiliki banyak fungsi. Tetapi mari kita asumsikan bahwa layak untuk menulis ulang dari awal dalam beberapa bahasa lain, mempertahankan fungsi dan params / flag dari skrip shell awal.

Pengguna skrip ini tidak perlu menyadari perubahan bahasa ini, mereka akan terus menjalankan perintah yang sama dan akan terus bekerja.

Jika skrip Anda dinamai do-something.sh, skrip ini dapat terus berlanjut do-something.sh, tetapi sekarang skrip tersebut ditulis dengan python (misalnya), dan karenanya petunjuk awal Anda sekarang benar-benar menyesatkan.

Carlos Campderrós
sumber
4

Untuk menjalankan file tanpa ekstensi yang biasanya Anda tidak perlu lakukan banyak, pastikan Anda memiliki (dalam kasus skrip bash) baris shebang yang tepat di baris pertama:

#!/bin/bash

maka Anda juga perlu membuat file yang dapat dieksekusi oleh sistem

chmod 755 yourfilename

Ini sama dengan menggunakan chmod +x yourfilenameangka-angka yang mudah dijelaskan.

Ini adalah tiga kali lipat dari jumlah oktal yang ditambahkan, angka pertama adalah singkatan dari pengguna, yang kedua untuk grup, dan yang ketiga untuk yang lain, lebih banyak tentang yang dapat Anda temukan di sini .

Dan jika Anda berada di direktori yang sama dengan skrip Anda jangan lupa gunakan ./seperti ini:

./yourfilename
Videonauth
sumber
Sudah mencoba ini. Sayangnya tidak ada perbedaan dari hasil asli.
Philip Kirkbride
@ PhilipKirkbride melihat jawaban saya yang telah direvisi, ini mungkin akan memberikan lebih banyak cahaya.
Videonauth
0

Sufiks .sh sebenarnya bisa menghalangi, karena untuk menjalankannya Anda harus mengetikkan myscript.sh daripada hanya myscript yang tidak akan berfungsi. Lebih baik menyebutnya "myscript" tanpa akhiran .sh, dan cepat menggunakan perintah "file" akan memberi tahu Anda apakah itu biner yang dapat dieksekusi (format ELF di linux) atau skrip shell, atau skrip jenis apa pun.

QDOS (Sistem Operasi Cepat dan Kotor, yang kemudian diubah namanya menjadi "DOS" oleh IBM setelah mirosoft membajaknya dan menjualnya secara ilegal kepada mereka) dan penipuan murah lainnya dari CP / M, termasuk windows, campur semua ini karena pada sistem itu tidak ada hal seperti mengeksekusi izin pada file. Ini telah menghasilkan banyak masalah keamanan dalam 30-40 tahun terakhir. Sebenarnya hanya beberapa menit yang lalu saya baru saja mendapat beberapa junk mail dengan file zip terperangkap booby diubah namanya menjadi MYPICTURE.JPG.zip :)

delt
sumber