Script không hoạt động khi được gọi bên ngoài


8

Tôi sử dụng một tập lệnh đơn giản để tạo .mp3 từ các tệp .mp4:

#!/bin/bash
for i in *.mp4
do
ffmpeg -i "$i" -ab 128k "${i%mp4}mp3"
done

Kịch bản chạy tốt khi chạy từ máy tính để bàn hoặc được gọi qua thiết bị đầu cuối. Tuy nhiên, khi tập lệnh được gọi từ tập lệnh bên ngoài, nó không chạy được, trả về

"* .mp4: Không có tệp hoặc thư mục như vậy".

Tôi nghi ngờ vấn đề là do mở rộng vỏ, nhưng không thể che giấu cách khắc phục trong tình huống này.

Câu trả lời:


13

Bạn đang sử dụng một đường dẫn tương đối, trong đó tập lệnh của bạn đang tìm kiếm các .mp4tệp trong thư mục hiện tại, tức là thư mục nơi tập lệnh đang được chạy và thấy rằng không có .mp4tệp nào như vậy tồn tại, thì nó sẽ tìm một *.mp4tệp bằng chữ (giả sử nullglob/ failglobkhông phải là thiết lập, là mặc định) và tập tin đó cũng không tồn tại, do đó thông báo lỗi *.mp4: No Such File or Directory.

Bạn nên sử dụng đường dẫn tuyệt đối thay thế:

for i in /directory/*.mp4; do ...; done

Thay thế /directory/bằng đường dẫn thư mục thực tế; nếu bạn muốn, bạn cũng có thể lấy tên thư mục làm đối số đầu tiên:

for i in "$1"/*.mp4; do ...; done

Bạn có thể sử dụng đường dẫn tuyệt đối hoặc tương đối ở đây, nhưng một lần nữa đường dẫn tuyệt đối luôn là lựa chọn an toàn hơn.

Bây giờ gọi tập lệnh thực thi theo cách thông thường:

/path/to/script.sh /directory

Từ thư mục script:

./script.sh /directory

Cảm ơn đã giúp đỡ. Đã định nói với bạn rằng tôi đã thử nó không thành công, nhưng sau đó nhận thấy tôi đã viết hoa chữ "H" trong "/ home" lần đầu tiên. Việc thông qua đường dẫn là đối số là đặc biệt hữu ích. Chúc mừng.
Đường M.

Trong đó "do đó thông báo lỗi" thực sự có nghĩa là: vì shell không thể khớp *.mp4với bất kỳ tệp nào, nó coi đó là tên tệp bằng chữ và cố gắng mở tệp được gọi *.mp4(đó là tên tệp hợp lệ) và không thành công vì bạn không có tệp được gọi *.mp4trong thư mục hiện tại. Ai đó có thể nghĩ rằng *.mp4luôn luôn mở rộng ra danh sách tên tệp phù hợp, có thể trống (và trong trường hợp đó, forvòng lặp sẽ không làm gì, nhưng không có lỗi nào được nêu ra), đây không phải là trường hợp: *.mp4luôn mở rộng sang thứ gì đó.
Bakuriu

@Bakuriu Trong khi điều này đúng trong trường hợp này (hoặc mặc định bash) nhưng không phải lúc nào cũng vậy; nhìn vào nullglob/ failglob.
heemayl

Có phải tôi đã sai khi nghĩ rằng '*' chỉ dành cho tên tệp, thay vì kết hợp đường dẫn VÀ tên tệp. sống và học hỏi :)
M. Street
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.