2013-07-07 24 views
5

Tôi đã tìm thấy một hành vi kỳ lạ mà tôi không biết cách giải quyết.Làm thế nào tôi có thể buộc bash mở rộng một biến để chuyển nó thành một đối số?

$ var1=* 

$ echo $var1 
Audiobooks Downloads Desktop (etc.) 

$ ls $var1 
Audiobooks: 

Downloads: 
(etc) 

Tất cả có vẻ OK. Khi khai báo, biến được mở rộng và mọi thứ khác hoạt động. Nhưng thấy điều này:

$ var2=~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm 

$ echo $var2 
/home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm 

$ ls $var2 
ls: no se puede acceder a /home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm: No existe el fichero o el directorio 

$ ls /home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm 
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc18.noarch.rpm /home/yajo/rpmbuild/SRPMS/enki-12.10.3-1.fc18.src.rpm 
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc19.noarch.rpm /home/yajo/rpmbuild/SRPMS/enki-12.10.3-1.fc19.src.rpm 

thời gian này, tại tuyên bố chỉ ~ được mở rộng, trong đó sản xuất mà tôi không thể vượt qua nó như một tham số để ls. Tuy nhiên, đi qua cùng một chuỗi theo nghĩa đen tạo ra kết quả mong đợi.

Câu hỏi là:

  • Tại sao đôi khi mở rộng và đôi khi không?
  • Làm cách nào để bắt chước hành vi của $var1 với $var2?

Cảm ơn.

ghi chú thêm:

tôi đã cố gắng cùng với dấu ngoặc kép và duy nhất, nhưng với kết quả xấu như vậy.

+0

Xem [Làm thế nào để biến các biến trong tập lệnh bash?] (Http://stackoverflow.com/questions/369145/how-to-glob-variables-in-bash-script). – tom

Trả lời

9

Thứ tự mà trình phân tích cú pháp các khía cạnh khác nhau của dòng lệnh không rõ ràng và vấn đề cho những thứ như thế này.

Thứ nhất, ký tự đại diện không được mở rộng tại tuyên bố, họ đang mở rộng sau khi giá trị biến được thay thế (lưu ý: trong các ví dụ tôi sẽ giả vờ tôi có hệ thống tập tin của bạn):

$ var1=* 
$ echo "$var1" # double-quotes prevent additional parsing of the variable's value 
* 
$ echo $var1  # without double-quotes, variable value undergoes wildcard expansion and word splitting 
Audiobooks: 

Downloads: 
(etc) 

BTW, các ~được mở rộng với tuyên bố, gây nhầm lẫn điều hơn nữa:

$ var2=~ 
$ echo "$var2" # again, double-quotes let me see what's actually in the variable 
/home/yajo 

vấn đề với ~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm1 là trong khi vỏ không mở rộng ký tự đại diện (*) trên giá trị sau khi thay thế, nó không làm mở rộng cú đúp ({SRPMS,RPMS/*}), do đó, nó thực sự tìm kiếm tên thư mục với niềng răng và dấu phẩy trong tên ... và không tìm thấy bất kỳ.

Cách tốt nhất để xử lý việc này thường là lưu trữ danh sách tệp dưới dạng mảng; nếu bạn làm điều này đúng, mọi thứ sẽ được mở rộng khi khai báo:

$ var2=(~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm) 
$ echo "${var2[@]}" # This is the proper way to expand an array into a word list 
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc18.noarch.rpm etc... 

Lưu ý rằng mảng là phần mở rộng bash và sẽ không hoạt động trong vỏ POSIX trơn. Vì vậy, hãy đảm bảo bắt đầu tập lệnh của bạn với #!/bin/bash, không phải #!/bin/sh.

+0

Câu trả lời hay! Cảm ơn, nó hoạt động! – Yajo

Các vấn đề liên quan