Скрипт не работает при внешнем вызове

8

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

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

Скрипт работает нормально при запуске с рабочего стола или при вызове через терминал. Когда скрипт вызывается из внешнего скрипта, он не запускается, возвращая

msgstr "* .mp4: Нет такого файла или каталога".

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

М. Стрит
источник

Ответы:

13

Вы используете относительный путь, где ваш скрипт ищет .mp4файлы в текущем каталоге, то есть в каталоге, из которого выполняется скрипт, и обнаруживает, что такого .mp4файла не существует, затем он ищет литеральный *.mp4файл (при условии, что nullglob/ failglobнет set, который является значением по умолчанию), и этот файл тоже не существует, отсюда и сообщение об ошибке *.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
heemayl
источник
Спасибо за помощь. Собирался сказать вам, что я уже пытался сделать это безуспешно, но потом заметил, что впервые в заглавной букве "H" в "/ home". Прохождение пути в качестве аргумента было особенно полезно. Приветствия.
улица М.
Где «следовательно, сообщение об ошибке» на самом деле означает: поскольку оболочка не может *.mp4найти соответствие ни одному файлу, она рассматривает его как буквальное имя файла и пытается открыть файл с именем *.mp4(который является допустимым именем файла) и завершается неудачей, потому что у вас нет файла вызывается *.mp4в текущем каталоге. Кто-то может подумать, что он *.mp4всегда расширяется до списка совпадающих имен файлов, который может быть пустым (и в этом случае forцикл ничего не делает, но ошибок не возникает), это не так: *.mp4всегда расширяется до чего-то.
Бакуриу
@Bakuriu Принимая во внимание, что это верно в этом случае (или по умолчанию в bash), но не всегда; посмотрите на nullglob/ failglob.
Heemayl
Если я ошибся, то думал, что «*» было только для имени файла, а не комбинации пути и имени файла. живи и учись :)
М. Улица