Skrypt nie działa po wywołaniu zewnętrznym

8

Używam prostego skryptu do tworzenia plików .mp3 z plików .mp4:

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

Skrypt działa poprawnie, gdy jest uruchamiany z pulpitu lub wywoływany przez terminal. Jednak, gdy skrypt jest wywoływany ze skryptu zewnętrznego, nie działa, wracając

„* .mp4: Brak takiego pliku lub katalogu”.

Podejrzewam, że problem dotyczy rozszerzenia powłoki, ale nie mogę się zastanowić, jak to naprawić w tej sytuacji.

M. Street
źródło

Odpowiedzi:

13

Używasz ścieżki względnej, w której skrypt szuka .mp4plików w bieżącym katalogu, tj. Katalogu, z którego skrypt jest uruchamiany, i gdy nie ma takiego .mp4pliku, wówczas szuka *.mp4pliku dosłownego (zakładając, że nullglob/ failglobnie jest zestaw, który jest domyślny), a ten plik również nie istnieje, stąd komunikat o błędzie *.mp4: No Such File or Directory.

Zamiast tego należy użyć ścieżki bezwzględnej:

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

Zamień /directory/na rzeczywistą ścieżkę do katalogu; jeśli chcesz, możesz również wziąć nazwę katalogu jako pierwszy argument:

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

Możesz tutaj użyć ścieżki bezwzględnej lub względnej, ale znowu ścieżka bezwzględna jest zawsze bezpieczniejszą opcją.

Teraz wywołaj skrypt wykonywalny w zwykły sposób:

/path/to/script.sh /directory

Z katalogu skryptów:

./script.sh /directory
heemayl
źródło
Dzięki za pomoc. Już miałam powiedzieć, że próbowałem już tego bezskutecznie, ale zauważyłem, że po raz pierwszy użyłem litery „H” w „/ home”. Przekazywanie ścieżki jako argumentu było szczególnie przydatne. Twoje zdrowie.
M. Street,
Gdzie „stąd komunikat o błędzie” faktycznie oznacza: ponieważ powłoka nie jest w stanie dopasować się *.mp4do żadnego pliku, uważa go za dosłowną nazwę pliku i próbuje otworzyć plik o nazwie *.mp4(która jest prawidłową nazwą pliku) i kończy się niepowodzeniem, ponieważ nie masz pliku wywoływane *.mp4w bieżącym katalogu. Ktoś mógłby pomyśleć, że *.mp4zawsze rozwija się do listy pasujących nazw plików, która może być pusta (iw takim przypadku forpętla nic nie robi, ale nie zostaną zgłoszone żadne błędy), tak nie jest: *.mp4zawsze rozwija się do czegoś.
Bakuriu
@ Bakuriu mając na uwadze, że jest to prawda w tym przypadku (lub domyślnie w bash), ale nie zawsze; spójrz na nullglob/ failglob.
heemayl
Gdybym się pomylił, pomyślałem, że „*” dotyczyło tylko nazwy pliku, a nie kombinacji ścieżki ORAZ nazwy pliku. żyj i ucz się :)
M. Street