I use a simple script to create .mp3s from .mp4 files:

for i in *.mp4
ffmpeg -i "$i" -ab 128k "${i%mp4}mp3"

The script runs fine when run from the desktop or called via the terminal. When the script is called from an external script however, it fails to run, returning

"*.mp4: No Such File or Directory".

I suspect the issue is with shell expansion, but can't wrap my head around how to fix it in this situation.


You are using a relative path, where your script is looking for the .mp4 files in the current directory i.e. the directory from where the script is being run, and finding that no such .mp4 file exists, then it looks for a literal *.mp4 file (assuming nullglob/failglob is not set, which is the default), and that file does not exist too, hence the error message *.mp4: No Such File or Directory.

You should use absolute path instead:

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

Replace /directory/ with the actual directory path; if you want you can take the directory name as first argument too:

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

You can use absolute or relative path here, but again absolute path is always the safer option.

Now call the executable script in usual manner:

/path/to/script.sh /directory

From the script directory:

./script.sh /directory
  • Thanks for the help. Was about to tell you I had already tried that unsuccessfully, but then noticed I'd capitalized the "H" in "/home" first time through. The passing of the path as argument was particularly useful. Cheers.
    – M. Street
    Jan 5 '17 at 16:10
  • Where "hence the error message" actually means: since the shell is unable to match *.mp4 to any file it consider it as a literal file name and tries to open the file called *.mp4 (which is a valid file name) and fails because you have no file called *.mp4 in the current directory. Someone could think that *.mp4 always expand to the list of matching filenames, which could be empty (and in that case the for loop would do nothing, but no errors would be raised), this is not the case: *.mp4 always expands to something.
    – Bakuriu
    Jan 5 '17 at 17:54
  • @Bakuriu Whereas this is true in this case (or default in bash) but not always; look at nullglob/failglob.
    – heemayl
    Jan 5 '17 at 18:13
  • Were I went wrong is thinking the '*' was just for the filename, rather than the combination of path AND filename. live and learn :)
    – M. Street
    Jan 5 '17 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.