Karena file tersebut bukan tipe yang dapat dieksekusi yang dikenali oleh sistem, dan dengan asumsi Anda memiliki izin untuk mengeksekusi file itu, execve()panggilan sistem biasanya akan gagal dengan kesalahan ENOEXEC( bukan yang dapat dieksekusi ).
Apa yang terjadi kemudian tergantung pada fungsi aplikasi dan / atau perpustakaan yang digunakan untuk menjalankan perintah.
Itu bisa berupa shell, fungsi execlp()/ execvp()libc.
Sebagian besar aplikasi lain akan menggunakan salah satu dari mereka ketika mereka menjalankan perintah. Mereka akan memanggil shell misalnya dengan menggunakan system("command line")fungsi libc yang biasanya akan memanggil shuntuk mem-parsing baris perintah itu (jalur yang dapat ditentukan pada waktu kompilasi (seperti /bin/shvs /usr/xpg4/bin/shpada Solaris)), atau memanggil shell yang disimpan dalam $SHELLdirinya sendiri seperti videngan !perintahnya, atau xterm -e 'command line'dan banyak perintah lainnya ( su user -cakan meminta shell login pengguna alih-alih $SHELL).
Secara umum, file teks tanpa-shebang yang tidak dimulai #dianggap sebagai shskrip. Yang shitu akan bervariasi.
execlp()/ execvp(), setelah execve()kembali ENOEXECbiasanya akan memintanya sh. Untuk sistem yang memiliki lebih dari satu shkarena mereka dapat memenuhi lebih dari satu standar, yang shbiasanya akan ditentukan pada waktu kompilasi (dari aplikasi menggunakan execvp()/ execlp()dengan menghubungkan gumpalan kode yang berbeda yang merujuk ke jalur yang berbeda dengan sh). Sebagai contoh, pada Solaris, itu akan menjadi /usr/xpg4/bin/sh(standar, POSIX sh) atau /bin/sh(cangkang Bourne (cangkang kuno) pada Solaris 10 dan lebih lama, ksh93 dalam Solaris 11).
Ketika datang ke kerang, ada banyak variasi. bash, AT&T ksh, shell Bourne biasanya akan menafsirkan skrip itu sendiri (dalam proses anak kecuali execdigunakan) setelah mensimulasikan a execve(), yang tidak mengatur semua variabel yang tidak diekspor, menutup semua fds close-on-exec, menghapus semua jebakan kustom, alias, fungsi ... ( bashakan menafsirkan skrip dalam shmode). yashakan mengeksekusi sendiri (dengan mode shseperti argv[0]dalam sh) untuk menafsirkannya.
zsh, pdksh, ashKerang berbasis biasanya akan memanggil sh(jalur yang ditentukan pada saat kompilasi).
Untuk cshdan tcsh(dan shbeberapa BSD awal), jika karakter pertama file tersebut #, maka mereka akan mengeksekusi sendiri untuk menafsirkannya, dan shsebaliknya. Yang kembali ke waktu pre-peristiwa di mana cshtidak mengakui #sebagai komentar tapi tidak Bourne shell, sehingga #merupakan petunjuk bahwa ia adalah script csh.
fish(setidaknya versi 2.4.0), baru saja mengembalikan kesalahan jika execve()gagal (tidak mencoba memperlakukannya sebagai skrip).
Beberapa shell (suka bashatau AT&T ksh) pertama-tama akan mencoba untuk menentukan apakah file tersebut dimaksudkan sebagai skrip atau tidak. Jadi Anda mungkin menemukan bahwa beberapa shell akan menolak untuk mengeksekusi skrip jika ada karakter NUL di beberapa byte pertama.
Juga perhatikan bahwa jika execve()gagal dengan ENOEXEC tetapi file tersebut memang memiliki garis shebang, beberapa shell mencoba menafsirkan garis shebang itu sendiri.
Jadi beberapa contoh:
- Ketika
$SHELLadalah /bin/bash, xterm -e 'myscript with args'akan myscriptditafsirkan oleh bashdi shmodus. Sementara dengan xterm -e myscript with args, xtermakan digunakan execvp()sehingga skrip akan ditafsirkan oleh sh.
su -c myscriptpada Solaris 10 di mana rootshell login adalah /bin/shdan /bin/shshell Bourne akan myscriptditafsirkan oleh shell Bourne.
/usr/xpg4/bin/awk 'BEGIN{system("myscript")'pada Solaris 10 akan ditafsirkan oleh /usr/xpg4/bin/sh(sama untuk /usr/xpg4/bin/env myscript).
find . -prune -exec myscript {} \;pada Solaris 10 (menggunakan execvp()) akan menafsirkannya /bin/shbahkan dengan /usr/xpg4/bin/find, bahkan dalam lingkungan POSIX (bug kepatuhan).
csh -c myscriptakan menafsirkannya cshjika dimulai dengan #, dengan shsebaliknya.
Secara keseluruhan, Anda tidak dapat memastikan shell apa yang akan digunakan untuk menafsirkan skrip itu jika Anda tidak tahu bagaimana dan oleh apa itu akan dipanggil.
Dalam kasus apa pun, read -pini adalah bashhanya sintaks, jadi Anda harus memastikan bahwa skrip diinterpretasikan oleh bash(dan menghindari .shekstensi yang menyesatkan ). Entah Anda tahu jalur yang bashdapat dieksekusi dan gunakan:
#! /path/to/bash -
read -p ...
Atau Anda dapat mencoba dan mengandalkan $PATHpencarian yang bashdapat dieksekusi (dengan asumsi bashdiinstal) dengan menggunakan:
#! /usr/bin/env bash
read -p ...
( envHampir di mana-mana ditemukan di /usr/bin). Atau, Anda dapat membuatnya POSIX + Bourne kompatibel dalam hal ini Anda dapat menggunakan /bin/sh. Semua sistem akan memiliki /bin/sh. Pada sebagian besar dari mereka itu akan (sebagian besar) kompatibel dengan POSIX, tetapi Anda mungkin masih menemukan shell Bourne di sana.
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"