How to use environment variables in a Makefile with Zsh? - makefile

I have some makefiles that I had written when macOS still used bash. Now, that macOS has switched to zsh, they no longer work. I'm wondering how to get the environment variables to work again. Here's a simple example:
Makefile:
all:
echo $(GOPATH)
Bash Output:
$ make
echo /Users/me/go
/Users/me/go
Zsh Output:
% make
echo
 

Related

Why is zsh not able to read ~ (tilde) from a path in a script?

When zsh was exporting a PATH from a script, it didn't read the path correctly.
My PATH was export PATH="~/path/to/stuff/", but when I tried to run a command located at that path, zsh could not find it.
When I changed the PATH to export PATH="$HOME/path/to/stuff/", then the zsh was able to run the command.
EDIT: The strange thing is that I just checked this and it's working again with export PATH="~/path/to/stuff/". There must be something weird going on with my dev environment.
EDIT 2: I failed to mention earlier that the script I am reading export PATH="~/path/to/stuff/" from is building a local dev environment for a team of developers who mainly use bash as their shell. I prefer to use zsh so I have to get my shell to play nice with all of the configs for the dominant bash setup across the team.
Use the following code to get what you want:
export PATH=~/Desktop/Capture/
echo $PATH
# Result: /Users/swift/Desktop/Capture/
Although, when you're using a string, you'll get this:
export PATH="~/Desktop/Capture/"
echo $PATH
# Result: ~/Desktop/Capture/
So to get it right, you'll have to try this approach:
tilde=~
export PATH="${tilde}/Desktop/Capture/"
echo $PATH
# Result: /Users/swift/Desktop/Capture/
P.S. Also, there's one useful command for tilde to be expanded.
Here's an example:
echo tilda=~
# Result: tilda=~
Use magicequalsubst command in zsh:
set -o magicequalsubst
echo tilda=~
# Result: tilda=/Users/swift

Refactoring bash command into tcsh command

I have problem with refactoring bash command into tcsh-friendly command. Don't know the tcsh syntax very well so the error im receiving doens't give me any clue.
The whole bash script was about adding modules on server
MODULEPATH=/app/modules/0/modulefiles:/env/common/modules
export MODULEPATH
module() { eval `/app/modules/0/bin/modulecmd sh "$#"` ;}
I changed first two commands to tcsh already
setenv MODULEPATH /app/modules/0/modulefiles:/env/common/modules
set MODULEPATH
But i dont know how to change the syntax of last command. Console is returning me error "Badly placed ()'s.".
Can I ask for little lesson what to change in this command to be tcsh-friendly?
chepner is right saying tcsh doesn't have functions at all and you'd have to write an alias instead. That's not much of an effort for your one-line function:
alias module 'eval `/app/modules/0/bin/modulecmd sh \!*`'
Basically, we prepend alias, remove () and {}, quote and replace "$#" with \!*.
The module command you want to port from bash to tcsh already comes with an initialization file to the tcsh shell. For all shells or scripting languages module is compatible with, there is an initialization file provided in the init directory of the software.
So from your example, Modules is installed in /app/modules/0, so you should have a /app/modules/0/init directory and a /app/modules/0/init/tcsh script to initialize the module command for tcsh. You just have to source it to initialize the module command:
source /app/modules/0/init/tcsh
As Armali says, the module command on tcsh is defined with the alias shell command.
With recent version of Modules (version 4+), you also have the possibility to define the module command in your current shell session with the autoinit subcommand of the modulecmd script:
eval `/app/modules/0/bin/modulecmd tcsh autoinit`

Parameter substitution bad substitution error on macOS High Sierra

