Tại sao --text = Lần $ @ chỉ vượt qua từ đầu tiên?


9

Khi tôi chạy đoạn script sau với một số đối số như arg1 arg2 arg3:

#!/bin/bash
zenity --entry --text="$@"

zenity tạo một hộp thoại nhập với văn bản này: "arg1" trong khi tôi mong đợi "arg1 arg2 arg3"

Nếu tôi sử dụng một biến như tập lệnh sau, nó sẽ hiển thị tất cả các đối số cho văn bản nhập.

#!/bin/bash
text="$@"
zenity --entry --text="$text"

Sự khác biệt giữa các kịch bản này là gì? Tại sao cái đầu tiên chỉ thay thế $@bằng đối số đầu tiên?

Câu trả lời:


16

$@mở rộng thành các từ riêng biệt (trong khi $*mở rộng thành một từ), như được giải thích trong bashhướng dẫn . Như vậy, khi bạn viết

zenity --text="$@"

nó mở rộng đến

zenity --text="$1" "$2" "$3"

Tuy nhiên, bài tập biến shell không trải qua quá trình phân tách từ. Lưu ý rằng chia tách trường / từ được bỏ qua trong danh sách mở rộng cho các bài tập biến trong bashhướng dẫn . Hành vi này phù hợp với thông số POSIX . Vì vậy, khi bạn viết

text="$@"

biến textnhận được tất cả các tham số vị trí dưới dạng một từ, tương đương với nếu bạn đã viết text="$*". Thật vậy, đây là lý do trích dẫn kép thường không cần thiết trong các bài tập biến. Cả hai

text=$@

text=$*

là hoàn toàn an toàn.

Vì thế,

text=$@
zenity --option="$text"

mở rộng "$text"thành một từ duy nhất, đó là lý do tại sao điều này hoạt động. Lưu ý rằng đó --option="$@"chỉ là một đối số bình thường cho lệnh zenityvà không phải là phép gán biến shell, đó là lý do tại sao việc chia từ diễn ra ở đây nhưng không phải trong text=$@.


1
+1. Điều này cũng sẽ làm việc: zenity --text="$*"- "$*"mở rộng thành một từ duy nhất.
glenn jackman

+1 để dạy tôi một điều: người đàn ông! = Tài liệu. Tôi nên đã tìm kiếm thông tin bash, nó cũng chứa phần thủ công bạn liên kết đến.
manatwork

7

$@ được mở rộng từng tham số trong từ riêng biệt, trở thành

zenity --entry --text="arg1" "arg2" "arg3" # syntactically wrong for zenity

Sử dụng $*thay thế để mở rộng nó trong một từ duy nhất

zenity --entry --text="$*"

mà sẽ trở thành

zenity --entry --text="arg1 arg2 arg3" # syntactically correct for zenity

Vui lòng làm sáng tỏ lý do tại sao biến thể $ text từ câu hỏi của OP hoạt động như mong đợi
iruvar

@ChandraRavoori, bạn bắt tôi với điều đó. Theo hướng dẫn, việc chia tách Word Word không được thực hiện, ngoại trừ "$ @", và nếu việc mở rộng được trích dẫn kép xảy ra trong một từ, việc mở rộng tham số đầu tiên được nối với phần đầu của từ gốc, và việc mở rộng các tham số cuối cùng được nối với phần cuối của từ gốc.”, vì vậy tôi mong chờ text="$@"để được mở rộng đến text="arg1" "arg2" "arg3", mà nên thất bại. Nhưng chắc chắn không phải là trường hợp.
manatwork

@ChandraRavoori Lý do là chia tách trường không xảy ra trong các bài tập biến. Tôi giải thích chi tiết hơn trong câu trả lời của tôi .
jw013

@ jw013: Nhưng theo Tài liệu tham khảo Bash , "$@" không trải qua quá trình phân tách từ, ngay cả trong các bài tập biến.
ruakh

@ruakh Hướng dẫn bash không nói điều đó theo như tôi biết. Bạn có một trích dẫn?
jw013
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.