Tại sao không xuất các biến trên cùng một dòng bạn gán chúng?


44

Từ đối số cuối cùng của lệnh trước là gì?

shellcheck cho bạn biết không xuất các biến trên cùng một dòng bạn gán chúng.

Tôi đã tự hỏi tại sao?

Có những lời khuyên tương tự áp dụng cho alias, declare, export, local, readonly, và typeset?




9
Quy tắc shellcheck trong câu hỏi là SC2155. Có tài liệu khá tốt tại wiki shellcheck .
phunehehe

3
Ngoài ra một số vỏ cũ sẽ không chấp nhận exportvà phân công cùng nhau. Các gia truyền Bourne Shell , ví dụ, kết quả đầu ra một "foo = 2 không phải là một định danh" lỗi.
Dennis Williamson

Câu trả lời:


54

Các vấn đề là trong Bash mỗi lệnh chỉ có một mã thoát. Khi bạn export foo="$(false)"mã thoát falsechỉ đơn giản là bị loại bỏ. Nếu bạn thay

foo="$(false)"
export foo

lệnh đầu tiên không thành công có thể được thực hiện, ví dụ như errexitcài đặt.

Khai báo và gán một chuỗi ký tự như export foo='bar'tất nhiên không gặp phải vấn đề này. Nhưng thay đổi là hằng số duy nhất trong phát triển phần mềm và đơn giản là việc quản lý tốt để chứng minh những tuyên bố như vậy trong tương lai bằng cách tách chúng ra.

Ngoài các lệnh cụ thể của nhiệm vụ mà bạn đề cập, còn có nhiều lệnh trong một nhiệm vụ đơn lẻ như foo="$(false)$(true)". Xem pipefailtrong man bashcho một cái bẫy khác như vậy.

Một điều cần nhớ là trình tự khai báo và chuyển nhượng đôi khi có liên quan. Ví dụ: bạn sẽ muốn khai báo các biến trước khi gán chúng. (Thật không may, không thể khai báo các biến trước khi gán chúng lần đầu tiên.)local readonly


Vì vậy, nếu một người đang đặt một biến từ một nghĩa đen và không có mã thoát để loại bỏ, thì không có gì sai khi thực hiện tất cả trên một dòng.
Monty Harder

1
Theo như lỗi shellcheck này, không. Nhưng vì các câu trả lời đã bị xóa bây giờ có một nửa đúng giữa chúng, shell Bourne không hỗ trợ cú pháp gán cho export, vì vậy trong một số năm, đã có sự khôn ngoan về việc này nếu trình thông dịch của một người có khả năng là shell Bourne.
JdeBP

@JdeBP, lưu ý rằng trình bao Bourne đã hỗ trợ foo=$(cmd) export foo, mặc dù với cùng một cảnh báo, cmdtrạng thái thoát đó bị mất (nhưng đã khiến trình bao thoát ra nếu không thành công set -e).
Stéphane Chazelas

Điều đó được bao phủ bởi câu đầu tiên của tôi.
JdeBP
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.