Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bash: Fix bashisms being applied to non-bash shells #4334

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

TraceyC77
Copy link
Contributor

@TraceyC77 TraceyC77 commented Nov 12, 2024

Summary

Move sourcing of bashrc.d directory to default skel/.bashrc
Make all scripts in profile.d POSIX compliant
Fixes issues with errors being emitted by non-bash shells
Fixes bash specific user scripts improperly being loaded by other shells
Add README for profile.d files needing to be POSIX compliant

Test Plan

Installed the new eopkgs & rebooted. Verified:
bash loads properly with no errors
Scripts in ~/.bashrc.d/ loaded
zsh loads properly with no errors
Scripts in
Scripts in /usr/share/defaults/etc/profile were loaded for both shells

Checklist

  • Package was built and tested against unstable

Fixes #4214

@TraceyC77
Copy link
Contributor Author

There is one problem I still need to solve. The block to source ~/.bashrc.d has been moved from /usr/share/defaults/etc/profile to /etc/skel/.bashrc so that a user's bash scripts are only sourced by bash, not all shells. This will be find for new users on a system, but we need a way to add that block for existing users on the system. I am not sure how to approach that, ideas are welcome

@TraceyC77 TraceyC77 self-assigned this Nov 12, 2024
@TraceyC77 TraceyC77 linked an issue Nov 12, 2024 that may be closed by this pull request
1 task
@ermo
Copy link
Contributor

ermo commented Nov 13, 2024

As requested:

Gentle suggestion to perhaps also consider adding zsh /etc/skel files that support ~/.zshrc.d/* auto-loading?

Another (alternative?) option is to check the shell being run in the vendor scripts under /usr/share/defaults, and then, depending on shell, auto-loading ~/{ba,z}shrc.d/* files?

@TraceyC77
Copy link
Contributor Author

Gentle suggestion to perhaps also consider adding zsh /etc/skel files that support ~/.zshrc.d/* auto-loading?

I can add that to the .zshrc file, similar to how .bashrc loads ~/.bashrc.d/*
This is pretty standard

Another (alternative?) option is to check the shell being run in the vendor scripts under /usr/share/defaults, and then, depending on shell, auto-loading ~/{ba,z}shrc.d/* files?

That is not standard, and fragile. If you load a shell, it loads its startup files (like .bashrc / .zshrc) which then (per this PR) load the scripts directory. What you suggest would add unnecessary complication IMO.

Thanks for the feedback :)

@TraceyC77 TraceyC77 force-pushed the zsh_source_app_configs branch from 231d736 to b69573a Compare January 1, 2025 18:41
@TraceyC77
Copy link
Contributor Author

After testing changes after restoring zsh loading the profile.d folder I discovered bugs in 50-prompt.sh with zsh. I've updated it to fix a bug with using $SHELL to determine which shell to provide for. I also added a prompt that works with zsh in the same style as the one for bash.

Testing:
Installed the updated zsh and bash packages
Created a new user
Switched between bash and zsh
Made zsh the default shell, switched back and forth between that and bash
Verified prompt looks as expected, output works as expected, no errors emitted
Changed into a git directory, verified prompt
Verified in Konsole & Tilix that text reflows properly when window is resized
Used arrows to navigate through history and verified text flowed properly

@TraceyC77 TraceyC77 force-pushed the zsh_source_app_configs branch from 15e6397 to 0803406 Compare January 3, 2025 03:16
Tracey Clark and others added 3 commits January 2, 2025 21:21
Move sourcing of bashrc.d directory to default skel/.bashrc
Make all scripts in profile.d POSIX compliant
Fixes issues with errors being emitted by non-bash shells
Fixes bash specific user scripts improperly being loaded by other shells
Add README for profile.d files needing to be POSIX compliant
Source profile.d files again to regain default settings now that they are POSIX compliant
Also fix method of getting shell to get current, not default

**Summary**
@TraceyC77
Copy link
Contributor Author

@ermo , if you could give this another look after sync, I'd like to get this in early enough for most of a week of testing. Thanks!

Copy link
Contributor

@ermo ermo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not keen on being on the hook for approving this. It would be better if an avid zsh user could try it out and see if it is fit for purpose.

Nonetheless, I have left some comments that came to me when reading through the files. I hope you find them useful. =)

@@ -1,7 +1,10 @@
# Begin /usr/share/defaults/etc/profile.d/50-history.sh

# Append to history file on exit instead of overwrite (parallel terminals)
shopt -s histappend
# shopt is bash only
if [ $SHELL = "/usr/bin/bash" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that

Suggested change
if [ $SHELL = "/usr/bin/bash" ]; then
if [ -n "$BASH_VERSION" ]; then

... is a very effective way to check if the running shell is bash.

endchar="\$"
if [ "$UID" = "0" ]; then
endchar="#"
elif [[ "$current_shell" =~ zsh ]]; then
Copy link
Contributor

@ermo ermo Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this logic is sound.

What I would do is to add a check like this:

# Default that doesn't look like anything a shell would normally ship
endchar="?" # pick a suitable default here
if [ -n "$BASH_VERSION" ]; then
    endchar="\$"
elif [ -n "$ZSH_VERSION" ]; then
    endchar="%#"
fi

... as those change in a shell-defined way, depending on whether a shell is running as euid 0 or not.

@@ -1,23 +1,53 @@
# Begin /usr/share/defaults/etc/profile.d/50-prompt.sh

# We cant use $SHELL since we need the *current* shell.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the prompt is only really relevant for interactive shells, maybe return early if the terminal is not interactive?

Suggested change
# We cant use $SHELL since we need the *current* shell.
# No point parsing this file for non-interactive shells that don't need a prompt
[ -t 0 ] || return 0
# We cant use $SHELL since we need the *current* shell.

if [[ "$current_shell" =~ bash ]]; then
PS1="\[${FG}\]\u\[${AT}\]@\[${HCOLOR}\]\H \[${DIR}\]\w \[${FG}\]$endchar \[${reset_color}\]"
elif [[ "$current_shell" =~ zsh ]]; then
PS1="%{${FG}%}%n%{${AT}%}@%{${HCOLOR}%}%m %{${DIR}%}%1~ %{${FG}%}$endchar# ${reset_color}"
Copy link
Contributor

@ermo ermo Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken together with my suggestion above, the # after $endchar is no longer necessary.

Note also that this uses double brackets, which is not very POSIX-y.


# bash and zsh handle prompt setup and character escaping differently

if [[ "$current_shell" =~ bash ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another instance where the [ -n "$BASH_VERSION"] or [ -n "$ZSH_VERSION" ] idiom might be nice?

unset endchar

# shopt is bash only
if [[ "$current_shell" =~ bash ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more instance where [ -n "$BASH_VERSION" ] might be fruitful (and more POSIX-y).

if [ -f /usr/share/defaults/etc/profile.d/vte.sh ]; then
source /usr/share/defaults/etc/profile.d/vte.sh
fi
# This should always be sourced regardless of the above files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block should probably be at the top of the script, so the system zprofile in /etc can override vendor config settings...?

@TraceyC77 TraceyC77 added this to the Solus 4.8 Epoch milestone Jan 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Ready
Development

Successfully merging this pull request may close these issues.

bash: fix 50-prompt.sh
2 participants