Сценарій не працює при зовнішньому виклику


8

Я використовую простий скрипт для створення .mp3 з файлів .mp4:

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

Сценарій працює добре під час запуску з робочого столу або дзвінка через термінал. Однак, коли скрипт викликається із зовнішнього сценарію, він не запускається, повертаючись

"* .mp4: Такого файлу чи каталогу немає".

Я підозрюю, що проблема полягає в розширенні оболонки, але я не можу обернути голову, як виправити це в цій ситуації.

Відповіді:


13

Ви використовуєте відносний шлях, де ваш скрипт шукає .mp4файли в поточному каталозі , тобто каталог , звідки запущений скрипт, і знаходячи , що такий .mp4файл не існує, то він шукає буквальний *.mp4файл (передбачається , що nullglob/ failglobНЕ встановити, що за замовчуванням), і цей файл теж не існує, отже, повідомлення про помилку *.mp4: No Such File or Directory.

Натомість слід використовувати абсолютний шлях:

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

Замініть /directory/фактичний шлях до каталогу; якщо ви хочете, ви можете взяти ім'я каталогу також як перший аргумент:

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

Тут ви можете використовувати абсолютний або відносний шлях, але знову-таки абсолютний шлях - це завжди безпечніший варіант.

Тепер зателефонуйте виконуваному сценарію звичайним чином:

/path/to/script.sh /directory

З каталогу скриптів:

./script.sh /directory

Дякую за допомогу. Я збирався сказати вам, що я вже пробував це безуспішно, але потім помітив, що вперше прописав "H" в "/ home". Проходження шляху як аргументу було особливо корисним. Ура.
вулиця М.

Звідси "отже, повідомлення про помилку" насправді означає: оскільки оболонка не в змозі відповідати *.mp4жодному файлу, вона розглядає це як буквальне ім'я файлу і намагається відкрити названий файл *.mp4(який є дійсним ім'ям файлу) і не працює, оскільки у вас немає файлу викликається *.mp4в поточному каталозі. Хтось міг подумати, що *.mp4завжди розширюється до списку відповідних імен файлів, які можуть бути порожніми (і в цьому випадку forцикл нічого не зробить, але помилок не буде підніматися), це не так: *.mp4завжди розширюється на щось.
Бакуріу

@Bakuriu Враховуючи, що це дійсно в цьому випадку (або за замовчуванням у bash), але не завжди; дивитись nullglob/ failglob.
heemayl

Якщо я помилився, я вважаю, що "*" призначений саме для імені файлу, а не для комбінації шляху та імені файлу. жити та вчитися :)
М. Вулиця
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.