Tôi không hoàn toàn hiểu lệnh nhưng mô tả của bạn có vẻ như đó có thể là một công việc cho các đường ống được đặt tên. Để làm cho khái niệm này rõ ràng ví dụ của tôi sử dụng bốn trong số họ. Với sự thay thế phù hợp, bạn có thể giảm con số này xuống còn hai, tôi nghĩ, thậm chí có thể là một; nhưng bây giờ hãy giữ nó đơn giản.
mkfifo pre-audio-pipe pre-video-pipe audio-pipe video-pipe # creating pipes
(reading commands) | mbuffer -p 1 -m 5G | tee pre-audio-pipe > pre-video-pipe # splitting
Quá trình này sẽ điền vào bất cứ bộ đệm nào được tạo cho hai ống được đặt tên, sau đó nó sẽ chờ dữ liệu này được đọc ở nơi khác.
"Nơi khác" nằm trong bảng điều khiển khác:
<pre-audio-pipe (isolate audio) | (process audio) > audio-pipe
và trong một giao diện điều khiển khác:
<pre-video-pipe (isolate video) | (process video) > video-pipe
Một lần nữa hai lệnh này sẽ đợi cho đến khi chúng ta đọc một số dữ liệu từ các đường ống. Trong bảng điều khiển cuối cùng:
ffmpeg -i video-pipe -i audio-pipe (doing final conversion)
Bạn có thể gặp phải tình trạng khóa máy trong trường hợp lệnh cuối cùng muốn đọc một luồng trước luồng khác. Tôi không biết khả năng này là như thế nào. Bộ đệm bổ sung có thể hữu ích để tránh điều này. Thử nghiệm đầu tiên của tôi sẽ là loại bỏ mbuffer
(trước tee
) và chèn hai bộ đệm độc lập giữa tương ứng (isolate)
và (process)
.
Sau khi xong tất cả:
rm pre-audio-pipe pre-video-pipe audio-pipe video-pipe # cleaning
Biên tập
Từ bình luận của OP:
Bạn có thấy bất kỳ cơ hội để thực hiện một giải pháp mà không sử dụng các ống có tên riêng biệt không?
Tôi đã suy nghĩ về coprocesses ( coproc
dựng sẵn) nhưng tôi không biết nhiều về chúng. Có câu trả lời toàn diện về họ. Tìm kiếm cụm từ "tại sao chúng không phổ biến". Từ đó:
Lợi ích duy nhất của việc sử dụng coproc
là bạn không phải dọn sạch những ống có tên sau khi sử dụng.
Tôi hoàn toàn đồng ý. Nhìn vào ví dụ ở đó - về cơ bản là trường hợp của bạn với luồng dữ liệu rẽ ba chiều thay vì hai chiều. Ví dụ này sử dụng các shell khác bash
nhưng theo kinh nghiệm của tôi thì nó cũng tương tự khủng khiếp bash
.
Lý tưởng nhất là sẽ chỉ có một dòng lệnh làm việc với các ống không tên, vì công việc nên được bắt đầu bằng một "nỗ lực kinh tế" từ dấu nhắc lệnh.
Nghiêm túc? Với tất cả những người (doing some encoding here)
mở rộng? Theo tôi, bất kể bạn sử dụng các ống có tên hay không tên, "nỗ lực kinh tế" ở đây sẽ là viết kịch bản, ngay cả khi đó là công việc một lần. So sánh kịch bản một đoạn dài và tương đương được viết tốt, tôi thấy phần sau dễ gỡ lỗi hơn.
Nhưng vì bạn đã yêu cầu một lớp lót, bạn sẽ nhận được nó , vẫn với các ống được đặt tên mặc dù. Ý tưởng của tôi để duy trì các đường ống được đặt tên là tạo một thư mục tạm thời cho chúng. Khái niệm chung:
my_temp=`mktemp -d` ; pre_audio_pipe="${my_temp}/pre-audio-pipe" ; pre_video_pipe="${my_temp}/pre-video-pipe" ; audio_pipe="${my_temp}/audio-pipe" ; video_pipe="${my_temp}/video-pipe" ; mkfifo "$pre_audio_pipe" "$pre_video_pipe" "$audio_pipe" "$video_pipe" ; (reading commands) | tee "$pre_audio_pipe" > "$pre_video_pipe" & <"$pre_audio_pipe" (isolate audio) | mbuffer -p 1 -m 1G | (process audio) > "$audio_pipe" & <"$pre_video_pipe" (isolate video) | mbuffer -p 1 -m 4G | (process video) > "$video_pipe" & ffmpeg -i "$video_pipe" -i "$audio_pipe" (doing final conversion) ; rm -rf "$my_temp"
Theo câu trả lời này, có lẽ bạn có thể điều chỉnh nó thành một dòng lệnh, ngay cả sau khi bạn đào sâu vào lệnh và mở rộng tất cả các (do something)
trình giữ chỗ đó.
OK, hình thức một lớp lót là để cho bạn thấy nó bất tiện như thế nào. Khái niệm tương tự như một kịch bản:
#!/bin/bash
my_temp=`mktemp -d`
pre_audio_pipe="${my_temp}/pre-audio-pipe"
pre_video_pipe="${my_temp}/pre-video-pipe"
audio_pipe="${my_temp}/audio-pipe"
video_pipe="${my_temp}/video-pipe"
mkfifo "$pre_audio_pipe" "$pre_video_pipe" "$audio_pipe" "$video_pipe" #creating actual pipes
# Main code here.
# Notice we put few commands into the background.
# In this example there are two separate mbuffers.
(reading commands) | tee "$pre_audio_pipe" > "$pre_video_pipe" & # splitting
<"$pre_audio_pipe" (isolate audio) | mbuffer -p 1 -m 1G | (process audio) > "$audio_pipe" &
<"$pre_video_pipe" (isolate video) | mbuffer -p 1 -m 4G | (process video) > "$video_pipe" &
ffmpeg -i "$video_pipe" -i "$audio_pipe" (doing final conversion)
# Then cleaning:
rm -rf "$my_temp"