Bug 233545 - bin/sh: "export VAR" always defines VAR unlike other shells
Summary: bin/sh: "export VAR" always defines VAR unlike other shells
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Jilles Tjoelker
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2018-11-26 20:23 UTC by Jan Beich
Modified: 2019-01-03 20:25 UTC (History)
3 users (show)

See Also:


Attachments
v0 (blind backport) (1.37 KB, patch)
2018-11-26 20:23 UTC, Jan Beich
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Beich freebsd_committer freebsd_triage 2018-11-26 20:23:19 UTC
Created attachment 199580 [details]
v0 (blind backport)

I'm trying to build a project that conditionally defines variables but always exports them. With FreeBSD sh those unset end up defined with empty value. If make/gmake/etc is later invoked ?= assignments are ignored.

  $ env -i sh -c 'export CC; printenv' | fgrep CC
  CC=
  $ env -i sh -c 'export CC; make -V CC'

dash, pdksh, bash, zsh aren't affected. NetBSD sh fixed it in https://github.com/netbsd/src/commit/9ad7f3a0e1b5
Comment 1 Jan Beich freebsd_committer freebsd_triage 2018-11-26 21:10:46 UTC
For a real example see https://github.com/unicorn-engine/unicorn/blob/73f457353543/make.sh#L120 found via

$ pkg install git cmake gmake ninja sdl2
$ git clone https://github.com/yuzu-emu/yuzu/
$ mkdir yuzu_build; cd yuzu_build
$ cmake -GNinja -DENABLE_QT=OFF ../yuzu
[..]
FAILED: /path/to/yuzu/externals/unicorn/libunicorn.a
cd /path/to/yuzu/externals/unicorn && /usr/local/bin/cmake -E env UNICORN_ARCHS="aarch64" PYTHON="/usr/local/bin/python2.7" /bin/sh make.sh macos-universal-no
g -shared qemu/aarch64-softmmu/tcg/tcg.o ... uc.o list.o -o libunicorn.so.1 -Wl,-Bsymbolic-functions,-soname,libunicorn.so.1 -lm
gmake: g: Command not found
gmake: [Makefile:232: libunicorn.so.1] Error 127 (ignored)
ln -sf libunicorn.so.1 libunicorn.so
gmake -C samples
gmake[1]: Entering directory '/path/to/yuzu/externals/unicorn/samples'
g -Wall -Werror -I../include -c sample_arm64.c -o sample_arm64.o
gmake[1]: g: Command not found
gmake[1]: [Makefile:129: sample_arm64.o] Error 127 (ignored)
g -Wall -Werror -I../include -c sample_arm64eb.c -o sample_arm64eb.o
gmake[1]: g: Command not found
gmake[1]: [Makefile:129: sample_arm64eb.o] Error 127 (ignored)
sample_arm64.o  -L.. -lunicorn -lpthread -lm -o sample_arm64
gmake[1]: sample_arm64.o: Command not found
gmake[1]: *** [Makefile:105: sample_arm64] Error 127
gmake[1]: Leaving directory '/path/to/yuzu/externals/unicorn/samples'
gmake: *** [Makefile:214: all] Error 2
Comment 2 Jilles Tjoelker freebsd_committer freebsd_triage 2018-11-26 22:59:01 UTC
Good catch. It somewhat surprises me that this has been broken for so long.

The environment() part of the patch looks good, but the exportcmd() part is redundant since setvar() already sets VUNSET if the value to be set is NULL (something like  sh -uc 'export thisshouldnotbehere; echo "$thisshouldnotbehere"'  detects the unset variable as it should). Also, a test should be added, preferably using env(1) or ${SH} itself only and not printenv(1) since it's not in POSIX.
Comment 3 commit-hook freebsd_committer freebsd_triage 2019-01-03 20:23:20 UTC
A commit references this bug:

Author: jilles
Date: Thu Jan  3 20:22:36 UTC 2019
New revision: 342740
URL: https://svnweb.freebsd.org/changeset/base/342740

Log:
  sh: Do not place exported but unset variables into the environment

  PR:		233545
  Submitted by:	Jan Beich
  Obtained from:	NetBSD

Changes:
  head/bin/sh/var.c
Comment 4 commit-hook freebsd_committer freebsd_triage 2019-01-03 20:23:23 UTC
A commit references this bug:

Author: jilles
Date: Thu Jan  3 20:23:13 UTC 2019
New revision: 342741
URL: https://svnweb.freebsd.org/changeset/base/342741

Log:
  sh: Add test for exported but unset variables

  PR:		233545

Changes:
  head/bin/sh/tests/execution/Makefile
  head/bin/sh/tests/execution/env1.0