Làm cách nào để rm không báo lỗi nếu tệp không tồn tại?


329

Tôi đang viết một tệp thực hiện sẽ dọn sạch một số tệp vô dụng vào cuối quá trình biên dịch. Nếu một mục tiêu đã được thực hiện, tất nhiên nó sẽ bỏ qua mục tiêu đó và tệp 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 rmđể bỏ qua các tập tin này?

Khi đọc trang man, 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ẻ gần như 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. Có cách nào để làm việc này không?


Bạn đã thử một số rmtrong một hộp cát? Nó trông giống như -flàm chính xác những gì bạn muốn, bất kể toàn cầu.
JMD

Nếu quyền không cho phép, rm sẽ với -ftùy chọn vẫn cố xóa nó. Nó sẽ thất bại. Nó sẽ không nói với bạn rằng nó thất bại. Hữu ích nếu tên tệp là một biến hoặc toàn cầu.
LawrenceC

chỉ để hoàn thiện: có rm --interactive=nevernhững hành động như rm -fngoại trừ nó trả về trạng thái thoát lỗi. xem tại đây để biết thêm chi tiết: unix.stackexchange.com/questions/72864/ Kẻ
lesmana

Câu trả lời:


282

Các -ftù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 là:

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

Vì vậy, rmsẽ 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 trên thư mục nhưng hơi lạ, đó là lý do tại sao rmthông thường cảnh báo bạn về nó.


1
Hầu hết, nhưng không phải tất cả các hệ thống sẽ yêu cầu (tôi nghĩ). Một số yêu cầu -i.
DaveParillo

1
Nếu bạn muốn thông báo lỗi, nhưng không phải mã thoát lỗi, hãy xem câu trả lời của Giel Berkers . Tôi sử dụng set -etrong tất cả các tập lệnh bash của mình để tập lệnh thoát ra sau khi bất kỳ lệnh nào xảy ra lỗi. Tôi thường muốn một kịch bản cho tôi biết nếu rmcó lỗi, nhưng vẫn tiếp tục. tiếp tục
cledoux

124

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 một câu lệnh OR sau lệnh của bạn:

rm -rf my/dir || true

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


4
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 29/2/2016

9
Hoặc chỉ rm -rf my/dir ||:để ngắn gọn hơn ( :viết tắt của từ true)
Godsmith

Các 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

76

Tôi đến bữa tiệc muộn, nhưng tôi sử dụng nó mọi lúc. Trong tệp tạo tệp, thêm -vào đầu dòng để bỏ qua giá trị trả về của dòng đó. Thích như vậy:

-rm lexer.ml xen kẽ.ml xen kẽ.mli

9
Điều này vẫn sẽ in lỗi cho giao diện điều khiển, điều này đào tạo bạn bỏ qua lỗi trong đầu ra make, đây có thể không phải là điều bạn muốn. Theo tôi, rm -rf là ​​một lựa chọn tốt hơn.
Godsmith

@Godsmith Tôi thà bỏ qua một lỗi hơn là buộc xóa đệ quy. Điều này có thể rất nghịch ngợm. Và +1 cho cú pháp cụ thể của
tệp thực hiện

Nếu rm -rf có thể "nghịch ngợm", điều đó có nghĩa là bạn đang sử dụng make bên ngoài một thư mục dưới sự kiểm soát phiên bản. Tại sao?
Godsmith

Vui lòng cung cấp một liên kết đến tài liệu. Có thể tìm thấy mô tả của tính năng này.
George Sovetov


14

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

rm filethatdoesntexist 2> /dev/null 

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


9
Thật không may, điều này vẫn sẽ cung cấp một mã thoát lỗi.
Shaun McDonald

8

Nếu bạn tìm cách nào đó để đặt tên tệp trên toàn cầu , rmsẽ không phàn nàn nếu không thể tìm thấy kết quả khớp. Vì vậy, một cái gì đó như lexer.m* interpparse.*, vv sẽ làm việc cho bạn (tất nhiên hãy cẩn thận, bạn sẽ không xóa quá nhiều). Ngoài ra, -flà một cách hoàn toàn hợp lý, miễn là bạn không hy vọng rằng các quyền của tệp sẽ cứu bạn khỏi việc xóa một tệp bạn không muốn - nếu bạn không muốn xóa nó, đừng đặt nó trong danh sách.


Globing sẽ ra khỏi câu hỏi vì có một tệp lexer.mll mà tôi không muốn xóa. Cảm ơn đã cho thấy tại sao -f là hợp lý. Tôi cho rằng tôi có xu hướng cẩn thận quá mức 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.mllexer.mz, nhưng không lexer.mllhoặc lexer.mla.
JMD

1
@JMD: Tôi cho rằng nó phụ thuộc vào vỏ của bạn và hỗ trợ phù hợp với mô hình nào mà nó cung cấp cho toàn cầu.
Nick Bastin

6

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

Nếu bạn không có đủ đặc quyền để xóa một tệp, nó 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 có 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 -fsẽ xóa tệp đó.


5

Có lẽ 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

Một thay thế:

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

Quá tệ Makefiles không thể chia sẻ định nghĩa hàm shell trên các dòng.


Bạn đã thử sử dụng \ (dấu gạch chéo ngược) ở cuối hàng để cho nó tiếp tục ở lần tiếp theo chưa?
một số

@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.
rebierpost

3

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

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

làm thế nào vềrm doesnotexist 2&> /dev/null
dùng8162

1

bạn có thể chạm vào các tập tin trước khi bạn rm chúng. sẽ tạo ra 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

1

viết cho rm -rf ppp>/dev/null 2>&1 bạn thông báo lỗi mới hơn Sự cố xảy ra, nếu lỗi tạo ra không phải là STDERR 2 nhưng STDOUT 1 ... Nó diễn ra khi lệnh tạo không phải lỗi mà là 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.


1

kiểm tra xem tập tin có tồn tại trước không, nếu có thì chuyển nó cho rm. Sau đó, các lỗi từ rm sẽ có ý nghĩa. -f hoặc bỏ qua thông báo lỗi thường bao gồm nhiều hơn những gì một người muốn. -f có thể làm những việc bạn không muốn làm.

if [ -f lexer.ml ]; then
  rm lexer.ml
fi

thêm nhiều mệnh đề kiểm tra nếu có nhiều tệp bạn muốn chắc chắn tồn tại.

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.