Apakah ekspansi riwayat dinonaktifkan di skrip?

9

Saya mengerti kesalahan berikut ini karena !digunakan untuk ekspansi sejarah:

$ echo "Hello!Tim"
bash: !Tim: event not found

Namun jika saya memasukkan perintah ke dalam skrip dan menjalankan skrip, tidak ada masalah:

$ cat myscript
echo "Hello!Tim"
$ bash myscript 
Hello!Tim

Mengapa demikian? Apakah manual bash menyebutkan alasannya?

Tim
sumber
1
Pertanyaan bagus, singkatnya. Bagus sekali!
Wildcard
Berdasarkan apa yang saya baca di sini: gnu.org/software/bash/manual/html_node/History-Interaction.html Saya yakin Anda perlu menggunakan semacam shoptpengubah untuk membuatnya berfungsi dalam skrip Anda. Saya tahu itu bukan jawaban yang Anda cari.
jesse_b
Apa gunanya? Skrip apa yang akan Anda jalankan yang akan memperluas riwayat Anda sebelumnya? Atau akankah itu memperluas perintah sebelumnya dari skrip?
Jeff Schaller
@JeffSchaller, ekspansi sejarah numerik dalam skrip dengan angka positif terdengar seperti ide yang sangat buruk, tapi saya bisa dengan mudah membayangkan kasus penggunaan untuk !!atau !-2(angka sejarah negatif / relatif) atau serupa. Kebanyakan mereka akan dipecahkan dengan cara lain, tetapi itu masih merupakan pertanyaan yang bagus tentang bagaimana shell bekerja (dan ketika Anda / tidak perlu melarikan diri dari exclams Anda!).
Wildcard

Jawaban:

12

Ya, ekspansi riwayat diaktifkan secara default hanya untuk shell interaktif.

Untuk mengaktifkannya untuk skrip shell, tulis:

set -H

Untuk menonaktifkannya di shell interaktif, tulis:

set +H

Untuk menentukan apakah ekspansi riwayat saat ini diaktifkan atau tidak, gunakan beberapa bentuk kode berikut:

case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac

Dalam mulai mengajar kelas shell, saya menggali manual secara ekstensif untuk mencoba menentukan apakah "shell interaktif" itu sebenarnya. Ini pertanyaan pusaran air, jadi izinkan saya menyelamatkan Anda dari beberapa masalah:

Shell memiliki opsi BANYAK. Beberapa opsi ini diinisialisasi dengan cara yang berbeda ketika shell memiliki terminal pengendali (atau ketika dimulai dengan -i, bla bla, apa pun, lihat di bawah).

SEMUA opsi shell dapat diubah secara individual.

"Shell interaktif" adalah istilah yang menipu ketika Anda mencoba mendefinisikannya dengan tepat. Ini benar-benar hanya kumpulan pengaturan opsi.

Pertanyaan tentang pengaturan mana yang membuat shell menjadi interaktif atau tidak tidak mungkin dijawab; itu menjadi konyol. Hal ini justru pertanyaan filosofis sama dengan Kapal Theseus .

Jika Anda memulai shell interaktif, tetapi kemudian menonaktifkan ekspansi histori, gunakan --noeditingflag, set --norc, matikan expand_aliases, dll, dll., Lalu dalam arti apa shell itu interaktif? Atau, kapan itu menjadi tidak interaktif lagi? Anda tidak dapat menjawab pertanyaan-pertanyaan ini.

Yang benar adalah bahwa "interaktif" hanyalah label yang nyaman untuk koleksi berbagai opsi shell. Demikian juga "non-interaktif." Hal yang sama; hanya kumpulan perilaku yang masing-masing dapat diubah secara individual.

Intinya: shell berperilaku berbeda ketika dimulai "secara interaktif" versus ketika itu dimulai "non-interaktif." Mencoba mendefinisikan istilah-istilah ini secara tepat setelah memulai adalah konyol. Lihat saja masing-masing opsi shell untuk memahami perilakunya.


Saya lupa bahwa selain penelitian saya sendiri, saya mempostingnya secara luas di situs ini.

Wildcard
sumber
Terima kasih. Dalam manual, saya hanya menemukan "Opsi ini diaktifkan secara default untuk shell interaktif" untuk set -H. Mungkin inferensi Anda bahwa "ekspansi sejarah diaktifkan secara default hanya untuk shell interaktif".
Tim
@Tim, lihat sisa jawaban saya. Kalimat manual itu sangat licin, dan mencoba mendapatkan jawaban untuk "apa itu shell interaktif?" keluar dari halaman manual seperti berbicara dalam lingkaran. Tidak ke mana-mana.
Wildcard
Apa yang BISA Anda katakan adalah bahwa cuplikan kode berikut akan selalu menunjukkan kepada Anda apakah perluasan riwayat diaktifkan di shell saat ini:case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
Wildcard
@Tim, ngomong-ngomong, aku tidak tahu maksudmu apa itu "inferensi" -ku, karena itulah makna yang jelas set -H. Itu ADALAH opsi histexpand.
Wildcard
1
Saya sudah mencoba ini pada skrip dan tidak berfungsi sampai saya juga melakukannya set -o history, setelah memverifikasi dengan set -oskrip bahwa itu dinonaktifkan.
Daniel C. Sobral