2013-10-01 15 views
22

Tôi thường tương tác lặp qua ví dụ: các tệp của tôi và muốn thực hiện một hoạt động cụ thể trên tất cả chúng, giả sử tôi muốn đổi tên tất cả các tệp:Hiển thị các lệnh mà không cần thực hiện chúng

for file in $(ls); do mv "$file" "${file}_new"; done 

Điều này làm việc tốt. Nhưng trước khi gọi lệnh này, tôi muốn xem những gì nó thực sự không có gì, vì vậy tôi sẽ thêm một tiếng vang trước

for file in $(ls); do echo mv "$file" "${file}_new"; done 

sau đó nó chỉ cho tôi tất cả các lệnh nó sẽ gọi. Nếu tôi hài lòng với họ, tôi xóa echo và thực hiện nó.

Tuy nhiên, khi các lệnh này tinh tế hơn một chút có thể bao gồm đường ống hoặc nhiều lệnh, điều này không hoạt động nữa. Tất nhiên tôi có thể sử dụng ' để các ký tự đặc biệt không được giải thích, nhưng sau đó tôi không có mở rộng tham số. Tôi cũng có thể thoát khỏi những nhân vật đặc biệt, nhưng điều này sẽ rất tẻ nhạt.

Câu hỏi của tôi là, cách tốt nhất để làm điều này là gì? Tôi đã đọc trong man bash về tùy chọn -n, có "Đọc lệnh nhưng không thực thi chúng. Điều này có thể được sử dụng để kiểm tra tập lệnh shell cho lỗi cú pháp. Điều này bị bỏ qua bởi các trình tương tác". Đây chính xác là những gì tôi cần, nhưng tôi cần nó cho một hệ vỏ tương tác. Lưu ý rằng các tùy chọn -x hoặc -v không giúp đỡ, vì nó sẽ không chỉ hiển thị lệnh, mà còn gọi nó và sau đó có thể đã quá trễ rồi.

+1

Về mặt kỹ thuật, không có cách nào để đạt được điều đó. – devnull

+0

Hoặc, bạn có thể * alias-empty * mỗi lệnh vào một cái gì đó như 'bí danh = 'bash -c" "'', để tham số được chấp nhận, nhưng không có gì được thực hiện. Bạn có thể chạy một vòng lặp * alias-emptifier *, thực thi tiến trình bạn muốn, và sau đó * alias-restore * các lệnh - phục hồi chức năng của chúng. – Rubens

+2

Bằng cách này, việc sử dụng 'cho tệp trong $ (ls) 'là hy sinh một đứa trẻ (quy trình) không có lý do chính đáng. Tại sao không sử dụng 'cho tập tin trong *'? – cdarke

Trả lời

21

This chủ đề sẽ cho bạn biết lý do tại sao các tùy chọn để hiển thị các lệnh thay vì thực hiện những (còn được gọi chạy khô) sẽ không bao giờ được thực hiện cho bash.

Tham khảo các phản hồi từ Eric Blake:

> Câu hỏi của tôi là lý do tại sao có thể không như một tùy chọn hoặc được cung cấp,

Một chút suy nghĩ sẽ hiển thị tại sao điều này sẽ không bao giờ được thực hiện. Có gì sẽ như một đầu ra tùy chọn sau:

if complex_command; then 
    foo=command1 
else 
    foo=command2 
fi 
$foo args 

Trên dòng cho $foo args, không có cách nào để biết những gì $foo mở rộng đến trừ khi bạn đã thực hiện trước đó (không chỉ quét) các complex_command. Do đó, không có cách nào để làm khô những gì kết quả cuối cùng của sẽ không có hoạt động, nhưng mọi thứ đang hoạt động là truy cập đến mục tiêu chạy khô.

Điều đó nói rằng, bạn có thể quan tâm đến các dự án bashdb, trong đó sử dụng móc bash để cung cấp một giao diện gỡ lỗi nơi bạn có thể đơn bước thông qua một kịch bản bash; nó không giống như nói cho bạn biết kịch bản sẽ làm gì, nhưng ít nhất nó cũng cho phép bạn kiểm soát số lượng hoặc ít của tập lệnh thực sự chạy.

16

Không có tùy chọn cho "chạy khô" như explained by devnull nhưng có một cách giải quyết đơn giản:

debug= 
#debug=echo 

$debug mv "$file" "${file}_new" 

Nếu bạn loại bỏ các bình luận từ việc chuyển nhượng thứ hai (mà không thay đổi bất cứ điều gì khác), bạn kích hoạt " chạy khô "cho lệnh nguy hiểm mv.

Một cách tiếp cận phức tạp hơn sẽ được kiểm tra một số điều kiện (như một tùy chọn dòng lệnh):

debug= 
if [[ ...enable dry run?... ]]; then 
    debug=echo 
fi 

Lưu ý: Việc phân rỗng là chỉ cần thiết khi bạn có tùy chọn -u ("Hãy đối xử với biến unset như một lỗi khi thay thế. ") được bật.

+0

Điều gì phải được gán để hoàn nguyên gỡ lỗi thành cài đặt khởi tạo của nó, bất kể cài đặt đó là gì? PS: Đối với một số lý do có vẻ như gỡ lỗi là không có sẵn trong bash của tôi –

+1

@GeorgeVasiliou 'debug' chỉ là một biến địa phương mà tôi hoặc chỉ định không có gì hoặc một lệnh mà chỉ in các đối số của nó (' echo'). Để hoàn nguyên hiệu ứng, chỉ cần gán lại không có gì: 'debug ='. –

+0

Điều này sẽ không hoạt động nếu bạn sử dụng chuyển hướng. –

6

Có một gói github gọi là có lẽ, đây là một ví dụ:

$ maybe rm file 
> maybe has prevented rm file from performing 1 file system operations: 
> 
> delete /home/user/file 
> 
> Do you want to rerun rm file and permit these operations? [y/N] 
Các vấn đề liên quan