Apakah semua variabel disimpan dalam memori sebagai string dalam bash?


13

Katakanlah saya membuat variabel berikut:

s=John
i=12345
f=3.14

Apakah semua variabel ini disimpan dalam memori sebagai string, atau memang bashmemiliki tipe data lain?


1
Hanya karena ketertarikan, mengapa itu penting? Saya benar-benar tidak peduli jika mereka disimpan sebagai teks Swahili selama itu tidak mempengaruhi fungsi bahasa (mempengaruhi kinerja mungkin masalah tetapi, jika itu penting, mereka adalah alat yang lebih baik di gudang senjata Anda daripada bash).

2
@paxdiablo Tidak masalah, saya hanya bertanya karena penasaran, karena semua bahasa pemrograman / scripting lain yang saya tahu (misalnya: Java, C ++, JavaScript, PHP, dll.) memiliki representasi memori unik untuk setiap tipe data , jadi menarik untuk melihat bahasa scripting yang hanya memiliki satu representasi memori untuk semua tipe data.
user268325

Jawaban:


16

Variabel Bash tidak diketik .

Tidak seperti banyak bahasa pemrograman lain, Bash tidak memisahkan variabel-variabelnya dengan "ketik". Pada dasarnya, variabel Bash adalah string karakter, tetapi, tergantung pada konteksnya, Bash mengizinkan operasi aritmatika dan perbandingan pada variabel. Faktor penentu adalah apakah nilai suatu variabel hanya berisi angka.

Seperti jawaban lain mengatakan , ada semacam bentuk pengetikan yang lemahdeclare .

Ini adalah bentuk pengetikan [1] yang sangat lemah yang tersedia dalam bahasa pemrograman tertentu.

Lihat sebuah contoh:

declare -i number
# The script will treat subsequent occurrences of "number" as an integer.     

number=3
echo "Number = $number"     # Number = 3

number=three
echo "Number = $number"     # Number = 0
# Tries to evaluate the string "three" as an integer.

Referensi:


13

Bash pada dasarnya memiliki variabel skalar polos, array, dan array asosiatif. Selain itu, skalar dapat ditandai sebagai bilangan bulat dengan declarebuiltin . Dari sudut pandang programmer script / pengguna shell, variabel string bertindak sebagai string, variabel integer bertindak sebagai integer, dan array sesuai dengan tipenya. Implementasi internal tidak terlalu relevan.


Tetapi, jika kita ingin tahu bagaimana data sebenarnya disimpan dalam memori, kita harus memeriksa kode sumber untuk melihat apa yang sebenarnya dilakukan oleh program.

Di Bash 4.4, skalar disimpan sebagai string, terlepas dari tag integer. Ini terlihat dalam definisi struct variable/ the SHELL_VARtypedef dan dalam fungsimake_variable_value , yang secara eksplisit menerjemahkan bilangan bulat ke string untuk penyimpanan.

Array disimpan dalam apa yang tampak sebagai daftar tertaut ( array.h), dan array asosiatif sebagai tabel hash. Nilai-nilai di dalamnya disimpan lagi sebagai string. Pilihan daftar yang ditautkan untuk array mungkin tampak aneh, tetapi karena array dapat jarang, dan indeks dapat berupa angka arbitrer terlepas dari seberapa sedikit elemen yang terdapat dalam array, pilihan desain sedikit lebih mudah untuk dipahami.

Namun, kode juga berisi definisi untuk yang tidak digunakanunion _value , dengan bidang untuk angka integer, angka floating point, serta nilai string. Itu ditandai dalam komentar sebagai "untuk masa depan", jadi ada kemungkinan bahwa beberapa versi Bash di masa depan akan menyimpan berbagai jenis skalar dalam bentuk asli mereka.


1

Untuk kehidupan saya, saya tidak dapat menemukan ini dinyatakan di mana saja dalam banyak kata tetapi ini adalah bagaimana saya memahaminya.

Bash adalah interpreter, bukan kompiler dan mewakili semua variabel sebagai string. Oleh karena itu semua upaya dan penekanan yang berjalan dengan ekspansi dari berbagai jenis.

