a

Câu hỏi Sự khác biệt giữa dấu nháy đơn và dấu ngoặc kép trong Bash


Trong Bash, sự khác biệt giữa dấu nháy đơn ('') và dấu ngoặc kép ("")?


339
2017-07-14 17:55


gốc




Các câu trả lời:


Dấu ngoặc đơn sẽ không nội suy bất cứ điều gì, nhưng dấu ngoặc kép sẽ. Ví dụ: biến, backticks, nhất định \ thoát, v.v.

Thí dụ:

$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")

Sổ tay Bash có điều này để nói:

3.1.2.2 Trích dẫn đơn

Bao gồm các ký tự trong dấu nháy đơn (') bảo tồn giá trị chữ của mỗi ký tự trong dấu ngoặc kép. Một trích dẫn duy nhất có thể không xảy ra giữa các dấu nháy đơn, ngay cả khi trước dấu gạch chéo ngược.

3.1.2.3 Báo giá gấp đôi

Bao gồm các ký tự trong dấu ngoặc kép (") giữ nguyên giá trị chữ của tất cả các ký tự trong dấu ngoặc kép, ngoại trừ $, `, \và, khi mở rộng lịch sử được bật, !. Các nhân vật $ và ` giữ lại ý nghĩa đặc biệt của chúng trong dấu ngoặc kép (xem Shell Expansions). Dấu gạch chéo ngược chỉ giữ lại ý nghĩa đặc biệt của nó khi được theo sau bởi một trong các ký tự sau: $, `, ", \hoặc dòng mới. Trong dấu ngoặc kép, dấu gạch chéo ngược được theo sau bởi một trong các ký tự này bị xóa. Dấu gạch chéo ngược trước các ký tự không có ý nghĩa đặc biệt sẽ không được sửa đổi. Trích dẫn kép có thể được trích dẫn trong dấu ngoặc kép bằng cách đặt trước dấu gạch chéo ngược. Nếu được bật, mở rộng lịch sử sẽ được thực hiện trừ khi ! xuất hiện trong dấu ngoặc kép được thoát bằng cách sử dụng dấu gạch chéo ngược. Dấu gạch chéo ngược trước ! không bị xóa.

Các thông số đặc biệt * và @ có ý nghĩa đặc biệt khi trong ngoặc kép (xem Mở rộng tham số Shell).


353
2017-07-14 17:57



Đối với những ai không biết "nội suy" nghĩa là gì: en.wikipedia.org/wiki/String_interpolation - Kolob Canyon


Nếu bạn đề cập đến điều xảy ra khi bạn lặp lại điều gì đó, thì dấu nháy đơn sẽ lặp lại những gì bạn có giữa chúng, trong khi dấu ngoặc kép sẽ đánh giá các biến giữa chúng và xuất ra giá trị của biến.

Ví dụ, điều này

#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'

sẽ cho điều này:

double quotes gives you sometext
single quotes gives you $MYVAR

180
2017-07-14 18:02





Các câu trả lời được chấp nhận tuyệt. Tôi đang tạo một bảng giúp hiểu nhanh chủ đề. Lời giải thích liên quan đến một biến đơn giản a cũng như một mảng được lập chỉ mục arr.

Nếu chúng ta đặt

a=apple      # a simple variable
arr=(apple)  # an indexed array with a single element

và sau đó echo biểu thức trong cột thứ hai, chúng ta sẽ nhận được kết quả / hành vi được hiển thị trong cột thứ ba. Cột thứ tư giải thích hành vi.

 # | Expression  | Result      | Comments
---+-------------+-------------+--------------------------------------------------------------------
 1 | "$a"        | apple       | variables are expanded inside ""
 2 | '$a'        | $a          | variables are not expanded inside ''
 3 | "'$a'"      | 'apple'     | '' has no special meaning inside ""
 4 | '"$a"'      | "$a"        | "" is treated literally inside ''
 5 | '\''        | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
 6 | "red$arocks"| red         | $arocks does not expand $a; use ${a}rocks to preserve $a
 7 | "redapple$" | redapple$   | $ followed by no variable name evaluates to $
 8 | '\"'        | \"          | \ has no special meaning inside ''
 9 | "\'"        | '           | \' is interpreted inside ""
10 | "\""        | "           | \" is interpreted inside ""
11 | "*"         | *           | glob does not work inside "" or ''
12 | "\t\n"      | \t\n        | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi          | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi`   | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]}   | array access not possible inside ''
16 | "${arr[0]}" | apple       | array access works inside ""
17 | $'$a\''     | $a'         | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'"     | $'\t'       | ANSI quoting is not interpreted inside ""
19 | '!cmd'      | !cmd        | history expansion character '!' is ignored inside ''
20 | "!cmd"      | cmd args    | expands to the most recent command matching "cmd"
---+-------------+-------------+--------------------------------------------------------------------

Xem thêm:


118
2018-02-07 06:14



Bảng đó là câu trả lời cho nhiều câu hỏi StackOverflow. - C0deDaedalus
Câu trả lời được chấp nhận nói cuối cùng The special parameters * and @ have special meaning when in double quotes vậy làm thế nào đến "*" kết quả trong *? - anddero
@ Karl-AnderoMere, bởi vì chúng không được mở rộng như các tham số trong trường hợp đó. "$@" và "$*" là mở rộng tham số. "@" và "*" không. - Charles Duffy
@ CharlesDuffy Cảm ơn, nó có ý nghĩa ngay bây giờ! - anddero


Những người khác giải thích rất tốt và chỉ muốn đưa ra những ví dụ đơn giản.

Dấu nháy đơn có thể được sử dụng xung quanh văn bản để ngăn trình diễn dịch bất kỳ ký tự đặc biệt nào. Ký hiệu đô la, dấu cách, dấu và, dấu hoa thị và các ký tự đặc biệt khác đều bị bỏ qua khi được đặt trong dấu nháy đơn.

$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.' 

Nó sẽ cho điều này:

All sorts of things are ignored in single quotes, like $ & * ; |.

Điều duy nhất không thể được đặt trong dấu nháy đơn là một trích dẫn duy nhất.

Dấu ngoặc kép hành động tương tự như dấu nháy đơn, ngoại trừ dấu ngoặc kép vẫn cho phép trình dịch diễn giải các dấu hiệu đô la, dấu ngoặc kép và dấu gạch chéo ngược. Nó đã được biết rằng dấu gạch chéo ngược ngăn chặn một ký tự đặc biệt duy nhất được giải thích. Điều này có thể hữu ích trong dấu ngoặc kép nếu một ký hiệu đô la cần được sử dụng làm văn bản thay vì cho một biến. Nó cũng cho phép dấu nháy kép được thoát để chúng không được hiểu là kết thúc của một chuỗi được trích dẫn.

$ echo "Here's how we can use single ' and double \" quotes within double quotes"

Nó sẽ cho điều này:

Here's how we can use single ' and double " quotes within double quotes

Nó cũng có thể được nhận thấy rằng dấu nháy đơn, mà nếu không sẽ được hiểu là sự khởi đầu của một chuỗi trích dẫn, được bỏ qua trong dấu ngoặc kép. Tuy nhiên, các biến được diễn giải và thay thế bằng giá trị của chúng trong dấu ngoặc kép.

$ echo "The current Oracle SID is $ORACLE_SID"

Nó sẽ cho điều này:

The current Oracle SID is test

Dấu ngoặc kép hoàn toàn không giống như dấu nháy đơn hoặc kép. Thay vì được sử dụng để ngăn chặn việc giải thích các ký tự đặc biệt, các dấu ngoặc kép thực sự buộc thực thi các lệnh mà chúng kèm theo. Sau khi các lệnh kèm theo được thực hiện, đầu ra của chúng được thay thế thay cho dấu ngoặc kép trong dòng ban đầu. Điều này sẽ rõ ràng hơn với một ví dụ.

$ today=`date '+%A, %B %d, %Y'`
$ echo $today 

Nó sẽ cho điều này:

Monday, September 28, 2015 

1
2017-07-14 18:21