Ngăn người dùng gõ không gian ngẫu nhiên giữa rm và ký tự đại diện


29

Ý định:

rm -rf string*

Vấn đề:

rm -rf string *

Trường hợp đầu tiên là sử dụng rm hợp pháp và phổ biến, một lỗi đánh máy nhỏ có thể gây ra nhiều vấn đề trong trường hợp thứ hai. Có một cách đơn giản để bảo vệ thông minh chống lại một dấu vết vô tình hoặc ký tự đại diện hàng đầu?


8
Với lớp vỏ gần đây và được cấu hình tốt ( zshhoặc bash), tôi thà có thói quen nhấn phím tab (để kích hoạt tự động hoàn thành) trước khi nhấn phím quay lại
Basile Starynkevitch

2
touch -- -isẽ tạo một tệp -isẽ được chuyển đến rmdưới dạng tham số -ikhi bạn đưa ký tự đại diện vào các đối số của mình.
Tái lập Monica - M. Schröder

@ MartinSchröder: Nếu bạn tình cờ ở trong thư mục chứa tệp.
Tạm dừng cho đến khi có thông báo mới.

@ MartinSchröder Điều đó sẽ chỉ hoạt động nếu bạn gõ rm *. Nếu bạn đánh máy rm name *, nó sẽ mở rộng sang rm name -i other names. -isẽ không được xử lý như một tùy chọn vì nó không có trước tên tập tin.
Barmar

1
Thông thường, một người dùng chỉ làm điều này một lần.
tedder42

Câu trả lời:


37

Một DEBUGcái bẫy có thể được viết để hủy bỏ các lệnh trông đáng ngờ. Có thể thêm đoạn mã sau hoặc mã tương tự vào ~/.bashrc:

shopt -s extdebug
checkcommand() {
  if [[ $BASH_COMMAND = 'rm -r'*' *' ]]; then
    echo "Suppressing rm -r command ending in a wildcard" >&2
    return 1
  fi
  # check for other commands here, if you like
  return 0
}
trap checkcommand DEBUG

Điều chỉnh logic theo sở thích.

.


47

Không có cách nào để hệ thống chống đạn hoàn toàn. Và thêm "Bạn có chắc không?" nhắc nhở mọi thứ là phản tác dụng và dẫn đến "Tất nhiên tôi chắc chắn." phản ứng đầu gối.

Một mẹo tôi nhặt được từ một cuốn sách trong nhiều năm qua là trước tiên hãy làm ls -R blah*sau đó, làm rm -fr blah* nếu và chỉ khi danh sách mà tôi bật lên đạt được những gì tôi muốn đạt được.

Nó đủ dễ để thực hiện lslệnh trước, sau đó , xóa ls -Rvà thay thế bằng rm -fr.

Câu hỏi cuối cùng là "Nếu thông tin có giá trị với bạn, thì bản sao lưu của bạn ở đâu?"


4
Thay vì mũi tên lên, bạn có thể sử dụng ^ls -R^rm -rf^và có thể đặt làm bí danh
exussum

FWIW, đây là ls -Rđiều mà về cơ bản tôi luôn luôn làm, nhưng nó rất bản năng vào thời điểm này, nó trượt tâm trí ý thức của tôi khi tôi hình thành bằng câu trả lời. Vì vậy, +1 cho điều đó.
JakeGould 14/1/2015

Điều này cũng có lợi thế là nó sẽ không gây hại nếu bạn nhấn phím enter hoặc gập chuột và dán thứ gì đó bằng dòng mới. Đôi khi tôi nhập mọi thứ theo thứ tự kém hiệu quả hơn để đảm bảo an toàn hơn, ví dụ cat > .log, sau đó quay lại và dán hoặc lấy tên tệp trước .log. Vì vậy, không có điểm nào tôi có > valuablefiletrên cmdline.
Peter Cordes