Bash melewati meneruskan semua variabel bernama ke declaresebagai string dengan atribut yang mengontrol bagaimana variabel itu akan diperluas oleh declarepada penyimpanan.

banana=yellow              #no call to declare
declare -p banana
declare -- banana="yellow" #but declare was invoked with --

declare -i test=a          #arithmetic expansion to null/zero
declare -p test
declare -i test="0"

declare -i test2=5+4       #successful arithmetic expansion
declare -p test2
declare -i test2="9"

declare -i float=99.6      #arithmetical expansion fails due to syntax
bash: declare: 99.6: syntax error: invalid arithmetic operator (error token is ".6")

nofloat=99.9
declare -p nofloat
declare -- nofloat"99.6"   #Success because arithmetical expansion not invoked

declare -a a               #variable is marked as a placeholder to receive an array
declare -p a
declare -a a

a[3]=99                    #array elements are appended
a[4]=99
declare -p a
declare -a a=([3]="99" [4]="99") 

declare -A newmap          #same as -a but names instead of numbers
newmap[name]="A Bloke"
newmap[designation]=CFO
newmap[company]="My Company"
declare -p newmap
declare -A newmap=([company]="My Company" [name]="A Bloke" [designation]="CFO" )

Dan tentu saja

declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")

Coda untuk ini adalah bahwa bahkan jika declarememiliki representasi internal yang berubah dengan flag atribut, string adalah semua yang dilihat atau ingin dilihat oleh bash.



0

Itu tidak relevan.

Satu-satunya cara untuk berinteraksi dengan variabel Bash adalah melalui Bash, jadi tidak mungkin bagi Anda untuk melihat perbedaan bagaimana variabel disimpan dalam memori, karena Anda tidak pernah dapat mengaksesnya melalui memori secara langsung , Anda selalu perlu meminta Bash untuk nilai, dan Bash kemudian dapat menerjemahkannya dengan cara apa pun yang ingin terlihat seolah-olah mereka telah disimpan dengan cara tertentu.

Bahkan, mereka bahkan mungkin tidak disimpan dalam memori sama sekali . Saya tidak tahu seberapa pintar implementasi umum Bash, tetapi setidaknya mungkin dalam kasus-kasus sederhana untuk menentukan apakah suatu variabel akan digunakan dan / atau apakah itu akan dimodifikasi, dan mengoptimalkannya sepenuhnya atau inline itu.


Saya pikir inti pertanyaannya adalah representasi daripada lokasi
bu5hman

2
Maksud saya adalah Anda tidak dapat mengetahui representasi, karena Anda tidak dapat mengamatinya. Jadi, itu tidak relevan dan mungkin berubah tanpa Anda sadari. Tidak mungkin mengatakan representasi apa yang Bash pilih. Anda dapat mempelajari kode sumber implementasi dan memeriksa representasi yang dipilihnya, tetapi itu dapat mengubah representasi besok di rilis patch berikutnya dan tidak akan ada cara bagi Anda untuk mengetahuinya.
Jörg W Mittag

Variabel Schroedingers? Saya setuju dengan Anda secara mendasar tentang representasi yang mendasarinya tidak relevan (lihat jawaban saya) tetapi dalam menggunakan bash, kami secara efektif 'mengkodekan ke antarmuka' dan representasi di antarmuka sangat ketat.
bu5hman

2
Ya, tetapi pertanyaannya bukan tentang representasi di batas antarmuka, tetapi secara khusus tentang bagaimana mereka "disimpan dalam memori". Dan untuk pertanyaan itu, saya akan menjawab: kita tidak, tidak bisa, dan seharusnya tidak tahu.
Jörg W Mittag

Mengutip baris terakhir dari posting saya sendiri ..... seperti yang saya katakan, kami setuju ...... dan diberi perwakilan OP dan sifat pertanyaan, saya pikir mereka akan diberi nilai wajar untuk pekerjaan rumah mereka, siapa pun akan dikutip ;-).
bu5hman
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.