Câu hỏi Làm thế nào để làm cho rm không đưa ra một lỗi nếu một tập tin không tồn tại?


Tôi đang viết một makefile mà sẽ làm sạch một số tập tin vô ích ở phần cuối của trình biên dịch. Nếu một mục tiêu đã được thực hiện, nó sẽ tất nhiên bỏ qua mục tiêu đó và tập tin vô dụng có thể không có ở đó. Vì vậy, nếu tôi làm điều này:

rm lexer.ml interpparse.ml interpparse.mli

Tôi có thể gặp lỗi vì một trong các tệp không tồn tại. có cách nào để nói không rm bỏ qua những tập tin này?

Khi đọc trang người đàn ông, tôi thấy tùy chọn sau:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

Nghe có vẻ như hầu hết những gì tôi muốn, nhưng tôi không thực sự chắc chắn về phần quyền hạn. Có cách nào để làm việc này không?


262
2017-11-27 16:43


gốc


Bạn đã thử một số rm trong một sandbox? Nó có vẻ như -f làm chính xác những gì bạn muốn, bất kể globbing. - JMD
Nếu các quyền sẽ không cho phép nó, rm sẽ với -f tùy chọn vẫn cố gắng xóa nó. Nó sẽ thất bại. Nó sẽ không cho bạn biết nó thất bại. Hữu ích nếu tên tập tin là một biến hoặc một glob. - LawrenceC


Các câu trả lời:


Các -f tùy chọn chắc chắn là những gì bạn muốn sử dụng.

Xác nhận về quyền truy cập tệp mà nó đề cập đến là:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

Vì thế rm sẽ cảnh báo bạn nếu bạn cố xóa một tệp mà bạn không có quyền ghi. Điều này được cho phép nếu bạn có quyền ghi vào thư mục nhưng hơi lạ, đó là lý do rm thường cảnh báo bạn về điều đó.


222
2017-11-27 16:54



Hầu hết, nhưng không phải tất cả các hệ thống sẽ hỏi (tôi nghĩ). Một số yêu cầu -i. - DaveParillo
Nếu bạn muốn thông báo lỗi, nhưng không phải là mã thoát lỗi, hãy xem câu trả lời bằng Giel Berkers. tôi sử dụng set -e trong tất cả các tập lệnh bash của tôi để tập lệnh thoát sau khi bất kỳ lệnh nào đưa ra lỗi. Tôi thường muốn một kịch bản cho tôi biết nếu rm đã đưa ra một lỗi, nhưng vẫn tiếp tục. tiếp tục. - cledoux


Một giải pháp khác là giải pháp này: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

Chỉ cần thêm câu lệnh OR sau lệnh của bạn:

rm -rf my/dir || true

Bằng cách này, khi tuyên bố # 1 thất bại (ném lỗi), hãy chạy câu lệnh # 2, đơn giản true.


77
2018-03-09 12:39



Nó in lỗi và tiếp tục thực hiện, đó là mong muốn cho trường hợp của tôi. - worldsayshi
Hay là rm -rf my/dir ||: thậm chí còn ngắn gọn hơn (: là viết tắt của true) - Godsmith
Giải pháp tốt hơn theo ý kiến ​​của tôi. Nó dễ dàng nhìn thấy những gì đang xảy ra và tại sao mã kết quả bị bỏ qua. Tôi thích nó! - Mavamaarten


Tôi đến trễ bữa tiệc, nhưng tôi luôn luôn sử dụng nó. Trong một makefile, thêm - vào đầu dòng để bỏ qua giá trị trả về của dòng đó. Giống như vậy:

-rm lexer.ml interpparse.ml interpparse.mli

69
2017-12-23 23:12



Điều này vẫn sẽ in lỗi cho giao diện điều khiển mặc dù, mà đào tạo bạn bỏ qua lỗi trong đầu ra thực hiện, mà có lẽ không phải là những gì bạn muốn. rm -rf là ​​một lựa chọn tốt hơn trong quan điểm của tôi. - Godsmith
@Godsmith Tôi muốn bỏ qua một lỗi hơn là buộc đệ quy xóa. Điều này có thể rất nghịch ngợm. Và +1 cho cú pháp cụ thể của makefile - Daishi
Nếu rm -rf có thể là "nghịch ngợm", điều đó có nghĩa là bạn đang sử dụng bên ngoài một thư mục trong điều khiển phiên bản. Tại sao? - Godsmith
Hãy cung cấp liên kết đến tài liệu. Có thể tìm thấy mô tả về tính năng này. - George Sovetov
@GeorgeSovetov gnu.org/software/make/manual/make.html#Errors - Robert Li