Tôi sử dụng rm bí danh rm -i, vì vậy tôi thường chỉ soạn lệnh rm của mình và sau đó đặt một \ ở đầu dòng. ( \rmtránh mở rộng bí danh cho rm, vì một phần của từ đã được trích dẫn). Nếu tôi cần một -rhoặc -f, vâng, đôi khi tôi bắt đầu với lsthay vì rm, hoặc chỉ để lại -rfmột phần. (chỉnh sửa, làm thế nào để bạn có được một định dạng mã gạch chéo ngược? bquote bslash bslash bquote không thành công.
Peter Cordes

8

Bạn có thể tự đào tạo để sử dụng, nói, rmrf thay cho rm -rf?

Nếu vậy, hàm bash này sẽ cung cấp cho bạn cơ hội để xem điều gì sẽ thực sự xảy ra trước khi xác nhận lệnh:

rmrf() { echo rm -rf "$@"; read -p "Proceed (y/N)? "; [ "${REPLY,,}" = y ] && rm -rf "$@"; }

Để làm cho chức năng này vĩnh viễn, hãy thêm dòng này vào ~/.bashrctệp trên mỗi máy tính bạn sử dụng.

So sánh với rmbí danh chung

Thông thường để định nghĩa một bí danh:

alias rm='rm -i'

Điều này có hai hạn chế:

  1. Nếu bạn phụ thuộc vào bí danh này, thì bạn sẽ bị sốc khi bạn ở trên máy hoặc trong môi trường không có nó. Ngược lại, cố gắng chạy rmrftrên một máy không có chức năng đó sẽ trả lại vô hạicommand not found .

  2. Bí danh này không giúp ích gì trong trường hợp của bạn vì -ftùy chọn mà bạn cung cấp trên dòng lệnh sẽ ghi đè -itùy chọn trong bí danh.


4
Một ý tưởng không tồi. Nhưng nó phụ thuộc vào chức năng này được cài đặt và có sẵn trên bất kỳ hệ thống nào mà người dùng này đang sử dụng. Vì vậy, giả sử họ đăng nhập vào một máy chủ từ xa cho một số công việc và chạy sai rm -rflệnh, điều gì xảy ra? Tạo các hàm giả như thế này cuối cùng chỉ làm phức tạp một giải pháp đơn giản: Chỉ cần cẩn thận hơn và hiểu các quyền là gì.
JakeGould

4
@JakeGould Và đừng sử dụng rm -f trừ khi bạn thực sự cần .
một CVn

1
Tại sao phải bận tâm rmrf, thay vì chỉ tạo một hàm shell rmđể kiểm tra các đối số -rhoặc -rf, và đưa ra logic đặc biệt trong trường hợp đó, nếu không thì gọi trực tiếp command rm "$@"để gọi rmlệnh thực ?
Charles Duffy

3
Bạn sử dụng một tên khác để bạn không tự bắn vào chân mình khi ghi đè của bạn không có ở đó. Và tôi đồng ý với @ MichaelKjorling, bạn không cần -fnếu bạn không có -i. Rời khỏi -fcung cấp cho bạn cảnh báo thêm trước khi xóa một tập tin chỉ đọc, ví dụ.
Peter Cordes

6

Nếu tôi đang ở một tình huống mà xóa các tập tin sai là một việc thực sự lớn, một trong những điều tôi đã thực hiện là tạo ra một thư mục thùng rác, giống như mkdir trashcan, và sau đó tôi có một kịch bản rmTrashcantrong đó có mộtrm -rf trashcan/* hoặc rm -rf *hoặc tương tự, được viết rất cẩn thận và kiểm tra nhiều lần.

Theo cách đó, nếu tôi mắc lỗi, lỗi là ở mvlệnh chứ không phải rmlệnh. Khi tôi làm một lsvà tự tin về chính xác những gì tôi đang xóa, rmTrashcanthực sự công việc bẩn sẽ an toàn.

Nó cũng cực kỳ thuận tiện cho tình huống tôi phải xóa các bản sao lưu. Tôi có thể mvtoàn bộ một tháng sao lưu vào thùng rác, mvsố ít tôi muốn giữ lại (ngày đầu tiên, ngày 15 tháng) trở lại vào bản sao lưu, sau đó rmTranshcanlà phần còn lại. Tự thực hiện một lệnh tương tự rất khó thực hiện rmvà thực hiện theo cách này cho phép lscác bản sao lưu tự tin vào những tệp tôi để lại (thay vì chỉ liệt kê các tệp tôi định xóa)


4

Thay vì làm phiền với hai lệnh ( lsrm), tôi nghĩ một cách đơn giản và dễ dàng hơn là sử dụng find:

find . -maxdepth 1 -name "string*" -delete

Nếu bạn vô tình gõ, "string *"nó sẽ xóa các tệp có tên string charsstring letters(dù sao bạn cũng muốn), nhưng nó sẽ không lấy mọi tệp như* trong shell.

Ngoài ra, bạn có thể rời khỏi -deleteđể xem những tập tin nào sẽ xóa, sau đó nhấn mũi tên và gõ -deletedễ dàng hơn so với gõ ^ls -R^rm -rfhoặc vô nghĩa khác.


A findsẽ thực hiện tìm kiếm lồng nhau cho các tệp khớp với thay vì chỉ các tham số rõ ràng được khai báo trên dòng lệnh. Tôi nghĩ rằng điều này bỏ lỡ các dấu hiệu. Tôi có thể sai mặc dù.
sát thủ

3

Có một cách đơn giản để bảo vệ thông minh chống lại một dấu vết vô tình hoặc ký tự đại diện hàng đầu?

Không hẳn vậy. Nó được đề xuất trong một câu trả lời khác, bạn có thể tạo một lệnh tùy chỉnh để thêm lời nhắc trước khi thực hiện một tác vụ. Nhưng vấn đề với lệnh tùy chỉnh này là nó phải được cài đặt có ý thức trên các hệ thống bạn đang làm việc. Và ngay cả khi nó được cài đặt, vấn đề là phản xạ của bạn để đạt đượcy để hoàn thành nhiệm vụ có thể xảy ra.

Có nghĩa đây là tất cả vấn đề giao diện người dùng ngay cả khi nó ở cấp độ dòng văn bản / lệnh. Có bao nhiêu lưới an toàn mà bạn mong đợi sẽ có để bảo vệ bạn khỏi làm điều gì đó bạn không nên làm? Nó giống như một chiếc kéo: Nếu bạn sơ suất và trượt và cắt tay trong khi có ý định cắt vải hoặc giấy, ai là người có lỗi? Hoặc thậm chí là đèn giao thông và biển báo dừng: Thực sự không có gì ngăn tài xế chạy đèn hoặc bỏ qua các biển báo giao thông ngoài nhận thức cấp tính về những gì có thể xảy ra nếu họ thực hiện hành vi nguy hiểm như vậy.

Điều đó nói rằng giải pháp tốt nhất, thực tế nằm ở quyền hệ thống cho người dùng cũng như các nhóm. Đó là mạng lưới an toàn thực sự tốt nhất / duy nhất để bảo vệ người dùng khỏi chính họ.

Nếu bạn đang làm việc trên một hệ thống mà bạn là người duy nhất truy cập vào hệ thống, bạn có thể bị cám dỗ chỉ chmod 777mọi thứ, nhưng đó không phải là cách một hệ thống hợp lý được thiết lập. Thay vào đó, quyền nên là một cái gì đó giống như 755cho tất cả các thư mục và 644cho tất cả các tệp không thể thực thi. Các tập tin thực thi nên có 755ít nhất, nhưng thậm chí có thể744 khi bạn chỉ muốn người khác đọc nhưng không chạy các tệp.


2

Hãy thử soạn rmlệnh ban đầu của bạn mà không có -fcờ, nhưng -ithay vào đó, nó rmsẽ nhắc bạn cho mỗi tệp mà nó dự định xóa. Đối với các thao tác xóa đệ quy nhỏ, bạn có thể giữ yphím, một khi bạn chắc chắn rằng lệnh đã được gõ đúng. Đối với các thao tác xóa lớn, bạn có thể hủy bỏ thao tác và sử dụng lịch sử dòng lệnh để cẩn thận thay đổi -ithành a -f.


Bạn thực sự phải nhấn y[RETURN]mọi tập tin, không có gì bạn có thể giữ với GNU rm. Chỉnh sửa ra -ilà cách để đi, một khi bạn đã gõ lệnh đúng. Sau đó, bạn nhận được một lời nhắc chỉ trên một tệp chỉ đọc và có thể những thứ khác.
Peter Cordes

1
Chỉ sử dụng rm -Iđể nó chỉ nhắc một lần và chỉ để xóa nguy hiểm tiềm ẩn (ví dụ như nhiều tệp.)
Nick Matteo

1
Trong các diễn đàn ít mang tính xây dựng hơn, câu trả lời của tôi sẽ là một câu trả lời "Nếu việc đánh máy / hiệu đính của bạn tệ đến mức đó, thì bạn không có doanh nghiệp nào sử dụng 'rm -rf' bằng ký tự đại diện." Tôi không biết về công tắc -tôi ... phải được đặt vào <20 năm trước; "Lần cuối cùng tôi làm" người đàn ông rm ". :)
Nevin Williams

2

rm có -i-Icờ để xác nhận trước khi loại bỏ. Trước đây, một số bản phân phối đã bật chúng theo mặc định. Đây là một ý tưởng khủng khiếp. Cung cấp cho người dùng quá nhiều hộp thoại xác nhận cho các hoạt động bình thường và họ sẽ bắt đầu thường xuyên xác nhận chúng. Điều này chỉ chuyển yêu cầu "cẩn thận" (luôn luôn là cờ đỏ) sang hộp thoại mới và khó chịu hơn. "Vâng. Vâng. Vâng. Vâng! CÓ! Trời ơi, máy tính ngu ngốc chỉ cần xóa các tập tin YESYESYESYESYES - CRAP TÔI CÓ Ý NGH NOA KHÔNG! NOOOOOOO!" Đây là vấn đề hộp thoại "Có, nhưng ý tôi là không". Câu trả lời này cung cấp một lời giải thích trực quan về lý do tại sao các hộp thoại xác nhận đến không đúng lúc.

Loại sai lầm bạn mô tả là một trượt , "việc thực hiện một hành động mà không phải là những gì đã được dự định". Người dùng thường ngay lập tức nhận ra lỗi và biết chính xác cách khắc phục. Thật không may, Unix không cung cấp cho người dùng cơ hội, rm xóa tệp ngay lập tức. Mọi hệ điều hành khác đều giải quyết vấn đề này bằng cách cho phép xóa hoàn toàn, ít nhất là trong một thời gian, bằng cách sử dụng Thùng rác.

Có nhiều hệ thống rác khác nhau dành cho Unix và câu trả lời này chứa đầy những gợi ý .

Câu hỏi là bí danh rm hay không bí danh rm. Ưu điểm cho răng cưa rm ...

  1. Bạn không thể bỏ qua việc quên sử dụng giải pháp thay thế rm.

Nhược điểm cho răng cưa rm ...

  1. Bạn có thể tin tưởng vào nó trên các hệ thống không có nó.
  2. Có thể gây ra vấn đề khi đĩa gần đầy.
  3. Cần cơ sở hạ tầng để định kỳ đổ rác.
  4. Phải chắc chắn không can thiệp vào hành vi dự kiến ​​của rm trong các chương trình.
  5. Có thể không mô phỏng đầy đủ rm.

Nếu bạn theo dõi đối số đầu tiên quá xa, bạn sẽ sử dụng vi (không phải vim, vi), csh (không phải tcsh, csh) và các tiện ích cổ khác vì chúng có sẵn trên toàn cầu. Tuy nhiên, có một nguy cơ quá quen thuộc với môi trường của bạn. Tôi thích mang theo các tiện ích của mình và làm cho nó dễ dàng nhất có thể. YMMV.

Hai và ba là vấn đề kỹ thuật. Chúng có thể được giải quyết bằng một công việc gặt thông minh kiểm tra kích thước của thùng rác và định kỳ dọn dẹp mọi thứ, tương tự như một tmpreaper . Đây có thể là một công việc định kỳ hoặc một phiên bản thông minh hơn có thể sử dụng các cơ sở hạ tầng sự kiện hệ thống tệp khác nhau có sẵn trên nhiều bản phân phối Linux trên máy tính để bàn. Điều này không đơn giản, và thậm chí khó hơn để làm hiệu quả. Tốt hơn là tìm một hệ thống hiện có hơn là cố gắng làm cho riêng bạn.

Thứ tư có thể được xử lý bằng cách biến rm mới của bạn thành bí danh shell alias rm='trash', sau đó nó sẽ không ảnh hưởng đến các chương trình.

Thứ năm là một vấn đề tôi để cho người đọc giải quyết. rm không có nhiều công tắc.


Tôi có bí danh rm rm -i, nhưng tôi thường sử dụng \rmđể có được hành vi không thiên vị. Tôi gõ rm -ibất cứ lúc nào tôi đang QUY HOẠCH để nói không với một trong các đối số. Đôi khi tôi bắt đầu lệnh với lstư cách là lệnh, sau đó chỉ đưa vào \ rm khi tôi hoàn thành. Vì vậy, không có cách nào tôi có thể vô tình quay trở lại rm -rf /thay vì/.../file
Peter Cordes

rm -Ihoặc rm --interactive=oncelà rất xa, ít gây phiền nhiễu hơn rm -ivà vẫn gây ra nhiều điều nguy hiểm (nó chỉ nhắc khi có hơn 3 tệp hoặc nếu nó được đệ quy và chỉ ONCE thay vì FOR EACH FILE.)
Nick Matteo

@Kundor Có, và nó không thay đổi phương trình. Nó có thể làm cho nhiều khả năng người dùng sẽ bỏ qua nó. Người dùng có một mục tiêu: xóa công cụ. Lời nhắc nói "bạn có chắc chắn muốn xóa nội dung bạn vừa nói với tôi để xóa không?" Người dùng vẫn cố định mục tiêu xóa nội dung, không xác minh nội dung cần xóa, vì vậy họ nói "có" mà không cần suy nghĩ. -icó thể cho người dùng thời gian để thay đổi mục tiêu. Câu trả lời này cho một câu hỏi liên quan đặt ra tất cả.
Schwern

@Schwern: nhưng không ai có thể sống với rm -ihơn 30 giây mà không tắt nó đi. Trong khi đó rm -Ichỉ nhắc khi có khả năng bạn đã làm hỏng; lời nhắc chỉ đưa ra để xóa lớn. Khi bạn đang cố gắng xóa một vài điều và lời nhắc được đưa ra, bạn sẽ ngạc nhiên và nhận ra rằng bạn đã vô tình gõ "foo *".
Nick Matteo

@Kundor Xóa hơn ba tệp và xóa đệ quy (xác nhận bị vô hiệu hóa theo thói quen -rftôi vừa phát hiện) là các proxy kém để phát hiện khả năng bắt vít. Muốn xóa một thư mục con không có khả năng làm hỏng. Thông báo không hữu ích vì nó chỉ xác nhận những gì người dùng đã nói sẽ làm mà không cần thêm thông tin hữu ích vào thời điểm mà người dùng không muốn xác minh. "rm: xóa 1 đối số đệ quy?" "Vâng, xóa thư mục, tôi chỉ bảo bạn làm điều đó! ... chờ đã, thư mục đó là gì? CRAP !!!"
Schwern

2

Tôi dạy mọi người về !$= đối số cuối cùng trong thủ thuật lệnh cuối cùng:

% ls job[XYZ].*
jobX.out1
jobX.out2
[rest of the matches]

% rm !$

Điều này cho phép kiểm tra việc mở rộng ký tự đại diện, và sau đó sử dụng cùng một mẫu hình cầu chính xác mà không có khả năng chèn một khoảng trắng trước *.

Ngoài ra tôi đề nghị mọi người không bao giờ cắt và dán một mẫu ký tự đại diện trên một dòng lệnh có khả năng phá hủy. Bởi vì trong tay tôi đã có vấn đề :)

Một công nghệ trong phòng thí nghiệm của tôi vừa mắc lỗi này vào tuần trước (3 tháng làm việc) - và vâng, chúng tôi đã có một bản sao lưu (chậm 1 ngày).


0

Mọi người dường như đang nói: "Cẩn thận hơn", "Đừng tạo bí danh / lời nhắc xác nhận vì bạn sẽ trở nên quen thuộc khi không chú ý đúng mức đến nó".

Mát mẻ, và tất cả mọi thứ. Ý tôi là, tôi không nghĩ bạn nên tạo một bí danh cho rm(cũng không rmrf, vì bạn có thể dễ dàng vặn nó lên và gõ lệnh thực sự).

Nhưng tại sao bạn không thể tạo bí danh / tập lệnh và gọi nó, nói removevà chỉ cung cấp cho nó một đối số (ví dụ: $ 1)? Ký tự đại diện phải là 2 đô la, vì không gian vô tình (amiright?) Và do đó tập lệnh / trình bao bọc / bí danh của bạn sẽ không được cung cấp lần thứ hai. Có, bạn chỉ có thể thực hiện một bộ xóa (với ký tự đại diện) tại một thời điểm, nhưng đó là giá bạn phải trả.

Nếu tôi đang viết một cái gì đó tốt đẹp, tôi có thể cho nó biết số lượng tệp và thư mục mà nó dự định xóa và tổng kích thước của những thứ tôi đang xóa, sau đó yêu cầu xác nhận, nhưng điều đó có thể cản trở dòng chảy của bạn. Có thể làm cho đó là một tùy chọn cờ trên remove? (-tôi). Bạn cũng có thể muốn kiểm tra $ 1 để xem nếu đó chỉ là một ký tự đại diện duy nhất và yêu cầu xác nhận và liệt kê thư mục mà bạn thực sự đang ở.


Như một bên, có một số rmthay thế ra khỏi đó. Nhiều người đang cố gắng tuân thủ thùng rác máy tính để bàn UI. Một số trong đó có thể đáng để xem xét.


6
Bí danh "xóa" của bạn sẽ không bao giờ xóa nhiều hơn một tệp cùng một lúc. Bạn không thể sử dụng ký tự đại diện, vì trình bao mở rộng nó trước khi lệnh nhìn thấy nó.
thánh ca

Vì vậy, làm một eval trên nó, và sau đó kéo nó vào kịch bản?
dùng3082

Vì vậy, bạn muốn gõ remove \*? Nếu tập lệnh của bạn cho phép trình bao toàn cầu mở rộng đầu vào của nó, tôi không thấy nó giúp ích nhiều.
Peter Cordes

0

Một mẹo rất đơn giản là đặt -rfở cuối: rm whatever* -rf
Điều này làm giảm đáng kể tỷ lệ lỗi, bởi vì bạn nhập nhiều ký tự hơn sau *đó, vì vậy bạn có nhiều thời gian hơn để xem lỗi chính tả.
Điều này không giải quyết mọi thứ. Chỉ là một mẹo đơn giản hàng ngày.

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.