Câu trả lời:
Đó là $'...'
trong bash
không phải là tham số mở rộng, đó là một loại đặc biệt của trích dẫn được giới thiệu bởi ksh93
đó mở rộng những \n
, \x0a
, \12
mã một ký tự xuống dòng. zsh
cũng được thêm vào \u000a
. ksh93
và bash
cũng có \cj
trong khi zsh
có \C-J
. ksh93
cũng hỗ trợ các biến thể như\x{a}
.
Đây $
là một gợi ý rằng nó là một hình thức hoặc mở rộng. Nhưng trong mọi trường hợp, nó khác với các hình thức mở rộng khác sử dụng $
(như $((1 + 1))
, $param
hoặc $(cmd)
) ở chỗ nó không được thực hiện bên trong dấu ngoặc kép hoặc tài liệu ở đây ( echo "$'x'"
đầu ra $'x'
trong tất cả các vỏ mặc dù không được chỉ định trên POSIX) và việc mở rộng của nó không bị chia tách + toàn cầu, nó chắc chắn gần với một toán tử trích dẫn hơn một toán tử mở rộng.
IFS=\n
sẽ đặt IFS thành n
( \
được coi là toán tử trích dẫn) và IFS="\n"
hoặc IFS='\n'
sẽ đặt IFS thành dấu gạch chéo ngược hai ký tự và n
.
Bạn cũng có thể dùng:
IFS='
'
hoặc là
IFS="
"
hoặc là
IFS=$'
'
Để vượt qua một dòng mới theo nghĩa đen, mặc dù điều đó ít dễ đọc hơn (và người ta không thể nhìn thấy ngoài việc sử dụng những thứ như set list
trong vi
liệu$IFS
có chứa các ký tự khoảng cách khác trong mã đó hay không).
IFS=:
, IFS=':'
, IFS=":"
, IFS=$':'
Tất cả các bộ IFS cho :
nên nó không quan trọng mà bạn sử dụng.
$'...'
được hỗ trợ (với các biến thể) bởi ít nhất: ksh93
, zsh
, bash
, mksh
, busybox sh
, FreeBSD sh
. ksh93
và bash
cũng có một $"..."
dạng trích dẫn được sử dụng để bản địa hóa văn bản mặc dù nó hiếm khi được sử dụng vì nó cồng kềnh để triển khai và sử dụng một cách hợp lý và đáng tin cậy.
Các shell es
và fish
shell cũng có thể sử dụng \n
bên ngoài dấu ngoặc kép để mở rộng sang dòng mới.
Một số công cụ như printf
, một số triển khai echo
hoặc awk
cũng có thể tự mở rộng \n
chúng. Chẳng hạn, người ta có thể làm:
printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only
để xuất ký tự dòng mới, nhưng lưu ý rằng:
IFS = $ (printf '\ n')
sẽ không hoạt động vì lệnh thay thế ( $(...)
) loại bỏ tất cả các ký tự dòng mới. Tuy nhiên, bạn có thể sử dụng:
eval "$(printf 'IFS="\n"')"
Mà hoạt động vì đầu ra của printf
kết thúc trong một "
ký tự, không phải là một dòng mới.
Bây giờ, để hoàn chỉnh, trong rc
shell và các dẫn xuất (như es
hoặc akanga
), $'\n'
thực sự là sự mở rộng của \n
biến đó (một biến có tên là chuỗi gồm hai ký tự \
và n
). Các shell đó không có giới hạn về tên biến ký tự có thể chứa và chỉ có một loại dấu ngoặc kép : '...'
.
$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo
rc
tất cả các biến cũng được xuất sang môi trường, nhưng ít nhất là trong biến thể Unix của rc
, đối với các tên biến như \n
, phiên bản biến môi trường trải qua một dạng mã hóa:
; env | grep foo | sed -n l
__5cn=foo\001bar$
( 0x5c
là giá trị byte của ASCII \
; xem thêm cách biến mảng đó được mã hóa với byte 0x1 làm dấu phân cách).
Đây là trích dẫn ANSI-C :
Từ ngữ của hình thức
$'string'
được đối xử đặc biệt. Từ này mở rộng thànhstring
, với các ký tự thoát dấu gạch chéo ngược được thay thế theo quy định của tiêu chuẩn ANSI C.
Do đó $'\n'
được thay thế bằng một dòng mới.
Điều này không liên quan đến việc mở rộng tham số shell , mặc dù sử dụng $
.
Các chuỗi như $'\n'
đã được giới thiệu bởi ksh93
và hiện không phải là một phần của tiêu chuẩn POSIX.
Chúng cho phép sử dụng hầu hết các lối thoát C giống nhau, ví dụ $'\u2345'
và các lối thoát cũng được hỗ trợ bởi echo
.
Lưu ý rằng nếu bạn không thích (trong trường hợp ksh93 hoặc bash) sử dụng phương thức thoát đó, bạn vẫn có thể sử dụng:
IFS='
'
tương đương nhưng khó đọc hơn.
BTW: Tiện ích mở rộng này đã vượt qua tiêu chuẩn POSIX, nhưng nó được lên kế hoạch cho SUSv8 dự kiến sẽ không xuất hiện trước năm 2020 vì trước tiên chúng tôi cần xử lý độ trễ của chúng tôi sau danh sách lỗi hiện tại.
$'...'
mở rộng khác nhau từ đó echo
. Chúng giống như những đối số cho đối số định dạng của printf
. Đối với echo
, 0 là bắt buộc trong \0123
khi cho $'...'
và printf
định dạng, \0123
sẽ là \012
một dòng mới theo sau bởi một lứa 3.
$'...'
đặc điểm kỹ thuật vẫn đang được thảo luận. Có một số vấn đề vẫn phải giải quyết với từ ngữ hiện đang đề xuất.
\uxxxx
việc mở rộng) và không có giải pháp nào phù hợp với việc triển khai hiện có. Vì vậy, nó có thể không được đưa vào phiên bản POSIX tiếp theo. Có lẽ họ có thể để lại bản \uxxxx
mở rộng cho vấn đề8, vì vậy chúng tôi vẫn có thể có ít nhất $'\n'
.
+1
cho trình độ hiểu biết vô nhân đạo thông thường