Những ký tự nào cần được thoát trong các tập tin mà không có dấu ngoặc kép?


12

Tôi có shell / terminal dựa trên trình duyệt thực thi các lệnh bash và tôi đang thoát các khoảng trắng nhưng hóa ra dấu ngoặc đơn cũng cần phải được thoát. Những ký tự nào khác cần được thoát cho tên tệp không nằm trong dấu ngoặc kép?


Nó không rõ ràng những gì bạn đang cố gắng làm. Và những gì đã tự động hoàn thành phải làm với bất cứ điều gì?
Michael Vehrs

@MichaelVehrs Tôi có lệnh mv filename filename-footrong bash, tôi cần thoát ký tự nào, ngoài dấu cách và dấu ngoặc đơn?
jcubic

@MichaelVehrs xóa tự động hoàn thành đề cập.
jcubic

Về cơ bản, tất cả các siêu ký tự shell, chẳng hạn như khoảng trắng, các khối vỏ, các sự kiện lịch sử. Vì lý do này, bạn nên trích dẫn toàn bộ tên tệp, thay vì thoát từng ký tự : mv "$filename" "$newname".
Michael Vehrs

@MichaelVehrs Tôi biết rằng trích dẫn sẽ giải quyết vấn đề với việc thoát nhưng tôi cần sử dụng tên tệp mà không có dấu ngoặc kép. Tôi có trình giả lập thiết bị đầu cuối và nó sẽ hoạt động khi người dùng không sử dụng dấu ngoặc kép.
jcubic

Câu trả lời:


22