The ${parameter[^|^^|,|,,][pattern]} parameter substitution is giving me a bad substitution error.
$ echo $greeting
hello world
$ echo "${greeting^}."
-bash: ${greeting^}.: bad substitution
I updated to the latest bash version and keep getting the error.
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.3.0)
I've looked everywhere and the only suggestion I've found is making sure it's running bash 4.
$ echo $SHELL
/bin/bash
I'm running macOS High Sierra.
Your default shell is not the bash shell (downloaded from brew install bash) that contains the v4 which supports the parameter expansion syntax you are referring to.
On macOS echo $BASH_VERSION will tell you the version of the current shell. bash --version tells you the version of the first bash in your $PATH. So the way you were looking at the version was not telling you the version that you were running.
You need to add the recent version of bash to the file /etc/shells as the last line and use the command to set the shell as the default on Terminal
chsh -s /usr/local/bin/bash "$USER"
After this close and re-open the Terminal to make it effect. Without adding this default option in your Terminal, you could only use the recent bash only on scripts with interpreter she-bang set to #!/usr/local/bin/bash
See also this Ask Different answer to - Update bash to version 4.0 on OSX

bash script not picking up environment variables

I have a strange situation where I'm using zsh full-time, and any bash scripts I run are not picking environment variables properly. Obviously I don't expect bash to pick up env vars that are defined in zsh's environment, so I am using ~/.bashrc and ~/.bash_profile, but that doesn't work either.
For example, here's a test script:
#!/bin/bash
echo $MYTEST
I've added this line to both ~/.bashrc and ~/.bash_profile to cover my bases:
export MYTEST="hello"
I just get a blank line when running the script.
PS: I know running . ./testscript will work, but that's not an option since it's a system-wide script that's failing to pull env vars.
Oops. Maybe I should try having export VAR=val in my ~/.oh-my-zsh/custom/vars.zsh instead of just VAR=val!

How to handle shell expansions in GNU Make under Ubuntu?

Given this very simple Makefile:
all:
#mkdir -pv test/{a,b}
I get this output on OS X 10.6.8 and CentOS 5.5:
mkdir: created directory `test'
mkdir: created directory `test/a'
mkdir: created directory `test/b'
But on Ubuntu 11.04 I get this:
mkdir: created directory `test'
mkdir: created directory `test/{a,b}'
Running the command mkdir -pv test/{a,b} manually in the shell on all platforms gives the expected result.
The version of GNU Make is the same on all platforms:
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program is built for [PLATFORM]
What's different under Ubuntu and why doesn't the shell expansion work there?
The problem is probably that Make spawns /bin/sh. It is usually a symlink to your system's default shell.
Option 1
You could make sure it points to bash (as this is a bashism). Probably, it is now /bin/dash or /bin/sh, depending on your version of Ubuntu.
Option 2
Easier option:
SHELL=/bin/bash
all:
#echo a{3,4}
#bash -c 'echo a{3,4}'
This prints the same output twice unless you comment-out the SHELL= line
Option 3
If you can't/don't want to modify the make file, you can invoke it like so:
make SHELL=/bin/bash
beware of interactions with sub-makefiles or includes. You might want to look at the make -e option and the make export keyword: http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html
Make has a function to do this:
#mkdir -pv $(addprefix test/,a b)
gets expanded to
#mkdir -pv test/a test/b
The docs are very thorough.
It's been a long, long time since I've used Make...
There are several ways to specify a particular shell to use. The default shell for old Make was the original Bourne shell. If you wanted a different shell, you had to set it yourself.
You're using Linux and GNU, so I'll assume that you're using BASH as the default shell. Try this command in your Make:
echo "random = $RANDOM"
If this simply prints random = and doesn't include a random number, your Make is using Bourne shell as its default shell instead of BASH. (Which is weird because I didn't think there was a real Bourne shell in Linux...) To get around this:
You can add in a SHELL macro pointing to the BASH shell.
You can include the shell in your command.
Instead of:
#mkdir -pv test/{a,b}
Put this:
/bin/bash -c #mkdir -pv test/{a,b}
This specifies you want to use BASH and not the standard /bin/sh Bourne shell.
If the echo random = $RANDOM does print a random number, you're using BASH (or at least Kornshell), but the BRACE EXPANSION might not be set. Try using this in your Makefile:
set -o
And make sure braceexpand is on. It could be off when you run Make.

Resources