Can't run a Homebrew app from batch file in WSL bash (command not found)

Viewed 188

I have a bash script that contains the following commands, including passing a file to eyeD3, which I installed using Homebrew:

#!/usr/bin/env bash
cd /mnt/c/Users/charl/Downloads;
eyeD3 test.mp3;

When I run it in Windows Subsystem for Linux (WSL) from my Ubuntu bash prompt, I get the correct result:

thompcha@WINDOWS-79UTJUF:/mnt/c/Users/charl/Documents/Scripts$ ./eyed3.sh
/mnt/c/Users/charl/Downloads/test.mp3                                                     [ 7.15 MB ]
-----------------------------------------------------------------------------------------------------
Time: 04:26     MPEG1, Layer III        [ 224 kb/s @ 44100 Hz - Stereo ]
-----------------------------------------------------------------------------------------------------
ID3 v2.4:
title: Example Song
artist: Example Artist
album: Example Album
track: 1
-----------------------------------------------------------------------------------------------------

However, if I run the bash script from a batch file like this,

@ECHO OFF
bash.exe -c ./eyed3.sh
PAUSE

the eyeD3 command cannot be run:

./eyed3.sh: line 3: eyeD3: command not found
Press any key to continue . . .

Default system commands like ls can be run in this way from a shell script called by a batch file, but eyeD3 cannot. I'm guessing that the script cannot "see" the environment $PATH when it is run this way, but I'm not sure what to do about it.

I have unchecked "Use legacy console" in the cmd.exe properties.

How can I run a homebrew command in a shell script from a batch file?

1 Answers

Short answer - Several options:

  • Option 1: Change it to bash.exe -l -c ./eyed3.sh. I'm fairly sure that will work (see below for "why").
  • Option 2: As per the comments, identify the location of the eyeD3 executable with which eyeD3 in the terminal where it works, then hardcode the fully-qualified path in the shell script.
  • Option 3: Set the Homebrew path in your .bashrc rather than your .profile (where Homebrew set it).

/aside: Wow, it's been more than 15 years since I used eyeD3. Amazing that it is still around and kicking!

What's happening

I don't run Homebrew, but looking at its install script (the last 10 lines or so) confirms my hunch that it adds its path to your .profile (or other applicable startup script) during its installation.

.profile (or .bash_profile or ...) is only sourced for login shells (usually the "top level" shell that spawns other non-login shells). It's the place for things that should only be done "once" when logging in, rather than in each shell instance. The PATH is set here because it is exported to subshells, so it doesn't need to be set each time.

So when you run bash.exe -c ./eyeD3.sh, that's actually a non-login shell, and it skips the login startup scripts, and thus skips the code that Homebrew added to modify the PATH. Running bash with the -l argument will cause it to run as a login shell, thus sourcing that Homebrew code, and modifying the PATH for that shell.

See this answer for some more detail on the different types of startup scripts, if you are interested.

Related