I want to install DevStack(Yoga) on RHEL 9.1 (https://opendev.org/openstack/DevStack).
I attempted to deploy using the official manual (https://www.redhat.com/sysadmin/get-started-openstack-devstack).
However, the deployment got stuck due to the unavailability of the "redhat-lsb-core" package while running the '$./stack.sh' command.
Any help would be appreciated.
Looking at the code, it appears that the redhat-lsb-core package is only required by the GetOSVersion function, and there are already explicit provisions in place for both CentOS and Rocky 9, both of which, like RHEL9, do not include the redhat-lsb-core package:
function GetOSVersion {
# CentOS Stream 9 does not provide lsb_release
source /etc/os-release
if [[ "${ID}${VERSION}" == "centos9" ]]; then
os_RELEASE=${VERSION_ID}
os_CODENAME="n/a"
os_VENDOR=$(echo $NAME | tr -d '[:space:]')
elif [[ "${ID}${VERSION}" =~ "rocky9" ]]; then
os_VENDOR="Rocky"
os_RELEASE=${VERSION_ID}
else
_ensure_lsb_release
os_RELEASE=$(lsb_release -r -s)
os_CODENAME=$(lsb_release -c -s)
os_VENDOR=$(lsb_release -i -s)
fi
...
It looks like you could probably get things working in RHEL9 by treating it like centos9, perhaps like this:
function GetOSVersion {
# CentOS Stream 9 does not provide lsb_release
source /etc/os-release
if [[ "${ID}${VERSION}" == "centos9" ]]; then
os_RELEASE=${VERSION_ID}
os_CODENAME="n/a"
os_VENDOR=$(echo $NAME | tr -d '[:space:]')
elif [[ "${ID}${VERSION}" == rhel9.* ]]; then
os_RELEASE=${VERSION_ID}
os_CODENAME="n/a"
os_VENDOR=$(echo $NAME | tr -d '[:space:]')
elif [[ "${ID}${VERSION}" =~ "rocky9" ]]; then
os_VENDOR="Rocky"
os_RELEASE=${VERSION_ID}
else
...
On a RHEL 9.1 system, this will set:
os_RELEASE=9.1
os_CODENAME=n/a
os_VENDOR=RedHatEnterpriseLinux
That will hopefully be enough to move things forward.
Related
I want to detect OS and introduce settings.
However, I get an unintelligible error.
There are few error messages and I don't understand what they mean.
function load_config(){
os=$(uname -a)
echo $os
if [[`echo $os | grep -o kali | tail -1` == "kali"]]; then
for FILE in ~/.config/zsh_config/kali/*.zsh; do
source $FILE
done
elif [[`echo $os | grep -o MANJARO | tail -1` == "MANJARO"]]; then
for FILE in ~/.config/zsh_config/manjaro/*.zsh; do
source $FILE
done
elif [[`echo $os | grep -o MacBook | tail -1` == "MacBook"]]; then
for FILE in ~/.config/zsh_config/osx/*.zsh; do
source $FILE
done
else
echo 'Unknown OS!'
fi
}
$load_config
Linux kali 5.18.0-kali5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 5.18.5-1kali5 (2022-07-04) x86_64 GNU/Linux
load_config:3: = not found
I have looked at various articles and they all had the same implementation. Please tell me why the error occurs. Please!
The shell is white-space sensititve. This means you must separate some tokens by white-space. In particular,
if [[`echo $os | grep -o kali | tail -1` == "kali"]]; then
should be
if [[ `echo $os | grep -o kali | tail -1` == "kali" ]]; then
Note white-space around [[ and ]].
Why do you parse uname -a when uname -s would yield the OS name right away? I usually use
case $(uname -s) in
(*FreeBSD*) ...;;
(*Gentoo*) ...;;
(*Kali*) ...;;
(*Solaris*) ...;;
(*) ...;;
esac
This saves a ton of expensive processes.
I am trying to customize the Bira zsh-theme so that a clean branch is green and a dirty branch is red and has an asterisk at the end like so...
I have gotten it so that the color changes based on the branch's state, but cannot figure out how to get the asterisk to show up at the end. Below is what I have so far. I'm very new to customizing zsh-theme files, so any help would be much appreciated!
# ZSH Theme - Modified from bira.zsh-theme
local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
if [[ $UID -eq 0 ]]; then
local user_host='%{$terminfo[bold]$fg[red]%}%n#%m%{$reset_color%}'
local user_symbol='#'
else
local user_host='%{$terminfo[bold]$fg[cyan]%}%n#%m%{$reset_color%}'
local user_symbol='$'
fi
local current_dir='%{$terminfo[bold]$fg[yellow]%}%~%{$reset_color%}'
local git_branch='$(git_prompt_info)%{$reset_color%}'
function git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
echo "$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(current_branch)$ZSH_THEME_GIT_PROMPT_SUFFIX"
}
PROMPT="
╭─${user_host} ${current_dir} ${git_branch}
╰─%B${user_symbol}%b "
RPS1="%B${return_code}%b"
ZSH_THEME_GIT_PROMPT_PREFIX="‹"
ZSH_THEME_GIT_PROMPT_SUFFIX="›$reset_color"
ZSH_THEME_GIT_PROMPT_DIRTY="$fg[red]"
ZSH_THEME_GIT_PROMPT_CLEAN="$fg[green]"
The parse_git_dirty function is defined in lib/git.zsh
By copying that function into your file and modifying it slightly, we can achieve what you want:
function git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
# Checks if working tree is dirty
local STATUS=''
local FLAGS
FLAGS=('--porcelain')
if [[ "$(command git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
if [[ $POST_1_7_2_GIT -gt 0 ]]; then
FLAGS+='--ignore-submodules=dirty'
fi
if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then
FLAGS+='--untracked-files=no'
fi
STATUS=$(command git status ${FLAGS} 2> /dev/null | tail -n1)
fi
if [[ -n $STATUS ]]; then
GIT_PROMPT_COLOR="$ZSH_THEME_GIT_PROMPT_DIRTY"
GIT_DIRTY_STAR="*"
else
GIT_PROMPT_COLOR="$ZSH_THEME_GIT_PROMPT_CLEAN"
unset GIT_DIRTY_STAR
fi
echo "$GIT_PROMPT_COLOR$ZSH_THEME_GIT_PROMPT_PREFIX$(current_branch)$GIT_DIRTY_STAR$ZSH_THEME_GIT_PROMPT_SUFFIX"
}
The only difference from the library function is assigning GIT_PROMPT_COLOR and GIT_DIRTY_STAR instead of echoing, and then using these in the final echo.
I'm trying to modify an existing zsh prompt to work with zsh 5.0 and 4.3 because those the versions the systems that I use. How would I make a zsh-script be aware of the current working directory instead of the directory that the file is in?
For context,
This is a function in the script that checks if we're currently in a git directory and adds to the prompt if we are:
# Git status.
# Collect indicators, git branch and pring string.
spaceship_git_status() {
[[ $SPACESHIP_GIT_SHOW == false ]] && return
# Check if the current directory is in a Git repository.
command git rev-parse --is-inside-work-tree &>/dev/null || return
# Check if the current directory is in .git before running git checks.
if [[ "$(git rev-parse --is-inside-git-dir 2> /dev/null)" == 'false' ]]; then
# Ensure the index is up to date.
git update-index --really-refresh -q &>/dev/null
# String of indicators
local indicators=''
indicators+="$(spaceship_git_uncomitted)"
indicators+="$(spaceship_git_unstaged)"
indicators+="$(spaceship_git_untracked)"
indicators+="$(spaceship_git_stashed)"
indicators+="$(spaceship_git_unpushed_unpulled)"
[ -n "${indicators}" ] && indicators=" [${indicators}]";
echo -n " %Bon%b "
echo -n "%{$fg_bold[magenta]%}"
echo -n "$(git_current_branch)"
echo -n "%{$reset_color%}"
echo -n "%{$fg_bold[red]%}"
echo -n "$indicators"
echo -n "%{$reset_color%}"
fi
}
However, based on my debugging, it appears that the function always believes that it is in the directory from which the script was sourced. In other words, as I change directory, the script continues to reference the directory where the script is located.
The spaceship_git_status function is called here:
# Build prompt line
spaceship_build_prompt() {
spaceship_host
spaceship_current_dir
spaceship_git_status
spaceship_nvm_status
spaceship_ruby_version
spaceship_venv_status
}
And this is the PROMPT environment variable is:
# Compose PROMPT
PROMPT=''
[[ $SPACESHIP_PROMPT_ADD_NEWLINE == true ]] && PROMPT="$PROMPT$NEWLINE"
PROMPT="$PROMPT $(spaceship_build_prompt) "
[[ $SPACESHIP_PROMPT_SEPARATE_LINE == true ]] && PROMPT="$PROMPT$NEWLINE"
PROMPT="$PROMPT $(spaceship_return_status) "
I think this is an issue with zsh versions < 5.2 because the prompt renders fine on my other computer with 5.2.
Full code: https://github.com/denysdovhan/spaceship-zsh-theme/blob/master/spaceship.zsh
I'm trying to create a Capistrano mutilstage completion for ZSH:
$ cap |
production staging
$ cap production |
deploy -- Deploy a new release
deploy:bundle -- Bundle
...
Completion code:
#compdef cap
#autoload
# /Users/pablo/.oh-my-zsh/custom/plugins/capistrano_custom/_capistrano_custom
local curcontext="$curcontext" state line ret=1
local -a _configs
_arguments -C \
'1: :->cmds' \
'2:: :->args' && ret=0
_cap_tasks() {
if [[ ! -f .cap_tasks~ ]]; then
echo "\nGenerating .cap_tasks~..." > /dev/stderr
cap -v --tasks | grep '#' | cut -d " " -f 2 > .cap_tasks~
fi
cat .cap_tasks~
}
_cap_stages() {
find config/deploy -name \*.rb | cut -d/ -f3 | sed s:.rb::g
}
case $state in
cmds)
if [[ -d config/deploy ]]; then
compadd `_cap_stages`
else
compadd `_cap_tasks`
fi
ret=0
;;
args)
compadd `_cap_tasks`
ret=0
;;
esac
return ret
The problem:
#compdef cap doesn't work. If I type cap and [TAB] it doesn't execute the completion, but with other words (i.e. shipit) works fine.
Any ideas?
Solution:
cap is really a reserved word and it seems that we can't use it with #compdef cap.
I'm wondering how cap and capistrano completions worked before (maybe an old version of ZSH).
Solution dotfiles code: capistrano_custom
Solution oh-my-zsh/PR: #2471
Both solutions use shipit instead of cap.
$ shipit |
production staging
$ shipit production |
deploy -- Deploy a new release
deploy:bundle -- Bundle
...
Yes, cap is a ZSH builtin. Quoting from zsh docs:
The zsh/cap module is used for manipulating POSIX.1e (POSIX.6)
capability sets. [...]. The builtins in this module are:
cap [ capabilities ] Change the shell’s process capability sets to the
specified capabilities, otherwise display the shell’s current
capabilities.
I am using KornShell (ksh) on Solaris and currently my PS1 env var is:
PS1="${HOSTNAME}:\${PWD} \$ "
And the prompt displays: hostname:/full/path/to/current/directory $
However, I would like it to display: hostname:directory $
In other words, how can I display just the hostname and the name of the current directory, i.e. tmp or ~ or public_html etc etc?
From reading the ksh man page you want
PS1="${HOSTNAME}:\${PWD##*/} \$ "
Tested on default ksh on SunOS 5.8
Okay, a little old and a little late, but this is what I use in Kornshell:
PS1='$(print -n "`logname`#`hostname`:";if [[ "${PWD#$HOME}" != "$PWD" ]] then; print -n "~${PWD#$HOME}"; else; print -n "$PWD";fi;print "\n$ ")'
This makes a prompt that's equivalent to PS1="\u#\h:\w\n$ " in BASH.
For example:
qazwart#mybook:~
$ cd bin
qazwart#mybook:~/bin
$ cd /usr/local/bin
qazwart#mybook:/usr/local/bin
$
I like a two line prompt because I sometimes have very long directory names, and they can take up a lot of the command line. If you want a one line prompt, just leave off the "\n" on the last print statement:
PS1='$(print -n "`logname`#`hostname`:";if [[ "${PWD#$HOME}" != "$PWD" ]] then; print -n "~${PWD#$HOME}"; else; print -n "$PWD";fi;print "$ ")'
That's equivalent to PS1="\u#\h:\w$ " in BASH:
qazwart#mybook:~$ cd bin
qazwart#mybook:~/bin$ cd /usr/local/bin
qazwart#mybook:/usr/local/bin$
It's not quite as easy as setting up a BASH prompt, but you get the idea. Simply write a script for PS1 and Kornshell will execute it.
For Solaris and other Older Versions of Kornshell
I found that the above does not work on Solaris. Instead, you'll have to do it the real hackish way...
In your .profile, make sure that ENV="$HOME/.kshrc"; export ENV
is set. This is probably setup correctly for you.
In your .kshrc file, you'll be doing two things
You'll be defining a function called _cd. This function will change to the directory specified, and then set your PS1 variable based upon your pwd.
You'll be setting up an alias cd to run the _cd function.
This is the relevant part of the .kshrc file:
function _cd {
logname=$(logname) #Or however you can set the login name
machine=$(hostname) #Or however you set your host name
$directory = $1
$pattern = $2 #For "cd foo bar"
#
# First cd to the directory
# We can use "\cd" to evoke the non-alias original version of the cd command
#
if [ "$pattern" ]
then
\cd "$directory" "$pattern"
elif [ "$directory" ]
then
\cd "$directory"
else
\cd
fi
#
# Now that we're in the directory, let's set our prompt
#
$directory=$PWD
shortname=${directory#$HOME} #Possible Subdir of $HOME
if [ "$shortName" = "" ] #This is the HOME directory
then
prompt="~$logname" # Or maybe just "~". Your choice
elif [ "$shortName" = "$directory" ] #Not a subdir of $HOME
then
prompt="$directory"
else
prompt="~$shortName"
fi
PS1="$logname#$hostname:$prompt$ " #You put it together the way you like
}
alias cd="_cd"
This will set your prompt as the equivelent BASH PS1="\u#\h:\w$ ". It isn't pretty, but it works.
ENV=~/.kshrc, and then in your .kshrc:
function _cd {
\cd "$#"
PS1=$(
print -n "$LOGNAME#$HOSTNAME:"
if [[ "${PWD#$HOME}" != "$PWD" ]]; then
print -n "~${PWD#$HOME}"
else
print -n "$PWD"
fi
print "$ "
)
}
alias cd=_cd
cd "$PWD"
Brad
HOST=`hostname`
PS1='$(print -n "[${USER}#${HOST%%.*} ";[[ "$HOME" == "$PWD" ]] && print -n "~" ||([[ "${PWD##*/}" == "" ]] && print -n "/" || print -n "${PWD##*/}");print "]$")'
PS1=`id -un`#`hostname -s`:'$PWD'$
and...
if you work between two shells for most of your effort [ksh and bourne sh]
and desire a directory tracking display on your command line
then PWD can be substituted easily in ksh
and if you use /usr/xpg4/bin/sh for your sh SHELL, it will work there as well
Try this:
PS1="\H:\W"
More information on: How to: Change / Setup bash custom prompt, I know you said ksh, but I am pretty sure it will work.