Hướng dẫn cho người mới bắt đầu với Shell Scripting 2: Đối với vòng lặp

Mục lục:

Hướng dẫn cho người mới bắt đầu với Shell Scripting 2: Đối với vòng lặp
Hướng dẫn cho người mới bắt đầu với Shell Scripting 2: Đối với vòng lặp

Video: Hướng dẫn cho người mới bắt đầu với Shell Scripting 2: Đối với vòng lặp

Video: Hướng dẫn cho người mới bắt đầu với Shell Scripting 2: Đối với vòng lặp
Video: Trưa 5/6: Công An Vẫn Chưa Tìm Được Kẻ Thảm Sát 3 Người Ở Khánh Hòa, Luật Sư Nhận Định Sốc | SKĐS - YouTube 2024, Tháng tư
Anonim
Nếu bạn muốn xây dựng niềm tin geek của bạn, hãy tham gia với chúng tôi cho phần thứ hai trong loạt kịch bản lệnh shell của chúng tôi. Chúng tôi có một số chỉnh sửa, một số cải tiến đối với tập lệnh của tuần trước và hướng dẫn về vòng lặp cho người không được khởi tạo.
Nếu bạn muốn xây dựng niềm tin geek của bạn, hãy tham gia với chúng tôi cho phần thứ hai trong loạt kịch bản lệnh shell của chúng tôi. Chúng tôi có một số chỉnh sửa, một số cải tiến đối với tập lệnh của tuần trước và hướng dẫn về vòng lặp cho người không được khởi tạo.

Tập lệnh datecp được xem xét lại

Trong phần đầu tiên của hướng dẫn kịch bản shell của chúng tôi, chúng tôi đã tạo một tập lệnh sao chép tệp vào thư mục sao lưu sau khi thêm ngày vào cuối tên tệp.

Samuel Dionne-Riel đã chỉ ra trong các nhận xét rằng có một cách tốt hơn để xử lý các tham chiếu biến đổi của chúng ta.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

sẽ hoạt động như dự định miễn là các biến mở rộng không có dấu cách trong chúng. Nếu bạn gọi kịch bản theo cách này:

datecp 'my old name' 'my new name'

việc mở rộng sẽ dẫn đến lệnh này:

cp my new name my old name.the_date

mà thực sự có 6 đối số.

Để giải quyết đúng vấn đề này, dòng cuối cùng của tập lệnh phải là:

cp '$1' '$2.$date_formatted'

Như bạn có thể thấy, thay đổi dòng của tập lệnh của chúng tôi từ:

cp -iv $1 $2.$date_formatted

đến:

cp -iv “$1” “$2”.$date_formatted

sẽ giải quyết vấn đề này khi sử dụng tập lệnh trên các tệp có dấu cách trong tên. Samuel cũng làm cho điểm rằng khi sao chép và dán mã từ trang web này (hoặc internet nói chung) hãy chắc chắn để thay thế dấu gạch ngang thích hợp và báo giá cho những "typographically tốt hơn" mà thường thay thế chúng. Chúng tôi cũng sẽ làm nhiều hơn để đảm bảo mã của chúng tôi được sao chép / dán thân thiện hơn.;-)

Một người bình luận khác, Myles Braithwaite, đã quyết định mở rộng kịch bản của chúng tôi để ngày đó xuất hiện trước phần mở rộng của tệp. Vì vậy, thay vì

tastyfile.mp3.07_14_11-12.34.56

chúng tôi sẽ nhận được điều này:

tastyfile.07_14_11-12.34.56.mp3

mà kết thúc là một chút thuận tiện hơn cho hầu hết người dùng. Mã của anh ấy có sẵn trên trang GitHub của anh ấy. Chúng ta hãy xem những gì anh ta sử dụng để tách rời tên tệp.

date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)

cp -iv $1 $file_name-$date_formatted.$file_extension

Tôi đã thay đổi định dạng một chút, nhưng bạn có thể thấy rằng Myles tuyên bố chức năng ngày của anh ấy trong Dòng 1. Trong Dòng 2, anh ấy sử dụng lệnh “echo” với đối số đầu tiên của tập lệnh để xuất ra tên của tệp. Ông sử dụng lệnh ống để lấy đầu ra đó và sử dụng nó làm đầu vào cho phần tiếp theo. Sau đường ống, Myles gọi lệnh “awk”, đó là một chương trình quét mẫu mạnh mẽ. Sử dụng cờ -F, anh ta nói lệnh rằng ký tự tiếp theo (sau dấu cách) là cái sẽ xác định “dấu tách trường”. Trong trường hợp này, đó là một khoảng thời gian.

Bây giờ, awk thấy một tập tin có tên "tastyfile.mp3" như là bao gồm hai lĩnh vực: "deliciousfile" và "mp3". Cuối cùng, anh ta sử dụng

‘{print $NF}’

