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
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 @subsubheading Bash Home Service
@anchor{home-bash-configuration} @anchor{home-bash-configuration}
@c %start of fragment
@deftp {Data Type} home-bash-configuration @deftp {Data Type} home-bash-configuration
Available @code{home-bash-configuration} fields are: 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 this is already taken care of by the globally installed
@file{/etc/bashrc}. @file{/etc/bashrc}.
@item @code{environment-variables} (default: @code{'()}) (type: alist) @item @code{environment-variables} (default: @code{()}) (type: alist)
Association list of environment variables to set for the Bash session. The Association list of environment variables to set for the Bash session.
rules for the @code{home-environment-variables-service-type} apply The rules for the @code{home-environment-variables-service-type} apply
here (@pxref{Essential Home Services}). The contents of this field will be here (@pxref{Essential Home Services}). The contents of this field will
added after the contents of the @code{bash-profile} field. 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 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 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, put in the @file{.bashrc} file. The alias will automatically be quoted,
@@ -50355,27 +50363,31 @@ turns into
alias ls="ls -alF" alias ls="ls -alF"
@end example @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}. 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 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} cases the shell started on tty just after login). @file{.bash_login}
won't be ever read, because @file{.bash_profile} always present. 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 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 executing user's commands at start of interactive shell (The shell
for interactive usage started by typing @code{bash} or by terminal app for interactive usage started by typing @code{bash} or by terminal app
or any other program). 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}. 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 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 be read in some cases (if the shell terminates by exec'ing another
process for example). process for example).
@end table @end table
@end deftp @end deftp
@c %end of fragment
You can extend the Bash service by using the @code{home-bash-extension} You can extend the Bash service by using the @code{home-bash-extension}
configuration record, whose fields must mirror that of configuration record, whose fields must mirror that of
@code{home-bash-configuration} (@pxref{home-bash-configuration}). The @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 For example, here is how you would define a service that extends the
Bash service such that @file{~/.bash_profile} defines an additional Bash service such that @file{~/.bash_profile} defines an additional
environment variable, @env{PS1}: shell variable, @env{PS1}:
@lisp @lisp
(define bash-fancy-prompt-service (define bash-fancy-prompt-service
(simple-service 'bash-fancy-prompt (simple-service 'bash-fancy-prompt
home-bash-service-type home-bash-service-type
(home-bash-extension (home-bash-extension
(environment-variables (variables
'(("PS1" . "\\u \\wλ ")))))) '(("PS1" . "\\u \\wλ "))))))
@end lisp @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{services} field of your @code{home-environment}. The reference of
@code{home-bash-extension} follows. @code{home-bash-extension} follows.
@c %start of fragment
@deftp {Data Type} home-bash-extension @deftp {Data Type} home-bash-extension
Available @code{home-bash-extension} fields are: Available @code{home-bash-extension} fields are:
@table @asis @table @asis
@item @code{environment-variables} (default: @code{'()}) (type: alist) @item @code{environment-variables} (default: @code{()}) (type: alist)
Additional environment variables to set. These will be combined with the Additional environment variables to set. These will be combined with
environment variables from other extensions and the base service to form one the environment variables from other extensions and the base service to
coherent block of environment variables. 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 Additional aliases to set. These will be combined with the aliases from
other extensions and the base service. other extensions and the base service.
@item @code{bash-profile} (default: @code{'()}) (type: text-config) @item @code{bash-profile} (default: @code{()}) (type: text-config)
Additional text blocks to add to @file{.bash_profile}, which will be combined Additional text blocks to add to @file{.bash_profile}, which will be
with text blocks from other extensions and the base service. 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 Additional text blocks to add to @file{.bashrc}, which will be combined
with text blocks from other extensions and the base service. with text blocks from other extensions and the base service.
@item @code{bash-logout} (default: @code{'()}) (type: text-config) @item @code{bash-logout} (default: @code{()}) (type: text-config)
Additional text blocks to add to @file{.bash_logout}, which will be combined Additional text blocks to add to @file{.bash_logout}, which will be
with text blocks from other extensions and the base service. combined with text blocks from other extensions and the base service.
@end table @end table
@end deftp @end deftp
@c %end of fragment
@subsubheading Zsh Home Service @subsubheading Zsh Home Service
@deftp {Data Type} home-zsh-configuration @deftp {Data Type} home-zsh-configuration

View File

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

View File

@@ -1,7 +1,7 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in> ;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> ;;; 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> ;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@@ -58,6 +58,7 @@
with-shell-quotation-bindings with-shell-quotation-bindings
environment-variable-shell-definitions environment-variable-shell-definitions
shell-variable-definitions
home-files-directory home-files-directory
xdg-configuration-files-directory xdg-configuration-files-directory
xdg-data-files-directory xdg-data-files-directory
@@ -241,6 +242,27 @@ ensures variable values are properly quoted."
"\n"))) "\n")))
variables)))) 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) (define (environment-variables->setup-environment-script vars)
"Return a file that can be sourced by a POSIX compliant shell which "Return a file that can be sourced by a POSIX compliant shell which
initializes the environment. The file will source the home initializes the environment. The file will source the home

View File

@@ -2,6 +2,7 @@
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in> ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2025 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; 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) (define (serialize-posix-env-vars field-name val)
(environment-variable-shell-definitions val)) (environment-variable-shell-definitions val))
(define (serialize-shell-variables field value)
(shell-variable-definitions value))
;;; ;;;
;;; Zsh. ;;; 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 here (@pxref{Essential Home Services}). The contents of this field will be
added after the contents of the @code{bash-profile} field." added after the contents of the @code{bash-profile} field."
(serializer serialize-posix-env-vars)) (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 (aliases
(alist %default-bash-aliases) (alist %default-bash-aliases)
"Association list of aliases to set for the Bash session. The aliases will be "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 ,@(list (file-if-not-empty
'bashrc 'bashrc
(if (home-bash-configuration-guix-defaults? config) (let ((user-settings (list (serialize-field 'variables) "\n"
(list (plain-file-content %default-bashrc) "\n" (serialize-field 'aliases))))
(serialize-field 'aliases)) (if (home-bash-configuration-guix-defaults? config)
(list (serialize-field 'aliases)))) (cons* (plain-file-content %default-bashrc) "\n"
user-settings)
user-settings)))
(file-if-not-empty 'bash-logout))))) (file-if-not-empty 'bash-logout)))))
(define (add-bash-packages config) (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 "Additional environment variables to set. These will be combined with the
environment variables from other extensions and the base service to form one environment variables from other extensions and the base service to form one
coherent block of environment variables.") 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 (aliases
(alist '()) (alist '())
"Additional aliases to set. These will be combined with the aliases from "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) (define (home-bash-extensions original-config extension-configs)
(match-record original-config <home-bash-configuration> (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 (home-bash-configuration
(inherit original-config) (inherit original-config)
(environment-variables (environment-variables
(append environment-variables (append environment-variables
(append-map (append-map
home-bash-extension-environment-variables extension-configs))) home-bash-extension-environment-variables extension-configs)))
(variables
(append variables
(append-map
home-bash-extension-variables extension-configs)))
(aliases (aliases
(append aliases (append aliases
(append-map (append-map