La secuencia de comandos no funciona cuando se llama externamente

8

Utilizo un script simple para crear .mp3s a partir de archivos .mp4:

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

El script funciona bien cuando se ejecuta desde el escritorio o se llama a través del terminal. Sin embargo, cuando se llama al script desde un script externo, no se ejecuta y devuelve

"* .mp4: No existe tal archivo o directorio".

Sospecho que el problema es con la expansión de shell, pero no puedo entender cómo solucionarlo en esta situación.

M. Street
fuente

Respuestas:

13

Está utilizando una ruta relativa, donde su secuencia de comandos busca los .mp4archivos en el directorio actual, es decir, el directorio desde donde se ejecuta la secuencia de comandos, y al encontrar que no .mp4existe tal archivo, entonces busca un *.mp4archivo literal (suponiendo que nullglob/ failglobno es establecido, que es el valor predeterminado), y ese archivo no existe también, de ahí el mensaje de error *.mp4: No Such File or Directory.

En su lugar, debe usar la ruta absoluta:

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

Reemplazar /directory/con la ruta real del directorio; si lo desea, puede tomar el nombre del directorio como primer argumento también:

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

Puede usar la ruta absoluta o relativa aquí, pero nuevamente la ruta absoluta es siempre la opción más segura.

Ahora llame al script ejecutable de la manera habitual:

/path/to/script.sh /directory

Desde el directorio de script:

./script.sh /directory
heemayl
fuente
Gracias por la ayuda. Estaba a punto de decirte que ya lo había intentado sin éxito, pero luego me di cuenta de que había puesto en mayúscula la "H" en "/ home" la primera vez. El paso del camino como argumento fue particularmente útil. Salud.
M. Street
Donde "de ahí el mensaje de error" en realidad significa: dado que el shell no puede coincidir *.mp4con ningún archivo, lo considera como un nombre de archivo literal e intenta abrir el archivo llamado *.mp4(que es un nombre de archivo válido) y falla porque no tiene ningún archivo llamado *.mp4en el directorio actual. Alguien podría pensar que *.mp4siempre se expande a la lista de nombres de archivos coincidentes, que podrían estar vacíos (y en ese caso el forbucle no haría nada, pero no se generarían errores), este no es el caso: *.mp4siempre se expande a algo.
Bakuriu
@Bakuriu Considerando que esto es cierto en este caso (o predeterminado bash) pero no siempre; mira nullglob/ failglob.
heemayl
Si me equivoqué, estoy pensando que '*' era solo para el nombre del archivo, en lugar de la combinación de la ruta Y el nombre del archivo. vive y aprende :)
M. Street