4 (thêm) Tùy chọn đáng tin cậy.
Một dấu hoa thị không được trích dẫn*
sẽ được hiểu là một mẫu (toàn cầu) bởi vỏ.
Shell sẽ sử dụng nó trong việc mở rộng tên đường dẫn.
Sau đó, nó sẽ tạo ra một danh sách tên tệp phù hợp với mẫu.
Một dấu hoa thị đơn giản sẽ khớp với tất cả tên tệp trong PWD (thư mục làm việc hiện tại).
Một mô hình phức tạp hơn */
sẽ phù hợp với tất cả các tên tệp kết thúc /
.
Như vậy, tất cả các thư mục. Đó là lý do tại sao lệnh:
1.- tiếng vang.
echo */
echo ./*/ ### avoid misinterpreting filenames like "-e dir"
sẽ được mở rộng (bằng vỏ) cho echo
tất cả các thư mục trong PWD.
Để kiểm tra điều này: Tạo một thư mục ( mkdir
) có tên như test-dir và cd
vào đó:
mkdir test-dir; cd test-dir
Tạo một số thư mục:
mkdir {cs,files,masters,draft,static} # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces} # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename' # and some files:
Lệnh echo ./*/
sẽ vẫn đáng tin cậy ngay cả với các tệp có tên kỳ lạ:
./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/
Nhưng không gian trong tên tệp làm cho việc đọc hơi khó hiểu.
Nếu thay vì echo
, chúng tôi sử dụng ls
, shell vẫn là thứ đang mở rộng danh sách tên tệp. Shell là lý do để có được một danh sách các thư mục trong PWD. Các -d
tùy chọn để ls
làm cho nó liệt kê các mục nhập thư mục hiện tại thay vì nội dung của mỗi thư mục (như đã trình bày theo mặc định).
ls -d */
Tuy nhiên, lệnh này là (phần nào) ít đáng tin cậy. Nó sẽ thất bại với các tập tin có tên kỳ lạ được liệt kê ở trên. Nó sẽ nghẹt thở với một vài cái tên. Bạn cần phải xóa từng cái một cho đến khi bạn tìm thấy những vấn đề.
2.-
GNU ls
sẽ chấp nhận phím "kết thúc tùy chọn" ( --
).
ls -d ./*/ ### more reliable BSD ls
ls -d -- */ ### more reliable GNU ls
3.-printf
Để liệt kê mỗi thư mục trong dòng riêng của nó (trong một cột, tương tự như ls -1), hãy sử dụng:
$ printf "%s\n" */ ### Correct even with "-", spaces or newlines.
Và, thậm chí tốt hơn, chúng ta có thể xóa dấu vết /
:
$ set -- */; printf "%s\n" "${@%/}" ### Correct with spaces and newlines.
Một nỗ lực như thế này:
$ for i in $(ls -d */); do echo ${i%%/}; done
Sẽ thất bại về:
- một số tên (
ls -d */
) như đã được hiển thị ở trên.
- sẽ bị ảnh hưởng bởi giá trị của
IFS
.
- sẽ phân chia tên trên dấu cách và tab (với mặc định
IFS
).
- mỗi dòng mới trong tên sẽ bắt đầu một lệnh echo mới.
4.- Chức năng
Cuối cùng, sử dụng danh sách đối số bên trong một hàm sẽ không ảnh hưởng đến danh sách đối số của trình bao hiện tại. Đơn giản:
$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs
trình bày danh sách này:
--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var
Tùy chọn này an toàn với một số loại tên tệp lẻ.
-d
nghĩa thực sự của nó.