home: services: bash: Support setting shell variables.

* gnu/home/services.scm (shell-variable-definitions): New procedure.
* gnu/home/services/shells.scm (serialize-shell-variables): New procedure.
(home-bash-configuration)[variables]: New field.
(add-bash-configuration): Honor it.
(home-bash-extension)[variables]: New field.
(home-bash-extensions): Handle ‘variables’.
* doc/guix.texi (Shells Home Services): Update.  Change ‘PS1’ example to use
‘variables’, not ‘environment-variables’.
* doc/he-config-bare-bones.scm: Use ‘variables’ instead of ‘bash-profile’.

Change-Id: I29083d6313d10b1eb9d91eccacfb33efefe60d58
This commit is contained in:
Ludovic Courtès 2025-09-30 11:08:13 +02:00
parent a1276ea843
commit 3f900442b4
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
4 changed files with 96 additions and 31 deletions

View file

@ -50319,6 +50319,8 @@ Extend home-shell-profile service only if you really know what you do.
@subsubheading Bash Home Service
@anchor{home-bash-configuration}
@c %start of fragment
@deftp {Data Type} home-bash-configuration
Available @code{home-bash-configuration} fields are:
@ -50333,13 +50335,19 @@ use Guix System, is it safe to set this to @code{#f}, as in this case
this is already taken care of by the globally installed
@file{/etc/bashrc}.
@item @code{environment-variables} (default: @code{'()}) (type: alist)
Association list of environment variables to set for the Bash session. The
rules for the @code{home-environment-variables-service-type} apply
here (@pxref{Essential Home Services}). The contents of this field will be
added after the contents of the @code{bash-profile} field.
@item @code{environment-variables} (default: @code{()}) (type: alist)
Association list of environment variables to set for the Bash session.
The rules for the @code{home-environment-variables-service-type} apply
here (@pxref{Essential Home Services}). The contents of this field will
be added after the contents of the @code{bash-profile} field.
@item @code{aliases} (default: @code{%default-bash-aliases}) (type: alist)
@item @code{variables} (default: @code{()}) (type: alist)
Bash variables (not to be confused with environment variables) to be set
in @file{.bashrc} for use by interactive shells. A typical example of
such variables is @code{HISTSIZE} and related history variables
(@pxref{Bash Variables,,, bash,Bash Reference Manual}).
@item @code{aliases} (type: alist)
Association list of aliases to set for the Bash session. The aliases
will be defined after the contents of the @code{bashrc} field has been
put in the @file{.bashrc} file. The alias will automatically be quoted,
@ -50355,27 +50363,31 @@ turns into
alias ls="ls -alF"
@end example
@item @code{bash-profile} (default: @code{'()}) (type: text-config)
@item @code{bash-profile} (default: @code{()}) (type: text-config)
List of file-like objects, which will be added to @file{.bash_profile}.
Used for executing user's commands at start of login shell (In most
cases the shell started on tty just after login). @file{.bash_login}
won't be ever read, because @file{.bash_profile} always present.
@item @code{bashrc} (default: @code{'()}) (type: text-config)
@item @code{bashrc} (default: @code{()}) (type: text-config)
List of file-like objects, which will be added to @file{.bashrc}. Used
for executing user's commands at start of interactive shell (The shell
for interactive usage started by typing @code{bash} or by terminal app
or any other program).
@item @code{bash-logout} (default: @code{'()}) (type: text-config)
@item @code{bash-logout} (default: @code{()}) (type: text-config)
List of file-like objects, which will be added to @file{.bash_logout}.
Used for executing user's commands at the exit of login shell. It won't
be read in some cases (if the shell terminates by exec'ing another
process for example).
@end table
@end deftp
@c %end of fragment
You can extend the Bash service by using the @code{home-bash-extension}
configuration record, whose fields must mirror that of
@code{home-bash-configuration} (@pxref{home-bash-configuration}). The
@ -50385,14 +50397,14 @@ Bash Reference Manual}.
For example, here is how you would define a service that extends the
Bash service such that @file{~/.bash_profile} defines an additional
environment variable, @env{PS1}:
shell variable, @env{PS1}:
@lisp
(define bash-fancy-prompt-service
(simple-service 'bash-fancy-prompt
home-bash-service-type
(home-bash-extension
(environment-variables
(variables
'(("PS1" . "\\u \\wλ "))))))
@end lisp
@ -50400,34 +50412,43 @@ You would then add @code{bash-fancy-prompt-service} to the list in the
@code{services} field of your @code{home-environment}. The reference of
@code{home-bash-extension} follows.
@c %start of fragment
@deftp {Data Type} home-bash-extension
Available @code{home-bash-extension} fields are:
@table @asis
@item @code{environment-variables} (default: @code{'()}) (type: alist)
Additional environment variables to set. These will be combined with the
environment variables from other extensions and the base service to form one
coherent block of environment variables.
@item @code{environment-variables} (default: @code{()}) (type: alist)
Additional environment variables to set. These will be combined with
the environment variables from other extensions and the base service to
form one coherent block of environment variables.
@item @code{aliases} (default: @code{'()}) (type: alist)
@item @code{variables} (default: @code{()}) (type: alist)
Extra Bash variables (not to be confused with environment variables) to
be set in @file{.bashrc} for use by interactive shells.
@item @code{aliases} (default: @code{()}) (type: alist)
Additional aliases to set. These will be combined with the aliases from
other extensions and the base service.
@item @code{bash-profile} (default: @code{'()}) (type: text-config)
Additional text blocks to add to @file{.bash_profile}, which will be combined
with text blocks from other extensions and the base service.
@item @code{bash-profile} (default: @code{()}) (type: text-config)
Additional text blocks to add to @file{.bash_profile}, which will be
combined with text blocks from other extensions and the base service.
@item @code{bashrc} (default: @code{'()}) (type: text-config)
@item @code{bashrc} (default: @code{()}) (type: text-config)
Additional text blocks to add to @file{.bashrc}, which will be combined
with text blocks from other extensions and the base service.
@item @code{bash-logout} (default: @code{'()}) (type: text-config)
Additional text blocks to add to @file{.bash_logout}, which will be combined
with text blocks from other extensions and the base service.
@item @code{bash-logout} (default: @code{()}) (type: text-config)
Additional text blocks to add to @file{.bash_logout}, which will be
combined with text blocks from other extensions and the base service.
@end table
@end deftp
@c %end of fragment
@subsubheading Zsh Home Service
@deftp {Data Type} home-zsh-configuration

View file

@ -13,8 +13,9 @@
(service home-bash-service-type
(home-bash-configuration
(guix-defaults? #t)
(bash-profile (list (plain-file "bash-profile" "\
export HISTFILE=$XDG_CACHE_HOME/.bash_history")))))
(variables
`(("HISTFILE" . "$XDG_CACHE_HOME/.bash_history")
("HISTSIZE" . "50000")))))
(simple-service 'test-config
home-xdg-configuration-files-service-type

View file

@ -1,7 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2022-2023, 2025 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
;;;
;;; This file is part of GNU Guix.
@ -58,6 +58,7 @@
with-shell-quotation-bindings
environment-variable-shell-definitions
shell-variable-definitions
home-files-directory
xdg-configuration-files-directory
xdg-data-files-directory
@ -241,6 +242,27 @@ ensures variable values are properly quoted."
"\n")))
variables))))
(define (shell-variable-definitions variables)
"Return a gexp that evaluates to a list of POSIX shell statements defining
VARIABLES, a list of variable name/value pairs, as shell variables (not
environment variables). The returned code ensures variable values are
properly quoted."
(with-shell-quotation-bindings
#~(string-append
#$@(map (match-lambda
((key . (or (? string? value)
(? file-like? value)
(? gexp? value)))
#~(string-append #$key "="
(shell-double-quote #$value)
"\n"))
((key . (? literal-string? value))
#~(string-append #$key "="
(shell-single-quote
#$(literal-string-value value))
"\n")))
variables))))
(define (environment-variables->setup-environment-script vars)
"Return a file that can be sourced by a POSIX compliant shell which
initializes the environment. The file will source the home

View file

@ -2,6 +2,7 @@
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2025 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -121,6 +122,9 @@ service type can be extended with a list of file-like objects.")))
(define (serialize-posix-env-vars field-name val)
(environment-variable-shell-definitions val))
(define (serialize-shell-variables field value)
(shell-variable-definitions value))
;;;
;;; Zsh.
@ -347,6 +351,13 @@ rules for the @code{home-environment-variables-service-type} apply
here (@pxref{Essential Home Services}). The contents of this field will be
added after the contents of the @code{bash-profile} field."
(serializer serialize-posix-env-vars))
(variables
(alist '())
"Bash variables (not to be confused with environment variables) to be set
in @file{.bashrc} for use by interactive shells. A typical example of such
variables is @code{HISTSIZE} and related history variables (@pxref{Bash
Variables,,, bash, Bash Reference Manual})."
(serializer serialize-shell-variables))
(aliases
(alist %default-bash-aliases)
"Association list of aliases to set for the Bash session. The aliases will be
@ -425,10 +436,12 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
,@(list (file-if-not-empty
'bashrc
(let ((user-settings (list (serialize-field 'variables) "\n"
(serialize-field 'aliases))))
(if (home-bash-configuration-guix-defaults? config)
(list (plain-file-content %default-bashrc) "\n"
(serialize-field 'aliases))
(list (serialize-field 'aliases))))
(cons* (plain-file-content %default-bashrc) "\n"
user-settings)
user-settings)))
(file-if-not-empty 'bash-logout)))))
(define (add-bash-packages config)
@ -440,6 +453,10 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
"Additional environment variables to set. These will be combined with the
environment variables from other extensions and the base service to form one
coherent block of environment variables.")
(variables
(alist '())
"Extra Bash variables (not to be confused with environment variables) to be
set in @file{.bashrc} for use by interactive shells.")
(aliases
(alist '())
"Additional aliases to set. These will be combined with the aliases from
@ -459,13 +476,17 @@ with text blocks from other extensions and the base service."))
(define (home-bash-extensions original-config extension-configs)
(match-record original-config <home-bash-configuration>
(environment-variables aliases bash-profile bashrc bash-logout)
(environment-variables variables aliases bash-profile bashrc bash-logout)
(home-bash-configuration
(inherit original-config)
(environment-variables
(append environment-variables
(append-map
home-bash-extension-environment-variables extension-configs)))
(variables
(append variables
(append-map
home-bash-extension-variables extension-configs)))
(aliases
(append aliases
(append-map