Bash có nhận ra một khai báo biến là chuỗi nếu bạn không đặt dấu ngoặc kép không?


8
name=Jackson
echo $name

Điều này sẽ hiển thị Jackson.

name="Jackson"
echo $name

Điều này cũng sẽ hiển thị Jackson.

Vì vậy, tôi giả sử bằng cách đặt dấu ngoặc kép xung quanh một biến, nó sẽ biến nó thành một chuỗi. Cái gì sẽ đặt tên = Jackson về mặt kỹ thuật? Nó cũng sẽ được công nhận là một chuỗi?


có một sự khác biệt: thử name=Michael Jackson ; echo "$name"name="Michael Jackson" ; echo "$name". Rất khác nhau. Thông thường, luôn đặt dấu ngoặc kép xung quanh khi bạn xác định và sử dụng biến. cd "${var}"sẽ tốt hơn nhiều so với cd $varviệc âm thầm đi đến homedir thay vì phản đối nếu var không được xác định ... Trừ khi bạn cần gọi rõ ràng từng yếu tố riêng biệt, tức là trong mộtfor i in $var ; do something ; done
Olivier Dulac

khi bạn nói rằng name=Michael Jackson ;bạn đang đặt "tên" biến thành giá trị "Michael" và gọi chương trình / cmd là "Jackson". Bash sẽ sửa lại một lỗi với thông báo "lệnh không tìm thấy" vì bash đang tìm kiếm một chương trình có tên là "Jackson". vì vậy, cuối cùng, biến "tên" không được đặt.
RKA

Câu trả lời:


6

Các biến môi trường Linux luôn là các chuỗi. Các trích dẫn chỉ cần thiết nếu bạn có các ký tự đặc biệt (siêu ký tự shell hoặc khoảng trắng) trong chuỗi của bạn. Shell metachar character là:

<>()[]{}*?$|&#\;`'"