để hiển thị trường cuối cùng. Trong trường hợp tệp của bạn có nhiều dấu chấm - do đó làm cho awk thấy nhiều trường - nó sẽ chỉ hiển thị trường cuối cùng, là phần mở rộng tệp.

Trong Dòng 3, anh ta tạo một biến mới cho tên của tệp và sử dụng lệnh "basename" để tham chiếu mọi thứ trong $ 1 ngoại trừ phần mở rộng của tệp. Điều này được thực hiện bằng cách sử dụng tên cơ sở và cho nó $ 1 làm đối số của nó, sau đó thêm một khoảng trắng và phần mở rộng của tệp. Phần mở rộng của tệp được tự động thêm vào vì biến tham chiếu Dòng 2. Điều này sẽ thực hiện

tastyfile.mp3

và biến nó thành

tastyfile

Sau đó, ở dòng cuối cùng, Myles tập hợp lệnh sẽ xuất mọi thứ theo thứ tự. Lưu ý rằng không có tham chiếu đến $ 2, một đối số thứ hai cho tập lệnh. Kịch bản cụ thể này sẽ sao chép tập tin đã nói vào thư mục hiện tại của bạn để thay thế. Công việc tuyệt vời Samuel và Myles!

Chạy tập lệnh và $ PATH

Chúng tôi cũng đề cập đến trong bài viết Cơ bản của chúng tôi rằng các tập lệnh không được phép tham chiếu dưới dạng các lệnh theo mặc định. Tức là, bạn phải trỏ đến đường dẫn của tập lệnh để chạy nó:

./script

~/bin/script

Tuy nhiên, bằng cách đặt tập lệnh của bạn vào ~ / bin /, bạn có thể chỉ cần nhập tên của chúng từ bất kỳ đâu để chúng chạy.

Các nhà bình luận đã dành một chút thời gian để tranh luận về mức độ thích hợp của nó, vì không có bản phân phối Linux hiện đại nào tạo ra thư mục đó theo mặc định. Hơn nữa, không ai thêm nó vào biến $ PATH theo mặc định, đó là những gì được yêu cầu để cho các kịch bản chạy như lệnh. Tôi hơi bối rối vì sau khi kiểm tra biến $ PATH của tôi, những người bình luận đã đúng, nhưng các kịch bản gọi điện vẫn hoạt động cho tôi. Tôi đã tìm ra lý do tại sao: nhiều bản phân phối Linux hiện đại tạo một tệp đặc biệt trong thư mục chính của người dùng -.profile.

Tệp này được đọc bởi bash (trừ khi.bash profile có trong thư mục chính của người dùng) và ở dưới cùng, có phần thêm thư mục ~ / bin / vào biến $ PATH nếu nó tồn tại. Vì vậy, bí ẩn đó được xóa sạch. Trong phần còn lại của loạt bài này, tôi sẽ tiếp tục đặt các tập lệnh trong thư mục ~ / bin / vì chúng là các tập lệnh người dùng và có thể được người dùng điều hành. Và, có vẻ như chúng ta không thực sự cần phải gây rối với biến $ PATH bằng tay để làm cho mọi thứ hoạt động.
Tệp này được đọc bởi bash (trừ khi.bash profile có trong thư mục chính của người dùng) và ở dưới cùng, có phần thêm thư mục ~ / bin / vào biến $ PATH nếu nó tồn tại. Vì vậy, bí ẩn đó được xóa sạch. Trong phần còn lại của loạt bài này, tôi sẽ tiếp tục đặt các tập lệnh trong thư mục ~ / bin / vì chúng là các tập lệnh người dùng và có thể được người dùng điều hành. Và, có vẻ như chúng ta không thực sự cần phải gây rối với biến $ PATH bằng tay để làm cho mọi thứ hoạt động.

Lặp lại các lệnh với các vòng lặp

Hãy tìm đến một trong những công cụ hữu ích nhất trong kho vũ khí chuyên nghiệp để xử lý các nhiệm vụ lặp đi lặp lại: vòng lặp. Hôm nay, chúng ta sẽ thảo luận về các vòng "for".

Các phác thảo cơ bản của một vòng lặp for là như sau:

for VARIABLE in LIST; do command1 command2 … commandn done

VARIABLE có thể là bất kỳ biến nào, mặc dù thường xuyên nhất chữ thường "i" được sử dụng theo quy ước. DANH SÁCH là danh sách các mục; bạn có thể chỉ định nhiều mục (tách chúng bằng dấu cách), trỏ tới tệp văn bản bên ngoài hoặc sử dụng dấu hoa thị (*) để biểu thị bất kỳ tệp nào trong thư mục hiện tại. Các lệnh được liệt kê được thụt lề theo quy ước, do đó, dễ dàng hơn để xem lồng nhau - đặt vòng lặp trong vòng lặp (vì vậy bạn có thể lặp trong khi bạn lặp lại).

