Shell command not working from AppleScript

I found that when typing the command “echo $LANG” into the Terminal app, I get a string result.
But when using the command in a “do shell script”, I get an empty string result returned.

set result to do shell script "echo $LANG"

Only tested this on “High Sierra”.

Any ideas what happening ?

Regards Mark

LANG in a do shell script instance is a generic, unset value. If you want to use a locale, then set it explicitly at the beginning; e.g.

do shell script "LANG='fr_FR.UTF-8' ruby -e 'puts " & quote & "Q184GHJK003éèú" & quote & ".match /(?<=\\d{3})[[:alpha:]]+$/'" 

If you want your locale returned, this works:

(system info)'s user locale

Thanks for the reply marc.

But I don’t want to set the locale, I was was simply trying to read it in.

I was working on an Xcode project, and noticed the same behaviour when calling out to the command line from that project, and then tested it again in AppleScript, and found the same behaviour there as well.
So using “system info” is not an option for the Xcode project, as I will have to find another way to read in the locale.

Although I’m still very interested in knowing why the posted command gets a result in Terminal.
But does not return a result when calling from an AppleScript or other code.

Any ideas why this is ?

Regards Mark

Other way to get locale:

text 6 thru -3 of (paragraph 2 of (do shell script "defaults read NSGlobalDomain AppleLanguages"))

For the record, I’m not looking for ways to get the locale, even if my original posting gave that impression, as I knew it could be got in several ways, this is one way.

use framework "Foundation"

set locale to current application's NSLocale's currentLocale()'s localeIdentifier() as text

And it can be got several other ways as well, including using other shell commands.

The question was more about the behaviour of the Terminal’s results in comparison to the AppleScript results, when using the “echo $LANG” shell command.

So if anyone knows why there is the difference in behaviour, I’m very interested.

Regards Mark

I believe AppleScript’s ‘do shell script’ command uses a different shell from Terminal: one whose “LANG” is, as Marc said, unset.

Hi Nigel

Thanks for making that clearer, I have to be honest I didn’t get that point made by marc, so apologies to him.

It wasn’t the getting or setting of the language or locale that was puzzling me, but the different results obtained from where you called the same shell command.
But now it kind of makes sense with what you and marc have said, that different processes are potentially using different shell’s, and that the locale may have been set by the Terminal app in it’s default shell, but that the same locale variables may not have been set in other shell processes.

You get the same behaviour with the “locale” shell command as well, when typed into the Terminal, or run as an AppleScript “do shell script”.

set result to do shell script "locale"

I’ve sorted out the problem in my Xcode project, using the Swift Locale class, used in a similar way to the NSLocale class above.

But it’s been puzzling and interesting in equal measure.

Regards Mark

I do get a return result of your script in Mojave.

To do little debuging I include ‘set’

set result to do shell script "echo $LANG; set"

And to use only ‘set’

set result to do shell script "set | grep LANG="
display dialog text 6 thru -1 of (second paragraph of result)

I decided to take a test to check the claim that the problem is that Terminal and do shell script are using different shells. To do this, I:

  1. executed the command “/bin/sh” in Terminal (the shell used by the do shell script), and then the command “echo $LANG”. The result was “”.

  2. I created a .zprofile configuration text file in my home folder with the following content:

# Setting LANG for do shell script
LANG = “en_EN.UTF-8”
export LANG

Then I ran the command “/bin/sh” in Terminal again, and then the command “echo $LANG”. The result was “en_EN.UTF-8” (that is, I achieved what I wanted using the fact that Terminal reads user config files when available).

I expected the do shell script to output the locale after that, but I got “” again. And then I realized that the do shell script does not read configuration files, unlike Terminal.

In the do shell script technical notes, I found confirmation of this observation: do shell script does not read configuration files.

And here is my answer: the difference in the behavior of the Terminal and the do shell script is that the first takes data from the configuration files (when available), and the second does not. Even if you use the same shell.

Here is interesting approach for PATH

If I runt this script

set result to do shell script "echo $PATH"

→ /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Pixar/RenderManProServer-22.5/bin

You may wonder where does this: /Applications/Pixar/RenderManProServer-22.5/bin come from.

I have on my machine ~/library/LaunchAgents/environment.plist

You could also see I have /usr/local/bin in my PATH for do shell script.
In /etc/paths
The first paragraph of paths I have /usr/local/bin

So my conclusion is when /bin/sh is run it looks for /etc/paths and environment.plist

so I could do something like this. (I do not need /usr/local/bin)

do shell script "python3 -V

→ Python 3.9.1

So when people say do shell script do not look for any settings on my machine it does. (Mojave)