Ide dasarnya adalah bahwa VAR=VALUE some-commandset VARuntuk VALUEuntuk pelaksanaan some-commandketika some-commandadalah perintah eksternal, dan tidak mendapatkan lebih mewah dari itu. Jika Anda menggabungkan intuisi ini dengan beberapa pengetahuan tentang cara kerja shell, Anda harus menemukan jawaban yang tepat dalam banyak kasus. Referensi POSIX adalah "Perintah Sederhana" di bab "Bahasa Perintah Shell" .
Jika some-commandmerupakan perintah eksternal , VAR=VALUE some-commandsama dengan env VAR=VALUE some-command. VARdiekspor di lingkungan some-command, dan nilainya (atau kurangnya nilai) di shell tidak berubah.
Jika some-commandadalah fungsi , maka VAR=VALUE some-commandsetara dengan VAR=VALUE; some-command, yaitu sisa-sisa tugas di tempat setelah fungsi telah kembali, dan variabel tersebut tidak diekspor ke lingkungan. Alasan untuk itu berkaitan dengan desain shell Bourne (dan kemudian dengan kompatibilitas ke belakang): ia tidak memiliki fasilitas untuk menyimpan dan mengembalikan nilai variabel di sekitar pelaksanaan fungsi. Tidak mengekspor variabel masuk akal karena fungsi dijalankan di shell itu sendiri. Namun, ksh (termasuk ATT ksh93 dan pdksh / mksh), bash dan zsh mengimplementasikan perilaku yang lebih bermanfaat di mana VARhanya diatur selama eksekusi fungsi (itu juga diekspor). Dalam ksh , ini dilakukan jika fungsi didefinisikan dengan sintaks kshfunction NAME …, tidak jika itu didefinisikan dengan sintaks standar NAME (). Dalam bash , ini dilakukan hanya dalam mode bash, bukan dalam mode POSIX (saat dijalankan dengan POSIXLY_CORRECT=1). Di zsh , ini dilakukan jika posix_builtinsopsi tidak disetel; opsi ini tidak diatur secara default tetapi dihidupkan oleh emulate shatau emulate ksh.
Jika some-commandbuiltin, perilaku tergantung pada tipe builtin. Builtin khusus berperilaku seperti fungsi. Built-in khusus adalah yang harus diimplementasikan di dalam shell karena mereka mempengaruhi shell negara (misalnya breakmemengaruhi aliran kontrol, cdmemengaruhi direktori saat ini, setmemengaruhi parameter dan opsi posisi ...). Builtin lainnya hanya built-in untuk kinerja dan kenyamanan (kebanyakan - misalnya fitur bash printf -vhanya dapat diimplementasikan oleh builtin), dan mereka berperilaku seperti perintah eksternal.
Penugasan berlangsung setelah ekspansi alias, jadi jika some-commandmerupakan alias , perluas terlebih dahulu untuk menemukan apa yang terjadi.
Perhatikan bahwa dalam semua kasus, penugasan dilakukan setelah baris perintah diuraikan, termasuk substitusi variabel apa pun pada baris perintah itu sendiri. Jadi var=a; var=b echo $varcetak a, karena $vardievaluasi sebelum penugasan berlangsung. Dan dengan demikian IFS=. printf "%s\n" $varmenggunakan nilai lama IFSuntuk membagi $var.
Saya sudah membahas semua jenis perintah, tetapi ada satu kasus lagi: ketika tidak ada perintah untuk dieksekusi , yaitu jika perintah hanya terdiri dari tugas (dan mungkin pengalihan). Dalam hal itu, penugasan tetap di tempatnya . VAR=VALUE OTHERVAR=OTHERVALUEsetara dengan VAR=VALUE; OTHERVAR=OTHERVALUE. Jadi setelah IFS=. arr=($var), IFStetap diatur ke .. Karena Anda dapat menggunakan $IFSdalam penugasan arrdengan harapan bahwa itu sudah memiliki nilai baru, masuk akal bahwa nilai baru IFSdigunakan untuk ekspansi $var.
Singkatnya, Anda dapat menggunakan hanya IFSuntuk pemisahan bidang sementara :
- dengan memulai shell baru atau subkulit (mis.
third=$(IFS=.; set -f; set -- $var; echo "$3")adalah cara yang rumit untuk dilakukan third=${var#*.*.}kecuali bahwa mereka berperilaku berbeda ketika nilai varmengandung kurang dari dua .karakter);
- di ksh, dengan
IFS=. some-functionmana some-functiondidefinisikan dengan sintaks ksh function some-function …;
- dalam bash dan zsh, dengan
IFS=. some-functionselama mereka beroperasi dalam mode asli yang bertentangan dengan mode kompatibilitas.
IFStetap diatur ke." Eek. Setelah membaca bagian pertama, itu masuk akal, tetapi sebelum saya memposting Q ini, saya tidak akan mengharapkan itu.