Nếu bạn không muốn sử dụng tùy chọn -f, một lựa chọn khác là:

rm filethatdoesntexist 2> /dev/null 

Điều này sẽ chỉ giữ cho các lỗi không được in.


8
2018-06-12 19:46



Rất tiếc, điều này sẽ vẫn cung cấp mã thoát lỗi. - Shaun McDonald


Nếu bạn tìm thấy một số cách để glob tên tệp, rm sẽ không phàn nàn nếu nó không thể tìm thấy một trận đấu. Vì vậy, một cái gì đó như lexer.m* interpparse.*, vv sẽ làm việc cho bạn (hãy cẩn thận bạn không xóa quá nhiều, tất nhiên). Cũng thế, -f là một cách hoàn toàn hợp lý để đi, miễn là bạn không hy vọng rằng quyền của tệp sẽ giúp bạn tiết kiệm từ việc xóa một tệp mà bạn không muốn - nếu bạn không muốn xóa nó, đừng đặt nó vào danh sách.


7
2017-11-27 16:48



Các globbing sẽ được ra khỏi câu hỏi là có một tập tin lexer.mll mà tôi không muốn xóa. Cảm ơn bạn đã cho thấy lý do tại sao -f là hợp lý. Tôi cho rằng tôi có xu hướng quá cẩn thận sau một quá nhiều sai lầm sudo rm -rf . - Jason Baker
Thậm chí không hạn chế hơn lexer.m? ...? Điều đó sẽ bắt lexer.ml và lexer.mz, nhưng không lexer.mll hoặc là lexer.mla. - JMD
@ JMD: Tôi cho rằng nó phụ thuộc vào trình bao của bạn và hỗ trợ mẫu phù hợp nào mà nó cung cấp cho globbing. - Nick Bastin


Tùy chọn -f có nghĩa là bạn sẽ không được nhắc nếu có điều gì đó không như mong đợi. Nó không có nghĩa là các điều khoản không được tính đến.

Nếu bạn không có đủ đặc quyền để xóa tệp, tệp sẽ không bị xóa.

NHƯNG, nếu bạn có đủ đặc quyền để thay đổi đặc quyền, tệp của bạn sẽ bị xóa. Đây là trường hợp khi bạn là chủ sở hữu của một tập tin với quyền chỉ đọc cho chủ sở hữu (-r --------). Là chủ sở hữu, bạn có thể chmod u+w, sau đó xóa nó: rm -f sẽ xóa tệp đó.


5
2017-11-27 19:27





Có thể có thể giúp một dòng tương tự với:

touch fakefile.exe fakefile.o && rm *.o *.exe

Tôi biết rằng điều này không phải là rất thông minh, nhưng nó thực hiện công việc.


3
2018-03-11 10:36





Một thay thế:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Makefiles quá xấu không thể chia sẻ các định nghĩa hàm vỏ trên các dòng.


2
2017-11-27 17:44



Bạn đã cố gắng sử dụng \ (dấu gạch chéo ngược) ở cuối hàng để nó tiếp tục? - some
@some: Có, chúng có thể được trải rộng trên nhiều dòng, nhưng để chia sẻ chúng qua các công thức nấu ăn, bạn phải đặt định nghĩa trong một biến làm cho. - reinierpost


Đây là những gì tôi sử dụng trong các kịch bản shell. Nó ẩn thông báo lỗi và mã lỗi.

rm doesnotexist 2> /dev/null || echo > /dev/null

2
2018-06-11 13:55





bạn có thể chạm vào các tập tin trước khi bạn rm chúng. sẽ tạo chúng nếu chúng không tồn tại :-)

touch lexer.ml interpparse.ml interpparse.mli
rm lexer.ml interpparse.ml interpparse.mli

0
2018-02-02 16:11





viết rm -rf ppp>/dev/null 2>&1 bạn mới nhận được thông báo lỗi Vấn đề xảy ra, nếu lỗi tạo ra không để STDERR 2 nhưng STDOUT 1 ... Nó diễn ra khi lệnh tạo ra không lỗi nhưng cảnh báo. Bạn cần đặt bộ lọc và xóa thông báo này. Nhưng trường hợp này là bình thường.


0
2017-08-19 09:47