2014-11-24 16 views
6

Gần như mọi nơi tôi đã đọc, bao gồm hướng dẫn về phong cách tập lệnh bash của Google đề cập đến sự cần thiết phải trích dẫn các thay thế lệnh (trừ khi đặc biệt mong muốn tất nhiên).Có cần phải trích dẫn các thay thế lệnh trong khi gán biến trong bash không?

Tôi hiểu khi nào/ở đâu/tại sao trích dẫn thay thế lệnh trong quá trình sử dụng chung. Ví dụ: echo "$(cat <<< "* useless string *")" hơn echo $(...)

Tuy nhiên đối với các bài tập biến đặc biệt, tôi đã thấy rất nhiều ví dụ như vậy: variable="$(command)"

Tuy nhiên, tôi đã không tìm thấy trường hợp variable=$(command) là không tương đương.

variable="$(echo "*")"variable=$(echo "*") cả hai đặt giá trị thành '*'.

Bất kỳ ai có thể đưa ra bất kỳ tình huống nào để rời khỏi sự thay thế không được kiểm soát trong quá trình xác định biến thực sự có gây ra sự cố không?

+0

Câu hỏi hay! Tôi đã làm nhiều bài kiểm tra và có vẻ như chúng giống hệt nhau, không có sự khác biệt. – fedorqui

+0

Tôi nghĩ rằng vấn đề anh ta yêu cầu có thể xảy ra với $ cmd, $ {cmd}. Thay thế và trong mệnh đề If, chúng ta cần "" ở đó. Vui lòng sửa nếu tôi sai –

Trả lời

6

Vỏ không thực hiện tách từ cho các bài tập biến (được chuẩn hóa theo cách đó bởi POSIX và bạn có thể dựa vào nó). Vì vậy bạn không cần dấu ngoặc kép (nhưng bạn có thể sử dụng chúng mà không làm cho kết quả khác nhau) trong

variable=$(command) # same as variable="$(command)" 

Tuy nhiên, word-tách được thực hiện trước khi lệnh thực hiện, vì vậy trong

echo $(command) 
echo "$(command)" 

kết quả có thể khác nhau. Sau này giữ tất cả các chuỗi không gian đa, trong khi trước đây làm cho mỗi từ trở thành một đối số khác nhau để lặp lại. Đó là vào bạn để quyết định đó là hành vi mong muốn.

Quirk vỏ thú vị: có một vị trí khác trong đó trích dẫn thay thế hoặc không tạo sự khác biệt, cụ thể là biểu thức trong cấu trúc case expr in.

case $FOO in 
    (frob) ...;; 
esac 

là không thể phân biệt từ Testing

case "$FOO" in 
    (frob) ...;; 
esac 
+2

Đó là những gì câu trả lời này nói. –

+0

Bạn có thể cung cấp liên kết đến phần chính xác của tiêu chuẩn POSIX trong trường hợp yêu cầu này không? Tôi gặp khó khăn khi tìm nó. – Lucas

+2

@Lucas Tôi sẽ giải thích 2.9.1 Lệnh đơn giản, số 4 trong http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01: * "Mỗi phép gán biến được mở rộng để mở rộng dấu ngã, tham số mở rộng, thay thế lệnh, mở rộng số học và xóa báo giá trước khi gán giá trị. "* Nó không nói tách từ ở đây. – Jens

-2

với rất nhiều lệnh khác nhau, nó là như nhau. Không thể tìm thấy sự khác biệt.

+1

Đây không phải là câu trả lời cho câu hỏi. Và để thấy sự khác biệt, hãy thử 'echo $ (echo -e" hello \ nworld ")' chống lại 'echo" $ (echo -e "hello \ nworld") "' – jeb

4

Khi sử dụng BASH, hai dòng này là 100% tương đương:

variable="$(command)" 
variable=$(command) 

trong khi hai đây không phải là:

echo $(command) 
echo "$(command)" 

Than ôi, não con người không phải là một máy tính. Nó đặc biệt không đáng tin cậy khi lặp lại một công việc. Vì vậy, rất có thể là nếu bạn trộn các kiểu (tức là bạn trích dẫn khi bạn sử dụng các đối số lệnh nhưng bạn không trích dẫn khi gán một biến), một lần trong một thời gian, bạn sẽ hiểu sai.

Tệ hơn nữa, thỉnh thoảng bạn sẽ muốn kết quả lệnh được mở rộng thành các từ riêng lẻ. Và người tiếp theo đọc mã của bạn sẽ tự hỏi liệu anh ta có đang nhìn vào một con bọ hay không.

Conculsion: Vì hai dòng đầu tiên giống nhau, nên bộ não trung bình luôn dễ dàng báo giá $() (ngay cả khi không cần thiết) để đảm bảo bạn luôn báo giá khi cần.

+2

Ok, điều đó có ý nghĩa sau đó là tại sao nó được khuyến khích thường xuyên ... Khi tôi lần đầu tiên bắt đầu viết các kịch bản lệnh shell, tôi đã trích dẫn như một quy tắc chung. Bây giờ tôi quen thuộc hơn nhiều với nó, tôi chỉ cố gắng loại bỏ bất cứ điều gì dư thừa hoặc không cần thiết. – Six

Các vấn đề liên quan