Phân công biến ngoài tuyên bố trường hợp


8

Trong nhiều ngôn ngữ, có thể gán kết quả của câu lệnh case / switch cho một biến, thay vì lặp lại phép gán biến nhiều lần trong câu lệnh case. Có thể làm một cái gì đó như thế này trong vỏ Bash?

color_code=$(case "$COLOR" in
  (red)    1;;
  (yellow) 2;;
  (green)  3;;
  (blue)   4;;
esac)

(Hoặc, như một bên, trong bất kỳ vỏ khác?)


Bạn có thêm (s. Nếu không, nó ổn.
HalosGhost

Câu trả lời:


6

Cấu variable=$(...)trúc sẽ lấy đầu ra tiêu chuẩn của bất kỳ lệnh nào trong $(...)và gán nó cho variable. Do đó, để được variablechỉ định theo cách bạn muốn, các giá trị phải được gửi đến đầu ra tiêu chuẩn. Điều này được thực hiện dễ dàng với echolệnh:

color_code=$(case "$COLOR" in
  red)    echo 1;;
  yellow) echo 2;;
  green)  echo 3;;
  blue)   echo 4;;
esac)

Điều này sẽ hoạt động trên bashcũng như tất cả các vỏ POSIX khác.

Parens trái tùy chọn

Theo tiêu chuẩn POSIX, các dấu ngoặc trái trong một casecâu lệnh là tùy chọn và các công việc sau cũng hoạt động:

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Như Gilles đã chỉ ra trong các nhận xét, không phải tất cả các shell đều chấp nhận cả hai hình thức kết hợp với $(...): để có một bảng tương thích chi tiết ấn tượng, hãy xem "$ ()" thay thế lệnh so với nhúng ")" .


Một trang tôi đã kiểm tra (tôi không nhớ nó ở đâu) liệt kê việc mở (là tùy chọn. Tôi nghĩ rằng nó có thể giúp tránh để )bị hiểu sai là đóng )cho $(...)biểu thức.
iconoclast

@iconoclast Có. Việc mở (là tùy chọn: mã hoạt động như nhau mà không có hoặc không có chúng. Tôi bỏ chúng đi chỉ vì, tốt hơn hay tồi tệ hơn, đó là truyền thống. Phần quan trọng của giải pháp đề xuất là việc sử dụng echo.
John1024

1
@iconoclast Già (pre-POSIX) vỏ không cho phép một khe hở (cho casecác mô hình, nhưng một số vỏ đã làm và yêu cầu mở (khi caseđược sử dụng trong một lệnh thay. Vỏ hiện đại là tốt cả hai cách. Xem in-ulm.de/~mascheck/various/cmd-subst
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles Cảm ơn thông tin đó. Độ sâu của kiến ​​thức của bạn, như mọi khi, ấn tượng.
John1024

2

color_code=$(…)gán đầu ra của lệnh cho biến color_code, với các dòng mới cuối cùng bị loại bỏ. Vì vậy, bạn cần phải sản xuất một số đầu ra. Mã bạn đã viết cố gắng thực thi 1như một lệnh.

Bạn có thể sử dụng thành ngữ này. Lưu ý rằng color_codesẽ trống nếu $COLORkhông có giá trị nào được hỗ trợ.

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Nhưng nó không phải là rất thành ngữ. Ngôn ngữ shell hướng đến sự kết hợp đơn giản của các lệnh đơn giản. Sự thay thế lệnh lớn này là khó xử. Việc thay thế lệnh tạo ra một lớp con, chậm hơn so với phương thức đơn giản:

case "$COLOR" in
  red)    color_code=1;;
  yellow) color_code=2;;
  green)  color_code=3;;
  blue)   color_code=4;;
esac

Sự khác biệt về ngữ nghĩa chính giữa hai cách tiếp cận là $(…)tạo ra một lớp con, sao cho mọi phép gán, thoát, chuyển hướng, v.v. được thực hiện bên trong không có tác dụng bên ngoài.

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.