Có vẻ như lệnh của bạn có thể thiết lập các biến môi trường dựa trên các đối số được đưa ra trên dòng lệnh. Nó có thể là bạn có thể làm:
CLUSTER=cl1; cluster=$CLUSTER command
... Và thiết lập môi trường cho nó theo yêu cầu.
Mặt khác, trích dẫn shell thường phân định các đối số hoặc thoát các ký tự shell đặc biệt khác khỏi giải thích shell. Bạn có thể chứa (và do đó thoát) các loại trích dẫn shell khác nhau trong các loại khác dựa trên các quy tắc khác nhau:
"''''"
- một chuỗi trích dẫn mềm có thể chứa bất kỳ số lượng trích dẫn cứng nào.
"\""
- \
dấu gạch chéo ngược có thể thoát khỏi "
trích dẫn "
mềm trong chuỗi trích dẫn mềm.
- Trong bối cảnh này,
\\
dấu gạch chéo ngược cũng thoát khỏi chính nó, \$
mã thông báo mở rộng và \n
ewlines như được lưu ý dưới đây, nhưng được xử lý theo nghĩa đen.
"${expand} and then some"
- một chuỗi trích dẫn mềm có thể chứa một $
mở rộng shell được giải thích .
'"\'
- một '
chuỗi trích dẫn cứng có thể chứa bất kỳ ký tự nào ngoài một '
trích dẫn cứng.
\
- dấu gạch chéo ngược không trích dẫn sẽ thoát khỏi bất kỳ ký tự nào sau đây để giải nghĩa theo nghĩa đen - thậm chí là dấu gạch chéo ngược khác - ngoại trừ một \n
ewline.
- Trong
\\n
trường hợp ewline, cả \
dấu gạch chéo ngược và \n
ewline đều bị xóa hoàn toàn khỏi lệnh được giải thích kết quả.
${parameter+expand "$parameter"}
- trích dẫn kết quả từ việc mở rộng shell hầu như không bao giờ đóng vai trò là dấu phân cách trừ một vài trường hợp đặc biệt. Tôi sẽ không mạo hiểm để mô tả những điều này hơn nữa ở đây.
Tôi coi thật kỳ quặc khi bất kỳ ứng dụng nào sẽ diễn giải các trích dẫn trong dòng lệnh của nó. Một thực tiễn như vậy không có nhiều ý nghĩa trong đó - đối với vỏ sò, ít nhất - mục đích chính của một trích dẫn thường là để phân định một lập luận. Tuy nhiên, tại lời gọi, các đối số luôn được phân định bằng các \0NUL
ký tự và vì vậy một trích dẫn không thể phục vụ nhiều mục đích.
Ngay cả một shell thường chỉ bận tâm để giải thích các trích dẫn trong một trong các đối số gọi của nó khi nó được gọi bằng một -c
công tắc - biểu thị rằng toán hạng đầu tiên của nó thực sự là một tập lệnh shell mà nó nên chạy khi gọi. Đây là một trường hợp hai lần đánh giá đầu vào.
Tất cả những gì đã nói, bạn có thể làm một số điều để vượt qua các trích dẫn bằng chữ thông qua các đối số trên dòng lệnh. Ví dụ:
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
Như tôi đã lưu ý trong một nhận xét trước đây, bạn có thể chứa các "
trích dẫn trong một bản mở rộng được "
trích dẫn.
CLUSTER=cl1; command -p "cluster=\"$CLUSTER\""
Bạn có thể thoát khỏi "
với một \
dấu chéo ngược trong "
chuỗi trích dẫn.
CLUSTER=cl1; command -p cluster='"'"$CLUSTER"'"'
Bạn có thể xen kẽ và ghép các kiểu trích dẫn để đi đến kết quả cuối cùng mong muốn của bạn như ghi chú @jimmij ở trên .
CLUSTER=cl1; ( set -f; IFS=; command -p cluster=\"$CLUSTER\" )
Bạn có thể vô hiệu hóa cả việc tạo và $IFS
tách tên tệp - do đó tránh phải trích dẫn $expansion
tất cả - và do đó chỉ trích dẫn các trích dẫn. Đây có lẽ là quá mức cần thiết.
Cuối cùng, có một loại trích dẫn shell khác có thể được sử dụng. Như tôi đã lưu ý trước khi sh -c "$scriptlet"
hình thức gọi shell thường được sử dụng để cung cấp tập lệnh của shell trên dòng lệnh. Tuy nhiên, khi $scriptlet
trở nên phức tạp - chẳng hạn như khi các trích dẫn phải chứa các trích dẫn khác - việc sử dụng tài liệu ở đây và sh -s
thay vào đó - trong đó trình bao được hướng dẫn cụ thể để gán tất cả các toán hạng sau cho các tham số vị trí như trong -c
trường hợp và chưa lấy kịch bản của nó từ stdin
.
Nếu lệnh của bạn phải diễn giải các trích dẫn theo cách này thì tôi sẽ xem xét nó tốt hơn nếu nó có thể làm như vậy trong một đầu vào tệp. Ví dụ:
CLUSTER=cl1
command --stdin <<-SCRIPT
cluster="$CLUSTER"
SCRIPT
Nếu bạn không trích dẫn delimiter của một <<here-document
sau đó tất cả các nội dung của nó được đối xử gần như giống hệt như họ đã "
mềm trích dẫn - ngoại trừ rằng "
hai dấu ngoặc kép mình không được đối xử đặc biệt. Và vì vậy, nếu chúng ta chạy ở trên với cat
thay thế:
CLUSTER=cl1
cat <<-SCRIPT
cluster="$CLUSTER"
SCRIPT
... nó in ...
cluster="cl1"
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"