Ya, kerang, dan bashkhususnya, berhati-hati untuk membaca file satu baris pada satu waktu, sehingga berfungsi sama seperti ketika Anda menggunakannya secara interaktif.
Anda akan melihat bahwa ketika file tidak dapat dicari (seperti pipa), bashbahkan membaca satu byte pada suatu waktu untuk memastikan tidak membaca melewati \nkarakter. Ketika file dicari, itu dioptimalkan dengan membaca blok penuh pada suatu waktu, tetapi mencari kembali setelah \n.
Itu berarti Anda dapat melakukan hal-hal seperti:
bash << \EOF
read var
var's content
echo "$var"
EOF
Atau tulis skrip yang memperbarui sendiri. Yang tidak akan bisa Anda lakukan jika itu tidak memberi Anda jaminan itu.
Sekarang, jarang sekali Anda ingin melakukan hal-hal seperti itu dan, seperti yang Anda ketahui, fitur itu cenderung lebih sering menghalangi daripada berguna.
Untuk menghindarinya, Anda dapat mencoba dan memastikan Anda tidak mengubah file di tempat (misalnya, memodifikasi salinan, dan memindahkan salinan di tempat (seperti sed -iatau perl -pidan beberapa editor lakukan misalnya)).
Atau Anda dapat menulis skrip Anda seperti:
{
sleep 20
echo test
}; exit
(perhatikan bahwa penting untuk exitberada di jalur yang sama }; meskipun Anda juga bisa meletakkannya di dalam kawat gigi tepat sebelum yang terakhir).
atau:
main() {
sleep 20
echo test
}
main "$@"; exit
Shell perlu membaca skrip sampai exitsebelum mulai melakukan apa pun. Itu memastikan shell tidak akan membaca dari skrip lagi.
Itu berarti seluruh skrip akan disimpan dalam memori.
Itu juga dapat mempengaruhi penguraian skrip.
Misalnya, di bash:
export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'
Akan menampilkan bahwa U + 00E9 dikodekan dalam UTF-8. Namun, jika Anda mengubahnya ke:
{
export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'
}
The \ue9akan diperluas di charset yang berlaku pada saat itu bahwa perintah itu diurai yang dalam hal ini adalah sebelum yang exportperintah dijalankan.
Perhatikan juga bahwa jika perintah sourcealias .digunakan, dengan beberapa shell, Anda akan memiliki masalah yang sama untuk file-file yang bersumber.
Itu tidak terjadi bashmeskipun sourceperintah yang membaca file sepenuhnya sebelum menafsirkannya. Jika menulis secara bashspesifik, Anda sebenarnya bisa memanfaatkannya, dengan menambahkan di awal skrip:
if [[ ! $already_sourced ]]; then
already_sourced=1
source "$0"; exit
fi
(Saya tidak akan mengandalkan itu meskipun seperti yang Anda bayangkan versi masa depan bashdapat mengubah perilaku yang saat ini dapat dilihat sebagai batasan (bash dan AT&T ksh adalah satu-satunya kerang mirip POSIX yang berperilaku seperti itu sejauh yang bisa diceritakan) dan already_sourcedtriknya agak rapuh karena mengasumsikan bahwa variabel tidak ada di lingkungan, belum lagi itu mempengaruhi konten dari variabel BASH_SOURCE)