Skip to content

2.8 Shell Environment

D3vil0p3r edited this page May 14, 2023 · 1 revision

Shells

In Athena OS, three shells are mainly used: BASH, FISH, ZSH and PowerShell. For BASH, FISH and ZSH the same prompt pattern has been used.

BASH

.bashrc (or /etc/bash.bashrc for root user) has been edited by changing PS1 variable as follows:

PS1="\e[1;32m┌──[HQ🚀\e[1;31m$(ip -4 addr | grep -v 127.0.0.1 | grep -v secondary | grep -Po "inet \K[\d.]+" | sed -z "s/\n/|/g;s/|$/\n/")⚔️\u\e[1;32m]\n└──╼[👾]\[\e[1;36m\]\$(pwd) $ \[\e[0m\]"

NOTE: the output colors could be affected by the current terminal theme. Furthermore, after \n, \[ characters have been used for wrapping the entire string for color: \[\e[36m\] and \[\e[0m\]. If this wrapping is not implemented, \n causes the shell to counts additional invisible character: https://superuser.com/questions/382456/why-does-this-bash-prompt-sometimes-keep-part-of-previous-commands-when-scrollin

For getting emoji to be placed on PS1, refer to: https://emojipedia.org/ (here alien, war, rocket, space have been searched). On GNOME, the gnome-characters package is needed.

If other kind of icons are needed: https://levelup.gitconnected.com/how-to-customize-your-command-prompt-and-icons-in-your-terminal-f88ea15a5d58

In general, BASH is not able to retrieve the new configuration on .bashrc automatically. For example, if the shell prompt changes due to a command, this change is not applied on the current shell session. For solving this, on .bashrc the following line has been added:

export PROMPT_COMMAND='source ~/.bashrc'

FISH

The implementation of FISH shell comes because of some characteristics as:

  • Extensive UI: syntax highlighting, Autosuggestions, tab completion and selection lists that can be navigated and filtered.
  • No configuration needed: FISH is designed to be ready to use immediately, without requiring extensive configuration.
  • Easy scripting: new functions can be added on the fly. The syntax is easy to learn and use.

Since FISH and BASH use different statements, at the beginning of the session, the user is associated with BASH because several bash scripts must be sourced at the login (i.e., /etc/profile.d/ scripts). When the user opens a terminal, .bashrc is sourced for setting configuration and variables and at the end it executes FISH.

The following lines have been saved in ~/.config/fish/functions/fish_prompt.fish file in order to edit the shell prompt in the following way (source https://fishshell.com/docs/current/tutorial.html#prompt):

function fish_prompt
    set_color 123e7c
    echo -n "┌──[HQ🚀"
    set_color ff00d7
    echo -n "$(ip -4 addr | grep -v '127.0.0.1' | grep -v 'secondary' | grep -oP '(?<=inet\s)\d+(\.\d+){3}')"
    echo -n "⚔️ $USER"
    set_color 123e7c
    echo -n "]"
    set_color 123e7c
    echo -n "└──╼[👾]"
    set_color 00ffff
    echo (pwd) '$' (set_color normal)
    end

After saving it, the shell will wait for something. Just close it.

For different colors, refer to: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit and pass the mouse over the colors for getting the HEX code, for example:

set_color ff8700 -> Orange
set_color 00ff00 -> Green
set_color 00ffff -> Cyan
set_color ff00d7 -> Purple
set_color 123e7c -> Dark Blue

Furthermore, for keeping FISH as shell even if in the terminal we open new tabs and preventing that it switches to BASH, add the following code at the end of .bashrc and delete each alias ps in your .bashrc or .bash_aliases file for avoding conflicting errors:

if [[ $(ps --no-header --pid=$PPID --format=comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]]
then
    exec fish
fi

Source: https://wiki.archlinux.org/title/fish#Modify_.bashrc_to_drop_into_fish

ZSH

.zshrc has been edited by changing PROMPT variable as follows:

PROMPT="%F{46}┌──[HQ🚀%F{201}$(ip -4 addr | grep -v '127.0.0.1' | grep -v 'secondary' | grep -Po "inet \K[\d.]+" | sed -z "s/\n/|/g;s/|$/\n/")⚔️%n%F{46}]"$'\n'"└──╼[👾]%F{44}%~ $%f "

In general, ZSH is not able to retrieve the new configuration on .zshrc automatically. For example, if the shell prompt changes due to a command, this change is not applied on the current shell session. For solving this, on .zshrc the following line has been added:

precmd() { eval "$PROMPT_COMMAND" }
export PROMPT_COMMAND='source ~/.zshrc'

PowerShell

It is needed to edit the prompt() function. For first,

mkdir /home/cybee/.config/powershell
nano /home/cybee/.config/powershell/Microsoft.PowerShell_profile.ps1

In this file, save the following code:

function prompt() 
{ 
  $ESC=$([char]27)
  "$ESC[32m┌──L3ts D0 1t $(whoami)💣$ESC[00m$($executionContext.SessionState.Path.CurrentLocation)$("`r`n$ESC[31m└──╼Weaponizing PowerShell...🚀>$ESC[00m" * ($nestedPromptLevel + 1)) ";
}

Notes

In case new shells must be implemented, it is important to remember that the following files must be adapted with the logic of the new shell:

  • dconf-shell.ini for PenTOXIC
  • .desktop files related to Payload 2 Dock
  • htb-spawn and htb-update scripts

Remember that the difference about the statements between BASH/ZSH and FISH in dconf.shell.ini entries, for example for Dimitry tool, are:

  • BASH/ZSH: kitty bash -c "if command -v dmitry &> /dev/null;then dmitry;$SHELL;else echo \"dmitry is not installed. I'm retrieving it for you...\";sudo pacman -Syy dmitry;dmitry;$SHELL;fi;"
  • FISH: kitty fish -c "if command -v dmitry &> /dev/null;dmitry;$SHELL;else;echo \"dmitry is not installed. I'm retrieving it for you...\";sudo pacman -Syy dmitry;dmitry;$SHELL;end;"

So, the differences are the usage of then, else without ; and fi instead of end.

The $SHELL variable is set both at global and local level, in order to avoid override of BASH shell in the user local environment. The global and local settings are defined in athena-shell-check of athena-system-installation package by the following piece of code:

package=athena-fish
if pacman -Qq $package > /dev/null ; then
    sed -i 's/\/usr\/bin\/bash;/\/usr\/bin\/fish;/g' /etc/skel/dconf-shell.ini
    sed -i 's/\/usr\/bin\/bash;/\/usr\/bin\/fish;/g' /etc/skel/.local/share/applications/*
    sed -i 's/Bash/Fish/g' /etc/skel/.local/share/applications/*
    sed -i "/export SHELL=/c\export SHELL=\$(which fish)" /etc/skel/.bashrc

cat >> /etc/profile.d/shell.sh << EOF
export SHELL=\$(which fish)
EOF

cat >> /etc/skel/.bashrc << EOF
if [[ \$(ps --no-header --pid=\$PPID --format=comm) != "fish" && -z \${BASH_EXECUTION_STRING} ]]
then
    exec fish
fi
EOF
fi

package=athena-zsh
if pacman -Qq $package > /dev/null ; then
    sed -i 's/\/usr\/bin\/bash;/\/usr\/bin\/zsh;/g' /etc/skel/dconf-shell.ini
    sed -i 's/\/usr\/bin\/bash;/\/usr\/bin\/zsh;/g' /etc/skel/.local/share/applications/*
    sed -i 's/Bash/Zsh/g' /etc/skel/.local/share/applications/*
    sed -i "/export SHELL=/c\export SHELL=\$(which zsh)" /etc/skel/.bashrc

cat >> /etc/profile.d/shell.sh << EOF
export SHELL=\$(which zsh)
EOF

cat >> /etc/skel/.bashrc << EOF
if [[ \$(ps --no-header --pid=\$PPID --format=comm) != "zsh" && -z \${BASH_EXECUTION_STRING} ]]
then
    exec zsh
fi
EOF
fi

Previously $SHELL was set in run-once.sh but it seemed to be set globally and override every local $SHELL variable set by the user. For this reason, it was removed from run-once.sh.

Terminal

In Athena, Kitty is the default terminal. This choice comes due to the following reasons:

  • Offload rendering to the GPU for lower system load
  • Use threaded rendering for absolutely minimal latency
  • Performance tradeoffs can be tuned

It is focused on the decrease the perceived latency and the CPU usage:

Terminal CPU usage (X + terminal)
kitty 6 - 8%
xterm 5 - 7% (but scrolling was extremely janky)
termite 10 -13%
urxvt 12 -14%
gnome-terminal 15 -17%
konsole 29 -31%

Source: https://sw.kovidgoyal.net/kitty/performance/

Along with Kitty, Tmux has also been implemented as terminal multiplexer.