Có thể sử dụng “/” trong tên tệp không?


111

Tôi biết rằng đây không phải là điều nên làm, nhưng có cách nào để sử dụng ký tự gạch chéo thường phân tách các thư mục trong tên tệp trong Linux không?


1
Tôi đoán bạn có thể sửa đổi tên của tệp bằng cách sử dụng quyền truy cập trực tiếp vào phân vùng hardisk của bạn và vá bằng ký tự '/' ở đâu đó. Điều gì xảy ra là một câu hỏi thú vị ... hầu hết có lẽ không phải những gì bạn muốn.
hochl

1
Nhưng câu trả lời ngắn nên là: không, đây không phải là cái gì đó bao giờ nên được thực hiện :-)
Simeon Visser

Việc hack dấu gạch chéo vào tên tệp trong mục nhập thư mục trong FS có được tính không? Nó sẽ không được khuyến khích; bạn sẽ không bao giờ có thể truy cập vào tệp.
Jonathan Leffler

35
Điều này làm tôi nhớ lại lần bạn tôi tạo một tệp có tên *và sau đó hỏi, "Làm cách nào để xóa tệp?" Tôi đã trả lời, rmtheo sau là tên tệp. Chà, bạn biết phần còn lại.
David Heffernan

1
Đối với những người dùng Linux mới, khi bạn không tự tin về một biểu thức hoặc tên tệp, tôi nghĩ rằng cách tốt là sử dụng lsđể liệt kê các tệp bạn muốn xóa và sau đó thay đổi lslệnh thành rmsau đó.
Dave F

Câu trả lời:


129

Câu trả lời là bạn không thể, trừ khi hệ thống tệp của bạn có lỗi. Đây là lý do tại sao:

Có một lệnh gọi hệ thống để đổi tên tệp của bạn được xác định bằng fs/namei.ctên renameat:

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)

Khi lệnh gọi hệ thống được gọi, nó thực hiện tra cứu đường dẫn ( do_path_lookup) trên tên. Tiếp tục theo dõi điều này, và chúng tôi nhận được link_path_walkđiều này:

