Chào mừng đến với Unix :)
Để trả lời một số câu hỏi nhỏ của bạn mà câu trả lời cho câu hỏi chính không bao gồm:
Shell scripting chắc chắn có một số cạnh khó khăn, vì rất nhiều thứ phá vỡ tên tệp có khoảng trắng. Và hầu hết mọi thứ đều phá vỡ tên tập tin với dòng mới (may mắn thay, không ai thực hiện những mục đích đó). Tên tập tin chứa ký tự glob thích [
, ]
và *
đôi khi một vấn đề, quá. Đôi khi, không đáng để viết mã shell khó đọc theo tiêu chuẩn của BashGuide của Wooledge , cho mục đích sử dụng của riêng bạn hoặc cho một lần mà bạn biết tên tệp của mình không lạ.
nơi để khai báo biến:
Biến Shell không cần phải khai báo. Trong bash, bạn có thể shopt -o nounset
biến nó thành một lỗi để tham chiếu và biến unSET, nhưng điều đó không hoàn toàn giống như không được khai báo. Bỏ đặt một biến có thể hữu ích. Trong hàm shell, cách tốt nhất là khai báo tất cả các tạm thời của bạn local foo bar baz;
, vì vậy bạn không xả rác môi trường shell với các biến hoặc tệ hơn là bước vào biến của người gọi cùng tên.
Tôi hầu như không hiểu "đường ống".
Khi làm việc với shell, rất nhiều dữ liệu truyền qua xảy ra bằng cách in dữ liệu ra thiết bị xuất chuẩn. Các đường ống gửi dữ liệu đó đến một chương trình khác, nó đọc nó trên stdin (và thường in một cái gì đó trên thiết bị xuất chuẩn). Bạn có thể nắm bắt đầu ra thành các biến shell bằng cách sử dụng lệnh thay thế , $()
. ví dụ for i in $( locate foo | grep bar );do echo "$i"; done
. (điều này sẽ phá vỡ tên tệp có khoảng trắng trong chúng, giống như rất nhiều mã shell nếu bạn không cẩn thận. Sử dụng read
nếu bạn muốn viết các tập lệnh đáng tin cậy.) locate
in, grep
đọc và in và shell đọc đầu ra của grep
. (Vỏ được đặt trên đầu ra của grep
bằng cách bắt đầu grep với đầu ra của nó được kết nối với phía đầu vào của ống mà vỏ được tạo. Vỏ đọc phía đầu ra của ống.)
Một đường ống chỉ là một cách để các chương trình hoạt động giống như chúng đang ghi vào một tệp, nhưng thực ra chúng đang ghi vào một bộ đệm nhỏ. Một quá trình đọc từ một đường ống sẽ read(2)
trả lại cuộc gọi hệ thống của nó khi có sẵn dữ liệu, điều này chỉ xảy ra khi một cái gì đó ghi vào đầu kia của ống.
Vỏ là |
, $()
và một số yếu tố cú pháp khác là làm thế nào bạn nói với vỏ làm thế nào để thiết lập hệ thống ống nước nối chương trình với nhau, và để vỏ.
Thật dễ dàng để học các thành ngữ xấu cho lập trình shell, bởi vì rất nhiều điều rõ ràng và cách làm cũ đã ẩn chứa những cạm bẫy phá vỡ tên tập tin kỳ lạ. Xem ví dụ http://mywiki.wooledge.org/BashFAQ/001 .
Tốt hơn là học các cách viết kịch bản an toàn ngay từ đầu, thay vì học các cách phá vỡ tên tệp lẻ, miễn là chúng không quá khó để gõ. :)
Rất nhiều tiện ích GNU có tùy chọn -0, để sử dụng ASCII NUL (0 byte, không thể có trong tên tệp hoặc văn bản) làm dấu tách bản ghi. Điều này cho phép bạn chuyển dữ liệu giữa find
và sort
, ví dụ, mà không có bất kỳ khả năng nào có một "dòng" đầu ra tìm được chuyển thành nhiều dòng đầu vào sắp xếp. Điều này kết thúc không phải là siêu hữu ích khi bạn muốn đưa dữ liệu vào một biến shell, bởi vì bash không có cách nào để đọc \0
các dòng giới hạn. (Tôi không nghĩ đó là một giá trị hợp lệ cho IFS.)
Dù sao, tránh việc shell xử lý dữ liệu dưới dạng mã là lý do để luôn trích dẫn hai lần mọi thứ bạn có thể, trừ khi bạn thực sự MUỐN chia tách từ. Nếu bạn muốn làm cho bộ não của bạn bị tổn thương khi nhìn vào mã shell phức tạp, chỉ cần nhìn vào mã hoàn thành bash. (Nó xử lý việc hoàn thành có thể lập trình để thực hiện những việc thông minh như hoàn thành ls --colo => --color
hoặc chỉ hoàn thành các tệp * .zip để giải nén.) set -x
Và nhấn tab: P. (đặt + x để tắt theo dõi thực thi.)
re: vòng lặp for của bạn: với *.mkv
một trong các mẫu của bạn, bạn sẽ có source = Dest cho các tệp đầu vào đó. ffmpeg
sẽ nhắc bạn ghi đè lên tệp đầu ra cho mỗi tệp.
Ngoài ra, bạn có thực sự cần phải chuyển mã âm thanh? -c:a copy
có thể là một ý tưởng tốt Tốc độ bit video thường là một thỏa thuận lớn hơn. Và bạn có thể muốn sử dụng -preset slow
(hoặc slower
, hoặc thậm chí veryslow
) để có được chất lượng cao hơn trên mỗi bitrate, với chi phí sử dụng CPU nhiều hơn. Cũng có -crf 20
(mặc định 23). https://trac.ffmpeg.org/wiki/Encode/H.264 . Bạn hy vọng đã biết điều này và bỏ nó đi vì nó không liên quan đến kịch bản bash, nhưng chỉ trong trường hợp ...: P -c:v libx264
là mặc định khi xuất ra mkv, vậy thì tốt.
**
toán tử hả hê để tìm kiếm các tệp đệ quy. Nó không di động nhưng nó chơi tốt với cú pháp for-loop.