Với $, \ và `dấu ngoặc kép là không đủ vì chúng thậm chí còn được mở rộng trong chúng. Ở đó bạn cần một dấu ngoặc đơn hoặc thoát chúng bằng \.

Như đã lưu ý trong một nhận xét, bash có các biến được gõ đặc biệt, nhưng chúng hiếm khi cần thiết và theo mặc định tất cả các biến bash cũng là chuỗi.


3
+1 vì cốt lõi của câu trả lời là đúng. Tuy nhiên, hệ vỏ cao cấp hơn có các kiểu dữ liệu khác ngoài chuỗi. Bash cho phép bạn nói những điều như typeset -i foo=2để có được một biến số nguyên $foovới giá trị 2.
Warren Young

1
@WarrenYoung Theo nghĩa nào đó thì có gì khác foo=2?
goldilocks

1
Nb. Không có thứ gọi là "biến số nguyên" trong bash: tldp.org/LDP/abs/html/untyped.html Chúng vẫn là các chuỗi; typeset -i foo=2là chính xác như foo=2foo="2".
goldilocks

1
@goldilocks Nó không hoàn toàn giống nhau. Chạy foo=0x${foo}; echo $foo"hoặc foo=bar;echo $foođể thấy một sự khác biệt trong hành vi. Chắc chắn có các biến số nguyên gõ trong bash.
jlliagre

1
@goldilocks declare -i x=123456789012345678901234567890;echo ${#x}sẽ hiển thị 30nếu đó là sự thật, nhưng thực tế không phải vậy.
jlliagre

5

Bash không được đánh máy mạnh mẽ; 1 sự khác biệt đáng kể duy nhất là giữa các loại vô hướng và hợp chất (mảng). Vô hướng luôn được coi là chuỗi , nhưng có "chuỗi số" có thể được sử dụng một cách hợp lý:

a="5"
b=10

echo "$a + $b = "$(($a+$b)); 

"Chuỗi số" chỉ đơn giản là một chuỗi chỉ chứa các chữ số và do đó có thể được chuyển đổi thành một giá trị số nguyên. Tất cả các giá trị vô hướng trong bash vẫn chỉ là các chuỗi và các trích dẫn trong khai báo ở đây là không liên quan. a=5là hoàn toàn giống như a="5". Nếu bạn so sánh $a$bsử dụng (ví dụ) -ltchúng được coi là số. Nếu bạn so sánh chúng bằng cách sử dụng <chúng được xử lý từ vựng. Đó là toán tử / bối cảnh làm cho quyết định, không phải là một đặc tính của biến.

Bạn cũng có thể khai báo một biến bằng "cờ số nguyên" và điều này sẽ khiến giá trị khai báo được hiểu là biểu thức số học:

x=10/2
echo "$x" # output: 10/2
declare -i x=10/2
echo "$x" # output: 5
declare -i x=what
echo "$x" # output: 0  

Sau đó, mọi thứ được gán cho biến đó sẽ được giải thích một cách hợp lý:

a=5
declare -i b=10
a=$a/5
b=$b/5
echo "$a $b" #output: 5/5 2
a=hello
b=world
echo $a$b #output hello0

Nhưng nội dung của biến vẫn là một chuỗi (số). Cờ số nguyên giới hạn nội dung của chuỗi và ảnh hưởng đến việc giải thích các giá trị được gán cho nó.

1 Đây không phải là kiểu gõ động đơn giản, như trường hợp của số nguyên khai báo thể hiện. Có lẽ chúng ta có thể gọi nó là một kiểu gõ vịt , hoặc, theo Hướng dẫn về kịch bản nâng cao của Bash , nó là "được tháo gỡ".


1
Khai báo một biến là số nguyên chắc chắn có hậu quả tiếp theo kể từ đó, biến không thể được sử dụng để lưu trữ chuỗi (ngẫu nhiên).
jlliagre

@jlliagre Ya đã cho tôi. Đã chỉnh sửa.
goldilocks

@goldilocks "Bash không được gõ mạnh; 1 sự khác biệt đáng kể duy nhất là giữa các kiểu vô hướng và hỗn hợp (mảng). Vô hướng luôn được coi là chuỗi". Tôi có thể hỏi, nguồn thông tin này của bạn là gì? Tôi không thể tìm thấy nó trong bất kỳ tài liệu Bash nào.
yroc

@yroc Có cái này từ "Hướng dẫn về kịch bản nâng cao": tldp.org/LDP/abs/html/untyped.html (đã làm việc đó vào phần chú thích ở trên). Ngoài ra tôi muốn nói rằng tôi chỉ nói rõ ràng: Thực tế là nó không có các loại định nghĩa rõ ràng có nghĩa là nó không được gõ mạnh.
goldilocks

1

có một sự khác biệt: thử

unset name
name="Michael Jackson" ; echo "$name" 

unset name #to reset name, see comments
name=Michael Jackson ; echo "$name"

Điều đó rất khác: vào ngày 2, nó cố gắng khởi động lệnh "Jackson", chuyển qua môi trường "name = Michael". Vì vậy, nó sẽ phàn nàn rằng "Jackson: không tìm thấy lệnh" Tôi phải thêm tên unset name"đặt lại", vì phần tiếp theo của dòng name=Michaelsẽ chỉ được chuyển cho lệnh "Jackson" (và chỉ cho lệnh đó), và do đó KHÔNG thực hiện trên cấp độ vỏ gọi! (do đó vẫn sẽ có lệnh name="Michael Jackson"từ lệnh thứ 1, nếu chúng ta không đặt nó trở lại ""trước lần thử thứ 2. Vì vậy, "echo $ name" sẽ gây nhầm lẫn vẫn hiển thị "Michael Jackson" nếu chúng ta không quên lần thử đầu tiên đó .)

Thông thường, luôn đặt dấu ngoặc kép xung quanh khi bạn xác định và đặc biệt là khi bạn sử dụng biến.

cd "${var}" 

tốt hơn nhiều

cd $var 

Phiên bản thứ 2 sẽ âm thầm đi đến homedir thay vì phản đối nếu $ var không được xác định ...

Sau đó, chỉ lấy ra các dấu ngoặc kép xung quanh chỉ khi bạn biết rằng bạn cần tách từng phần tử của biến, tức là trong một:

for i in $var ; do something_using_i ; done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.