static int link_path_walk(const char *name, struct nameidata *nd)
{
       struct path next;
       int err;
       unsigned int lookup_flags = nd->flags;

       while (*name=='/')
              name++;
       if (!*name)
              return 0;
...

Mã này áp dụng cho bất kỳ hệ thống tệp nào. Điều này có nghĩa là gì? Nó có nghĩa là nếu bạn cố gắng truyền một tham số với một '/'ký tự thực tế là tên của tệp bằng cách sử dụng phương tiện truyền thống, nó sẽ không thực hiện những gì bạn muốn. Không có cách nào để thoát khỏi nhân vật. Nếu hệ thống tệp "hỗ trợ" điều này, đó là bởi vì chúng:

  • Sử dụng một ký tự unicode hoặc một cái gì đó giống như một dấu gạch chéo nhưng không phải.
  • Họ có một lỗi.

Hơn nữa, nếu bạn đã vào và chỉnh sửa các byte để thêm ký tự gạch chéo vào tên tệp, điều tồi tệ sẽ xảy ra. Đó là bởi vì bạn không bao giờ có thể tham chiếu đến tệp này bằng tên :( vì bất cứ lúc nào bạn làm vậy, Linux sẽ cho rằng bạn đang đề cập đến một thư mục không tồn tại. Sử dụng kỹ thuật 'rm *' cũng sẽ không hoạt động, vì bash chỉ cần mở rộng nó thành tên tệp. Thậm chí rm -rfsẽ không hoạt động, vì một sơ suất đơn giản cho thấy mọi thứ diễn ra như thế nào (rút gọn):

$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0)               = 0
unlinkat(3, "out", 0)                   = 0
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(3)                                = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...

Lưu ý rằng các lệnh gọi unlinkatnày sẽ không thành công vì chúng cần tham chiếu đến các tệp theo tên.


8
Ngoài ra, hãy lưu ý rằng ít nhất e2fsckhãy coi bất kỳ tên tệp nào là tên tệp bất hợp pháp phải được sửa— xem nguồn . Vì vậy, nếu bạn bằng cách nào đó kết thúc với một tên tệp có dấu gạch chéo trong đó, bạn có thể sử dụng fsckđể khắc phục sự cố.
ehabkost

4
@ehabkost Bất kỳ tên tệp nào? Âm thanh như một lỗi trong e2fsck: p
flarn2006

36

Bạn có thể sử dụng một ký tự Unicode hiển thị dưới dạng "/" (ví dụ: ký tự có vẻ thừa này ) giả sử hệ thống tệp của bạn hỗ trợ nó.


42
Có, chính xác là: only /, là U + 002F SOLIDUS, bị cấm. Có rất nhiều ứng viên phù hợp khác: ⁄ là U + 2044 FRACTION SLASH; ∕ là U + 2215 DIVISION SLASH; ⧸ là U + 29F8 BIG SOLIDUS; / Là U + FF0F FULLWIDTH SOLIDUS, và ╱ là U + 2571 là BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT. Tất cả sẽ hoạt động đáng ngưỡng mộ!
tchrist

2
Nhưng sau đó điều gì sẽ xảy ra nếu người dùng sử dụng các ký tự thực đó trong tên tệp / dir của mình? Chúng tôi cần một giải pháp thoát chung. Quá tệ là mã bình thường của Linux không hỗ trợ bất kỳ mã nào, vì nó khớp theo nghĩa đen trên ASCII 0x2F. ASCII là một điều không thể tránh khỏi kể từ ít nhất 20 năm. (Unicode 1.0 có từ năm 1991!)
Evi1M4chine

@tchrist Tôi không muốn phụ thuộc vào unicode. vì vậy tôi có lẽ sẽ thích một dấu phân cách nhiều ký tự như thế ---. lựa chọn mê sảng của bạn có thể sử dụng một ký tự khác và thay đổi số lần lặp lại.
Trevor Boyd Smith

Để biết danh sách các ký tự có thể thay thế trên nhiều ký tự bị cấm trong các hệ thống tệp khác nhau, hãy xem câu trả lời của tôi: stackoverflow.com/a/61448658/4575793
Cadoiz

9

Nó phụ thuộc vào hệ thống tệp bạn đang sử dụng. Trong số những cái phổ biến hơn:


1
nó không chỉ phụ thuộc vào hệ thống tệp, các lệnh gọi hệ thống trong tất cả các hệ thống * nix sẽ phân tích cú pháp / như một thành phần của cây thư mục.
Blackle Mori

2
Ký tự gạch chéo về phía trước được mã hóa cứng vào hạt nhân, độc lập với hệ thống tệp (hãy thử làm grep -r "'/'" *trong nguồn hạt nhân của bạn)
Robert Martin

20
@tchrist Xin lỗi. "Dấu gạch chéo" là một cách hoàn toàn chấp nhận được để đề cập đến ký tự gạch chéo để làm rõ ràng rõ ràng dấu gạch chéo nào được đề cập đến. Đôi khi người ta bị lẫn lộn: P
Robert Martin

2
Hah, nhưng @tchrist cũng có lý, tôi nghĩ vậy. Tại sao chuyển tiếp 'ngụ ý' / 'và' quay lại 'hàm ý' \ '? Lời giải thích tốt nhất mà tôi có cho đến nay là nếu viết bằng bút bắt đầu trên một dòng, từ dưới lên, '/' di chuyển sang phải hoặc 'tiến lên' và '\' di chuyển 'sang trái' hoặc 'quay lại', khi đọc / viết từ trái sang phải. Mặc dù vậy, tôi không thực sự thích lời giải thích đó, một phần vì tôi không phải lúc nào cũng viết các ký tự của mình từ dưới lên rồi chuyển lên. Tôi nghĩ rằng bắt đầu từ trên xuống và di chuyển xuống trong khi viết một ký tự thường trôi chảy hơn.
Jesse W. Collins

4
@jwso Đây hoàn toàn là một điểm phụ, nhưng đây là ngôn ngữ chuẩn, kinh điển. Dấu gạch chéo không phải là cái mà unicode gọi các biểu tượng trông giống như thế này, nó gọi chúng là solidus, nhưng "\" là một dấu gạch chéo ngược, đồng nghĩa với ngược, do đó dấu gạch chéo ngược. Nhưng nếu người ta cần một sự biện minh, thì lùi và tiến là hướng mà đường nghiêng hoặc phải đổ, với hướng dựa trên hướng viết (từ trái sang phải). Nó nghiêng hoặc phải rơi xuống <== hoặc lùi lại nếu nó giống như "\" và ==> hoặc về phía trước nếu nó giống như "/".
Stuart R. Jefferys

4

Chỉ với một mã hóa được thỏa thuận. Ví dụ: bạn có thể đồng ý rằng %sẽ được mã hóa bằng %%%2Fcó nghĩa là a /. Tất cả phần mềm đã truy cập tệp này sẽ phải hiểu mã hóa.


19
"đó mà chúng ta gọi là một dấu gạch chéo bằng bất kỳ tên khác sẽ mùi như hôi" - Shakespeare
Robert Martin

1

Câu trả lời ngắn gọn là: Không, bạn không thể. Đó là một điều cấm cần thiết vì cách cấu trúc thư mục được xác định.

Và, như đã đề cập, bạn có thể hiển thị một ký tự unicode "trông giống như" một dấu gạch chéo, nhưng đó là chừng mực mà bạn nhận được.


1

Nói chung, đó là một ý tưởng tồi nếu cố gắng sử dụng các ký tự "xấu" trong tên tệp; ngay cả khi bạn quản lý nó bằng cách nào đó, nó có xu hướng khiến bạn khó sử dụng tệp sau này. Bộ phân tách hệ thống tệp là phẳng sẽ không hoạt động chút nào, vì vậy bạn sẽ cần phải chọn một phương pháp thay thế.

Bạn đã xem xét mã hóa URL sau đó sử dụng URL đó làm tên tệp chưa? Kết quả là một tên tệp tốt và thật dễ dàng để tạo lại tên từ phiên bản được mã hóa.

Một tùy chọn khác là tạo chỉ mục - tạo tên tệp đầu ra bằng bất kỳ phương pháp nào bạn thích - tên được đánh số thứ tự, hàm băm SHA1, bất cứ thứ gì - sau đó ghi tệp với cặp tên tệp / URL đã tạo. Bạn có thể lưu nó vào một mã băm và sử dụng nó để thực hiện tra cứu URL-to-filename hoặc ngược lại với phiên bản băm đã đảo ngược và bạn có thể viết nó ra và tải lại sau nếu cần.

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.