Le script ne fonctionne pas lorsqu'il est appelé en externe

8

J'utilise un script simple pour créer des .mp3 à partir de fichiers .mp4:

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

Le script fonctionne correctement lorsqu'il est exécuté à partir du bureau ou appelé via le terminal. Cependant, lorsque le script est appelé à partir d'un script externe, il ne s'exécute pas, retournant

msgstr "* .mp4: aucun fichier ou répertoire de ce type".

Je soupçonne que le problème concerne l'expansion du shell, mais je ne peux pas comprendre comment résoudre ce problème dans cette situation.

M. Street
la source

Réponses:

13

Vous utilisez un chemin d'accès relatif, où votre script recherche les .mp4fichiers dans le répertoire courant, c'est-à-dire le répertoire à partir duquel le script est exécuté, et constatant qu'aucun .mp4fichier de ce type n'existe, il recherche un *.mp4fichier littéral (en supposant que nullglob/ failglobn'est pas set, qui est la valeur par défaut), et ce fichier n'existe pas non plus, d'où le message d'erreur *.mp4: No Such File or Directory.

Vous devez utiliser un chemin absolu à la place:

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

Remplacez /directory/par le chemin du répertoire réel; si vous le souhaitez, vous pouvez également prendre le nom du répertoire comme premier argument:

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

Vous pouvez utiliser ici un chemin absolu ou relatif, mais là encore, le chemin absolu est toujours l'option la plus sûre.

Appelez maintenant le script exécutable de la manière habituelle:

/path/to/script.sh /directory

Depuis le répertoire du script:

./script.sh /directory
heemayl
la source
Merci pour l'aide. J'étais sur le point de vous dire que j'avais déjà essayé cela en vain, mais j'ai remarqué que j'avais mis en majuscule le "H" dans "/ home" la première fois. Le passage du chemin en argument a été particulièrement utile. À votre santé.
M. Street
Où "d'où le message d'erreur" signifie en fait: comme le shell ne peut pas correspondre *.mp4à aucun fichier, il le considère comme un nom de fichier littéral et essaie d'ouvrir le fichier appelé *.mp4(qui est un nom de fichier valide) et échoue parce que vous n'avez pas de fichier appelé *.mp4dans le répertoire courant. Quelqu'un pourrait penser que *.mp4toujours s'étendre à la liste des noms de fichiers correspondants, qui pourrait être vide (et dans ce cas, la forboucle ne ferait rien, mais aucune erreur ne serait générée), ce n'est pas le cas: se *.mp4développe toujours en quelque chose.
Bakuriu
@Bakuriu Attendu que cela est vrai dans ce cas (ou par défaut dans bash) mais pas toujours; regardez nullglob/ failglob.
heemayl
Si je me suis trompé, je pense que le '*' était juste pour le nom de fichier, plutôt que la combinaison de chemin ET de nom de fichier. vivre et apprendre :)
M. Street