Một số trường hợp số lượng khoảng trắng có vấn đề gì trong các tập lệnh bash (hoặc shell khác)


14

Tôi đã được thông báo rằng các không gian rất quan trọng trong bashcác tập lệnh shell khác và tôi không nên thay đổi sự tồn tại của các không gian trừ khi tôi biết tôi đang làm gì. Bằng cách "thay đổi sự tồn tại", tôi có nghĩa là chèn một khoảng trắng giữa hai ký tự không phải khoảng trắng hoặc xóa khoảng trắng giữa hai ký tự không phải khoảng trắng, ví dụ: thay đổi var="$val"thành var ="$val"hoặc ngược lại. tôi muốn hỏi

Có trường hợp nào sử dụng một khoảng trắng hoặc sử dụng nhiều khoảng trắng liên tiếp trong tập lệnh shell sẽ tạo ra sự khác biệt không? .

(Tất nhiên, việc chèn / xóa khoảng trắng trong dấu ngoặc kép sẽ tạo ra sự khác biệt, như thay đổi từ echo "a b"sang echo "a b"hoặc ngược lại. Tôi đang tìm kiếm các ví dụ khác với ví dụ tầm thường này.)

Tôi đã bắt gặp câu hỏi này nhưng câu hỏi đó là về việc thêm và xóa khoảng trắng giữa hai ký tự không phải không gian mà tôi biết nhiều ví dụ rằng nó sẽ tạo ra sự khác biệt.

Bất kỳ trợ giúp sẽ được đánh giá cao. Bao gồm nhiều loại vỏ nếu có thể.

Câu trả lời:


19

Ngoài dấu ngoặc kép, shell sử dụng khoảng trắng (dấu cách, tab, dòng mới, trả về vận chuyển, v.v.) làm dấu tách từ / mã thông báo. Điều đó có nghĩa là:

  • Những thứ không được ngăn cách bởi khoảng trắng được coi là một "từ".
  • Những thứ được phân tách bằng một hoặc nhiều ký tự khoảng trắng được coi là hai (hoặc nhiều) từ.

Số lượng ký tự khoảng trắng thực tế giữa mỗi "vật" không thành vấn đề, miễn là có ít nhất một ký tự.


Cảm ơn bạn. Tôi không thể tìm thấy bất kỳ ví dụ truy cập bản thân mình. Tôi chỉ muốn chắc chắn.
Weijun Zhou

2
Bash cũng coi các nguồn cấp dữ liệu mẫu và các tab dọc là khoảng trắng.
fpmurphy

thật. ban đầu tôi đã viết '... dòng mới, v.v. và sau đó thay đổi nó thành thêm lợi nhuận vận chuyển. vô tình làm rơi 'vv'.
cas

Điều gì sẽ xảy ra nếu số lượng không gian quá lớn, khiến chương trình không thể vừa với bộ nhớ?
Worse_Username 29/12/17

7
@Worse_Username Khoảng trắng không phải nằm gọn trong bộ nhớ. Tôi vừa tạo một tập lệnh 48 GB trên một máy có 8GB RAM và 20 GB trao đổi. Nó chạy tốt Phải mất 3 phút để vượt qua tất cả các khoảng trắng đó, nhưng cuối cùng, nó đã chạy thành công một echolệnh với nhiều khoảng trắng giữa lệnh và đối số.
kasperd

23

Đây có thể là gian lận, nhưng điều này:

rm foo\ bar         # "delete the file named 'foo bar'"

khác với điều này:

rm foo\  bar        # "delete the files named 'foo ' and 'bar'"

mặc dù các khoảng trắng không nằm trong dấu ngoặc kép. ;-)

Đáng lo ngại hơn, điều này:

rm \
    foo          # "delete the file named 'foo'"

khác với điều này:

rm \ 
    foo          # "delete the file named ' ', then run the command 'foo'"

mặc dù trông chúng giống hệt nhau!


Mặc dù các khoảng trắng không có trong dấu ngoặc kép, dấu gạch chéo ngược có chức năng tương tự như hình thức trích dẫn và tôi sẽ đặt nó trong cùng thể loại với "ví dụ tầm thường" của câu hỏi. (Mặc dù điều này thật thú vị.)
David Z

12

Nếu chúng ta không nói về những nhân vật không gian ( U+0020), nhưng bất kỳ ký tự khoảng trắng ( U+0020, \n, \t, vv), sau đó một trường hợp đặc biệt đến tâm trí của tôi: Đây-Documents.

Mã này (sử dụng dấu cách):

cat <<- 'EOF'
<space><space>foo
EOF

Sẽ in:

  foo

Nhưng mã này (sử dụng các tab):

cat <<- 'EOF'
<tab><tab>foo
EOF

Sẽ in:

foo

Đó là bởi vì ( như trạng thái POSIX ):

Nếu toán tử chuyển hướng là <<-, tất cả các ký tự <tab> hàng đầu sẽ bị xóa khỏi các dòng đầu vào và dòng chứa dấu phân cách dấu.


1
Điều đó thật thú vị. Tôi nghĩ về tài liệu ở đây nhưng không biết <<-nhà điều hành. Cảm ơn rât nhiều.
Weijun Zhou

tài liệu ở đây là một dạng văn bản được trích dẫn, không phải mã shell. tách từ vỏ không áp dụng.
cas

2

Nó cũng có tác dụng khi viết câu lệnh gán. Giống như nếu tôi nói FOO=xyznó sẽ tạo ra một biến môi trường có tên là FOOgiá trị xyz, nhưng nếu tôi tách các phần bằng với một khoảng trắng, nó sẽ nghĩ rằng tôi đang gọi một chương trình có tên là FOOarg =xyz. Vì vậy, nó không thành vấn đề khi nói đến cú pháp nhất định.


Thường FOO=xyzkhông tạo một biến shell nội bộ nhưng không phải là biến môi trường. Bạn cần set -ahoặc export FOO=xyzcho điều đó (tức là biến nó thành một phần của môi trường của các quy trình con không phụ).
Hauke ​​Laging
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.