Subject: Re: bug#53355: guix shell --check: confusing error message

From: Chris Marusich <[email-masked]>
Date: Sun, 13 Feb 2022 15:17:20 -0800

Hi Ludo,

Ludovic Courtès <[email-masked]> writes:

> How about this:
>
> diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
> index ec071402f4..ac2c79ab65 100644
> --- a/guix/scripts/environment.scm
> +++ b/guix/scripts/environment.scm
> @@ -420,7 +420,7 @@ (define script
>      ;; Script to obtain the list of environment variable values.  On a POSIX
>      ;; shell we can rely on 'set', but on fish we have to use 'env' (fish's
>      ;; 'set' truncates values and prints them in a different format.)
> -    "env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
> +    "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
>  
>    (define lines
>      (match (primitive-fork)

Unfortunately, this doesn't quite work.  I tried this patch:

--8<---------------cut here---------------start------------->8---
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index 510cee727f..4399a5dd04 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -420,7 +420,7 @@ (define script
     ;; Script to obtain the list of environment variable values.  On a POSIX
     ;; shell we can rely on 'set', but on fish we have to use 'env' (fish's
     ;; 'set' truncates values and prints them in a different format.)
-    "env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
+    "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
 
   (define lines
     (match (primitive-fork)
@@ -440,7 +440,7 @@ (define lines
               (result (begin
                         (display script port)
                         (let loop ((lines '()))
-                          (match (read-line port)
+                          (match (pk 'read-line (read-line port))
                             ((? eof-object?) (reverse lines))
                             ("GUIX-CHECK-DONE\r"
                              (display "done\n" port)
@@ -458,10 +458,10 @@ (define lines
           ;; but it also truncates values anyway, so don't try to support it.
           (let ((index (string-index line #\=)))
             (if index
-                (vhash-cons (string-take line index)
+                (vhash-cons (pk 'variable line (string-take line index))
                             (string-drop line (+ 1 index))
                             table)
-                table)))
+                (pk 'dropped line table))))
         vlist-null
         lines))
--8<---------------cut here---------------end--------------->8---

Here is the output:

--8<---------------cut here---------------start------------->8---
[0] [env] marusich@suzaku:~/guix-master
$ ./pre-inst-env guix shell --check --pure --development guix
guix shell: checking the environment variables visible from shell '/bin/bash'...

;;; (read-line "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\r")

;;; (read-line "\x1b[?2004h[0] [env] marusich@suzaku:~/guix-master\r\r")

;;; (read-line "$ PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\r")

;;; (read-line "\x1b[?2004l\rPKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig\r")

;;; (read-line "PWD=/home/marusich/guix-master\r")

;;; (read-line "LOGNAME=marusich\r")

;;; (read-line "GUILE_LOAD_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0\r")

;;; (read-line "HOME=/home/marusich\r")

;;; (read-line "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:\r")

;;; (read-line "GUILE_LOAD_COMPILED_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/guile/3.0/site-ccache:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0\r")

;;; (read-line "INFOPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/info\r")

;;; (read-line "TERM=screen.xterm-256color\r")

;;; (read-line "CPLUS_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include/c++:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include\r")

;;; (read-line "ACLOCAL_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/aclocal\r")

;;; (read-line "USER=marusich\r")

;;; (read-line "LIBRARY_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib\r")

;;; (read-line "SHLVL=1\r")

;;; (read-line "GUIX_LOCPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/locale\r")

;;; (read-line "GUIX_ENVIRONMENT=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile\r")

;;; (read-line "PS1=\r")

;;; (read-line "PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/sbin\r")

;;; (read-line "C_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include\r")

;;; (read-line "_=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin/env\r")

;;; (read-line "GUIX-CHECK-DONE\r")

;;; (variable "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit" "PS1")

;;; (dropped "\x1b[?2004h[0] [env] marusich@suzaku:~/guix-master\r" #<vhash 2b482ca0 1 pairs>)

;;; (variable "$ PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit" "$ PS1")

;;; (variable "\x1b[?2004l\rPKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig" "\x1b[?2004l\rPKG_CONFIG_PATH")

;;; (variable "PWD=/home/marusich/guix-master" "PWD")

;;; (variable "LOGNAME=marusich" "LOGNAME")

;;; (variable "GUILE_LOAD_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0" "GUILE_LOAD_PATH")

;;; (variable "HOME=/home/marusich" "HOME")

;;; (variable "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:" "LS_COLORS")

;;; (variable "GUILE_LOAD_COMPILED_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/guile/3.0/site-ccache:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0" "GUILE_LOAD_COMPILED_PATH")

;;; (variable "INFOPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/info" "INFOPATH")

;;; (variable "TERM=screen.xterm-256color" "TERM")

;;; (variable "CPLUS_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include/c++:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include" "CPLUS_INCLUDE_PATH")

;;; (variable "ACLOCAL_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/aclocal" "ACLOCAL_PATH")

;;; (variable "USER=marusich" "USER")

;;; (variable "LIBRARY_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib" "LIBRARY_PATH")

;;; (variable "SHLVL=1" "SHLVL")

;;; (variable "GUIX_LOCPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/locale" "GUIX_LOCPATH")

;;; (variable "GUIX_ENVIRONMENT=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile" "GUIX_ENVIRONMENT")

;;; (variable "PS1=" "PS1")

;;; (variable "PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/sbin" "PATH")

;;; (variable "C_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include" "C_INCLUDE_PATH")

;;; (variable "_=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin/env" "_")
guix shell: warning: variable 'PKG_CONFIG_PATH' is missing from shell environment
hint: One or more environment variables have a different value in the shell than
the one we set.  This means that you may find yourself running code in an
environment different from the one you asked Guix to prepare.

This usually indicates that your shell startup files are unexpectedly
modifying those environment variables.  For example, if you are using Bash,
make sure that environment variables are set or modified in
`~/.bash_profile' and _not_ in `~/.bashrc'.  For more information on Bash
startup files, run:

     info "(bash) Bash Startup Files"

Alternatively, you can avoid the problem by passing the `--container' or
`-C' option.  That will give you a fully isolated environment running in a
"container", immune to the issue described above.

[1] [env] marusich@suzaku:~/guix-master
$ 
--8<---------------cut here---------------end--------------->8---

Most of the interesting stuff happened in the first few lines:

--8<---------------cut here---------------start------------->8---
;;; (read-line "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\r")

;;; (read-line "\x1b[?2004h[0] [env] marusich@suzaku:~/guix-master\r\r")

;;; (read-line "$ PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\r")

;;; (read-line "\x1b[?2004l\rPKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig\r")
--8<---------------cut here---------------end--------------->8---

As you can see, nothing good is happening when the code parses this
later on:

--8<---------------cut here---------------start------------->8---
;;; (variable "PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit" "PS1")

;;; (dropped "\x1b[?2004h[0] [env] marusich@suzaku:~/guix-master\r" #<vhash 2b482ca0 1 pairs>)

;;; (variable "$ PS1=; env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit" "$ PS1")

;;; (variable "\x1b[?2004l\rPKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig" "\x1b[?2004l\rPKG_CONFIG_PATH")
--8<---------------cut here---------------end--------------->8---

Although I'm sure you see it, for clarity I will explain why the above
is bad: The first variable was actually just the entire script being
echoed back; it is not actually an environment variable.  The second
variable "$ PS1" is also not really an environment variable.  And the
variable "\x1b[?2004l\rPKG_CONFIG_PATH", again, appears to contain
garbage at the start, probably from my PS1 value.

Basically, I think we can work around these issues if we just read and
discard all that junk at the start.  I wasn't able to figure out a
graceful way to force that to happen, but I did find that simply
printing a few lines at the start of the script was good enough to work
around the issue on my computer.  Here's my proposed patch, with
debugging statements included:

--8<---------------cut here---------------start------------->8---
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index 510cee727f..35669b39cd 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -420,7 +420,8 @@ (define script
     ;; Script to obtain the list of environment variable values.  On a POSIX
     ;; shell we can rely on 'set', but on fish we have to use 'env' (fish's
     ;; 'set' truncates values and prints them in a different format.)
-    "env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
+    "PS1=; for i in 1 2 3; do echo GUIX_FLUSH_$i; done; \
+env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
 
   (define lines
     (match (primitive-fork)
@@ -439,8 +440,10 @@ (define lines
        (let* ((port   (fdopen controller "r+l"))
               (result (begin
                         (display script port)
+                        (while (not (string=? "GUIX_FLUSH_3\r"
+                                              (read-line port))))
                         (let loop ((lines '()))
-                          (match (read-line port)
+                          (match (pk 'read-line (read-line port))
                             ((? eof-object?) (reverse lines))
                             ("GUIX-CHECK-DONE\r"
                              (display "done\n" port)
@@ -458,10 +461,10 @@ (define lines
           ;; but it also truncates values anyway, so don't try to support it.
           (let ((index (string-index line #\=)))
             (if index
-                (vhash-cons (string-take line index)
+                (vhash-cons (pk 'variable line (string-take line index))
                             (string-drop line (+ 1 index))
                             table)
-                table)))
+                (pk 'dropped line table))))
         vlist-null
         lines))
 
--8<---------------cut here---------------end--------------->8---

And here's the output:

--8<---------------cut here---------------start------------->8---
[0] [env] marusich@suzaku:~/guix-master
$ ./pre-inst-env guix shell --check --pure --development guix
guix shell: checking the environment variables visible from shell '/bin/bash'...

;;; (read-line "PKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig\r")

;;; (read-line "PWD=/home/marusich/guix-master\r")

;;; (read-line "LOGNAME=marusich\r")

;;; (read-line "GUILE_LOAD_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0\r")

;;; (read-line "HOME=/home/marusich\r")

;;; (read-line "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:\r")

;;; (read-line "GUILE_LOAD_COMPILED_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/guile/3.0/site-ccache:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0\r")

;;; (read-line "INFOPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/info\r")

;;; (read-line "TERM=screen.xterm-256color\r")

;;; (read-line "CPLUS_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include/c++:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include\r")

;;; (read-line "ACLOCAL_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/aclocal\r")

;;; (read-line "USER=marusich\r")

;;; (read-line "LIBRARY_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib\r")

;;; (read-line "SHLVL=1\r")

;;; (read-line "GUIX_LOCPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/locale\r")

;;; (read-line "GUIX_ENVIRONMENT=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile\r")

;;; (read-line "PS1=\r")

;;; (read-line "PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/sbin\r")

;;; (read-line "C_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include\r")

;;; (read-line "_=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin/env\r")

;;; (read-line "GUIX-CHECK-DONE\r")

;;; (variable "PKG_CONFIG_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/pkgconfig" "PKG_CONFIG_PATH")

;;; (variable "PWD=/home/marusich/guix-master" "PWD")

;;; (variable "LOGNAME=marusich" "LOGNAME")

;;; (variable "GUILE_LOAD_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0" "GUILE_LOAD_PATH")

;;; (variable "HOME=/home/marusich" "HOME")

;;; (variable "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:" "LS_COLORS")

;;; (variable "GUILE_LOAD_COMPILED_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/guile/3.0/site-ccache:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/guile/site/3.0" "GUILE_LOAD_COMPILED_PATH")

;;; (variable "INFOPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/info" "INFOPATH")

;;; (variable "TERM=screen.xterm-256color" "TERM")

;;; (variable "CPLUS_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include/c++:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include" "CPLUS_INCLUDE_PATH")

;;; (variable "ACLOCAL_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/share/aclocal" "ACLOCAL_PATH")

;;; (variable "USER=marusich" "USER")

;;; (variable "LIBRARY_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib" "LIBRARY_PATH")

;;; (variable "SHLVL=1" "SHLVL")

;;; (variable "GUIX_LOCPATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/lib/locale" "GUIX_LOCPATH")

;;; (variable "GUIX_ENVIRONMENT=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile" "GUIX_ENVIRONMENT")

;;; (variable "PS1=" "PS1")

;;; (variable "PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin:/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/sbin" "PATH")

;;; (variable "C_INCLUDE_PATH=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/include" "C_INCLUDE_PATH")

;;; (variable "_=/gnu/store/hvcq6yjfjjc7060pq09zm1rj02mivg4h-profile/bin/env" "_")
guix shell: All is good!  The shell gets correct environment variables.
[0] [env] marusich@suzaku:~/guix-master
$ 
--8<---------------cut here---------------end--------------->8---

As you can see, it seems to be working correctly here.

Here's a version of the patch that is ready for committing, with the
debug statements removed and comments added:

From c3eea81846ae71a246e6b592be74062f4bf26474 Mon Sep 17 00:00:00 2001
From: Chris Marusich <[email-masked]>
Date: Sun, 13 Feb 2022 14:15:14 -0800
Subject: [PATCH] environment: Prevent PS1 from clobbering output in 'check'.

Fixes: <https://issues.guix.gnu.org/51466>.

* guix/scripts/environment.scm (child-shell-environment): In the script
executed the child shell, set PS1 to an empty value and then echo three
sentinel lines to try to "flush" the original PS1 value before printing the
environment variables.  In the parent process, read and discard all lines up
to and including the last sentinel line.  After that, read the remaining lines
as usual.
---
 guix/scripts/environment.scm | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index ec071402f4..0b137467f9 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2014, 2015, 2018 David Thompson <[email-masked]>
 ;;; Copyright © 2015-2022 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2018 Mike Gerwitz <[email-masked]>
+;;; Copyright © 2022 Chris Marusich <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -420,7 +421,16 @@ by running 'set' in the shell."
     ;; Script to obtain the list of environment variable values.  On a POSIX
     ;; shell we can rely on 'set', but on fish we have to use 'env' (fish's
     ;; 'set' truncates values and prints them in a different format.)
-    "env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
+    ;;
+    ;; Why print "GUIX_FLUSH" a few times?  We are trying to "flush" the
+    ;; original PS1 value to the port so we can read it (and discard it)
+    ;; before we start reading the environment variables from the port.  If we
+    ;; don't do this, the original PS1 value can sometimes get interleaved
+    ;; into the output, which interferes with our parsing logic.  It's a hack,
+    ;; but in practice it seems to do the job.  If you know of a more graceful
+    ;; solution, please implement it!  See: https://issues.guix.gnu.org/51466
+    "PS1=; for i in 1 2 3; do echo GUIX_FLUSH_$i; done; \
+env || /usr/bin/env || set; echo GUIX-CHECK-DONE; read x; exit\n")
 
   (define lines
     (match (primitive-fork)
@@ -439,6 +449,12 @@ by running 'set' in the shell."
        (let* ((port   (fdopen controller "r+l"))
               (result (begin
                         (display script port)
+                        ;; Ignore all lines up to and including the final
+                        ;; "GUIX_FLUSH" line.
+                        (while (not (string=? "GUIX_FLUSH_3\r"
+                                              (read-line port))))
+                        ;; Now (hopefully) the original PS1 value will not be
+                        ;; interleaved in the remaining lines.
                         (let loop ((lines '()))
                           (match (read-line port)
                             ((? eof-object?) (reverse lines))

base-commit: d65979c46c99dc36324ca94aa9650b9de37f22de
-- 
2.26.3

And here's its output:

--8<---------------cut here---------------start------------->8---
[0] [env] marusich@suzaku:~/guix-master
$ ./pre-inst-env guix shell --check --pure --development guix
guix shell: checking the environment variables visible from shell '/bin/bash'...
guix shell: All is good!  The shell gets correct environment variables.
[0] [env] marusich@suzaku:~/guix-master
$ 
--8<---------------cut here---------------end--------------->8---

WDYT?

-- 
Chris

PGP: https://savannah.gnu.org/people/viewgpg.php?user_id=106836