Giải pháp đơn giản là đặt một trích dẫn ( ') ở đầu và một trích dẫn khác ở cuối và thay thế mọi 'ký tự bên trong tên tệp bằng chuỗi 4 ký tự '\''. Tất cả các ký tự mất ý nghĩa đặc biệt của chúng trong một chuỗi trích dẫn, ngoại trừ 'chính nó đánh dấu sự kết thúc của chuỗi. Trình tự '\''kết thúc bằng chữ được trích dẫn đơn, ngay sau đó là một trích dẫn đơn được trích dẫn và mở ra một chữ mới được trích dẫn. Do đó, tên tập tin

This file's name has some weird characters!
Will you manage to escape them?

có thể được trích dẫn như sau:

somecommand 'This file'\''s name has some weird characters!
Will you manage to escape them?'

Dấu ngoặc kép có các quy tắc thoát phức tạp hơn và không cho phép bạn bao gồm dấu chấm than !nếu thay thế lịch sử được kích hoạt, vì vậy tôi sẽ không xem xét chúng thêm nữa.

Một cách tiếp cận khác là bảo vệ các ký tự có dấu gạch chéo ngược. Điều này hoạt động cho mọi nhân vật ngoại trừ dòng mới; đối với một dòng mới, đặt nó trong dấu ngoặc đơn (hoặc dấu ngoặc kép) là giải pháp duy nhất. Nếu bạn muốn giảm thiểu số lượng dấu gạch chéo ngược để hiển thị tên được trích dẫn cho người dùng, bạn có thể giới hạn nó ở những nơi cần sử dụng dấu gạch chéo ngược; tuy nhiên, bạn càng bỏ qua nhiều dấu gạch chéo ngược, bạn càng có nguy cơ quên một thứ cần thiết. Chữ cái, chữ số và ký tự không phải ASCII luôn ok. Trích dẫn khoảng trắng và dấu chấm câu bất cứ khi nào bạn không chắc chắn.

Với hệ vỏ điển hình (ksh, bash hoặc zsh), bạn cần trích dẫn các ký tự sau trong ít nhất một số trường hợp.

  • Khoảng trắng (dấu cách, tab, dòng mới - ghi nhớ rằng dòng mới không thể được trích dẫn bằng dấu gạch chéo ngược).
  • ! - mở rộng lịch sử.
  • " - cú pháp shell.
  • #- bình luận bắt đầu khi đi trước khoảng trắng; ký tự đại diện zsh.
  • $ - cú pháp shell.
  • & - cú pháp shell.
  • ' - cú pháp shell.
  • (- ngay cả ở giữa một từ: ksh kéo dài (cũng có sẵn trong bash và zsh); ký tự đại diện zsh.
  • )(xem ()
  • * - ký tự đại diện.
  • , - chỉ bên trong mở rộng niềng răng.
  • ; - cú pháp shell.
  • < - cú pháp shell.
  • = - trong zsh, khi nó ở đầu tên tệp (mở rộng tên tệp với tra cứu PATH).
  • > - cú pháp shell.
  • ? - ký tự đại diện.
  • [ - ký tự đại diện.
  • \ - cú pháp shell.
  • ] - bạn có thể thoát khỏi việc bỏ nó.
  • ^- mở rộng lịch sử; ký tự đại diện zsh.
  • ` - cú pháp shell.
  • { - Niềng răng mở rộng.
  • | - cú pháp shell.
  • } - cần phải được thoát trong zsh, các shell khác sẽ dễ dàng hơn khi không có nẹp mở phù hợp.
  • ~- mở rộng thư mục nhà khi nó ở đầu tên tệp; ký tự đại diện zsh; luôn luôn an toàn khi đó là nhân vật cuối cùng.

Một vài nhân vật nữa có thể yêu cầu xử lý đặc biệt đôi khi:

  • -không phải là đặc biệt cho shell, nhưng khi nó bắt đầu một đối số lệnh, nó chỉ ra một tùy chọn. Nó không thể được bảo vệ bằng dấu ngoặc kép vì việc xử lý đặc biệt nằm trong lệnh chứ không phải trong trình bao. Để bảo vệ tên tệp bắt đầu bằng -, bạn có thể đặt ./trước tên đó - theo cách này nó vẫn là cùng một tệp, nhưng đối số không bắt đầu -nữa.
  • .Bản thân nó không đặc biệt, nhưng các tệp chấm được loại trừ khỏi các khối *theo mặc định.
  • :không phải là đặc biệt cho shell, nhưng một số lệnh phân tích nó đặc biệt, ví dụ để chỉ ra một tệp từ xa ( hostname:filename). Tham khảo tài liệu của lệnh để xem cách đối phó với tên tệp có chứa dấu hai chấm.

¹ Trừ khi người dùng đã cấu hình các nhân vật lịch sử mở rộng thay thế. Một số vỏ cho phép điều này. Đây là một lý do khác để sử dụng dấu ngoặc đơn thay vì dấu gạch chéo ngược.


Các dòng mới, ít nhất là LFduy nhất, có thể được trích dẫn bằng dấu gạch chéo ngược trong một số shell.
iBug

@iBug Không. Trong bất kỳ shell nào giống như sh, dấu gạch chéo ngược + dòng mới mở rộng thành một chuỗi trống, không phải là một dòng mới.
Gilles 'SO- ngừng trở nên xấu xa'

Đây là một câu trả lời tốt, cảm ơn bạn. Có liên kết đến nơi thông tin này 'chính thức' có sẵn không?
slashmais

1
@slashmais Thông tin gì? Cú pháp của ngôn ngữ shell là chính thức có sẵn trong các hướng dẫn và thông số kỹ thuật khác nhau, nhưng từ đó tìm ra chính xác những ký tự cần trích dẫn ở đâu không hoàn toàn đơn giản.
Gilles 'SO- ngừng trở nên xấu xa'

1
Tôi cũng tìm thấy cái này: tecmint.com/manage-linux-filenames-with-special-char character - nó không nhỏ gọn như danh sách của bạn, nhưng có nhiều ví dụ. (by-the-by: "Thông tin gì?" không phải là một phản hồi hay khi chủ đề ở đây liên quan đến các nhân vật)
slashmais
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.