Bởi vì các danh sách sử dụng dấu cách làm dấu phân cách - tức là, một dấu cách biểu thị di chuyển đến mục tiếp theo trong danh sách - các tệp có khoảng trống trong tên không thân thiện lắm. Bây giờ, hãy bắt đầu làm việc với các tệp không có dấu cách. Hãy bắt đầu bằng một tập lệnh đơn giản để hiển thị tên tệp trong thư mục hiện tại. Tạo một tập lệnh mới trong thư mục ~ / bin / của bạn mang tên “loopscript”. Nếu bạn không nhớ cách thực hiện điều này (bao gồm đánh dấu nó là tệp thực thi và thêm băm băm), hãy tham khảo bài viết cơ bản về bash scripting của chúng tôi.

Trong đó, nhập mã sau:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Khi bạn chạy tập lệnh, bạn chỉ nên lấy các mục danh sách đó dưới dạng đầu ra.
Khi bạn chạy tập lệnh, bạn chỉ nên lấy các mục danh sách đó dưới dạng đầu ra.
Khá đơn giản, phải không? Hãy xem điều gì xảy ra nếu chúng ta thay đổi mọi thứ một chút. Thay đổi kịch bản của bạn để nó nói điều này:
Khá đơn giản, phải không? Hãy xem điều gì xảy ra nếu chúng ta thay đổi mọi thứ một chút. Thay đổi kịch bản của bạn để nó nói điều này:

for i in *; do echo “$i” done

Khi bạn chạy tập lệnh này trong một thư mục, bạn sẽ nhận được một danh sách các tệp mà nó chứa làm đầu ra.
Khi bạn chạy tập lệnh này trong một thư mục, bạn sẽ nhận được một danh sách các tệp mà nó chứa làm đầu ra.
Bây giờ, hãy thay đổi lệnh echo thành cái gì đó hữu ích hơn - ví dụ, lệnh zip. Cụ thể là chúng tôi sẽ thêm tệp vào một tệp lưu trữ. Và, chúng ta hãy có một số lý lẽ trong sự pha trộn!
Bây giờ, hãy thay đổi lệnh echo thành cái gì đó hữu ích hơn - ví dụ, lệnh zip. Cụ thể là chúng tôi sẽ thêm tệp vào một tệp lưu trữ. Và, chúng ta hãy có một số lý lẽ trong sự pha trộn!

for i in $@; do zip archive “$i” done

Có gì đó mới mẻ! “$ @” Là một phím tắt cho “$ 1 $ 2 $ 3… $ n”. Nói cách khác, đó là danh sách đầy đủ của tất cả các đối số bạn đã chỉ định. Bây giờ, hãy xem điều gì xảy ra khi tôi chạy tập lệnh với một vài tệp đầu vào.
Có gì đó mới mẻ! “$ @” Là một phím tắt cho “$ 1 $ 2 $ 3… $ n”. Nói cách khác, đó là danh sách đầy đủ của tất cả các đối số bạn đã chỉ định. Bây giờ, hãy xem điều gì xảy ra khi tôi chạy tập lệnh với một vài tệp đầu vào.
Bạn có thể xem các tệp nào nằm trong thư mục của tôi. Tôi chạy lệnh với sáu đối số và mỗi tệp được thêm vào kho lưu trữ nén có tên là "archive.zip". Dễ dàng, phải không?
Bạn có thể xem các tệp nào nằm trong thư mục của tôi. Tôi chạy lệnh với sáu đối số và mỗi tệp được thêm vào kho lưu trữ nén có tên là "archive.zip". Dễ dàng, phải không?

Đối với vòng lặp là khá tuyệt vời. Bây giờ bạn có thể thực hiện các hàm batch trên danh sách các tệp. Ví dụ: bạn có thể sao chép tất cả các đối số tập lệnh của mình vào một kho lưu trữ đã nén, di chuyển bản gốc sang một thư mục khác và tự động bảo mật sao chép tệp zip đó vào máy tính từ xa. Nếu bạn thiết lập các tệp quan trọng bằng SSH, bạn thậm chí sẽ không cần phải nhập mật khẩu của mình và thậm chí bạn có thể yêu cầu tập lệnh xóa tệp zip sau khi tải lên!

Sử dụng các vòng lặp giúp dễ dàng thực hiện một loạt các hành động cho tất cả các tệp trong một thư mục. Bạn có thể gộp nhiều lệnh khác nhau lại với nhau và sử dụng các đối số rất dễ dàng để tạo và danh sách liên tục, và đây chỉ là đỉnh của tảng băng trôi.

Bash scripters, bạn có bất cứ đề nghị? Bạn đã tạo một tập lệnh hữu ích có sử dụng vòng lặp chưa? Bạn muốn chia sẻ suy nghĩ của bạn về bộ truyện? Để lại một số bình luận và giúp những người mới viết kịch bản khác ra!

Đề xuất: