zsh script detect OS, occr errror - zsh

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.

Related

How to deploy devstack (OpenStack) on RHEL 9.1?

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.

recovering deleted script running in background

I have script which is running in bg(nohup) but it was accidently deleted,but that is continue running now I need to edit the code which is already deleted.
How can I now get that code.I assume somewhere it should be as it is running.
Try this :
#!/bin/bash
if [[ ! $1 || $1 == -h || $1 == --help ]]; then
echo -e "Usage:\n\n\t$0 '[path/]<file name>'"
exit 1
fi
files=(
$(file 2>/dev/null /proc/*/fd/* |
grep "(deleted)'$" |
sed -r 's#(:.*broken\s+symbolic\s+link\s+to\s+.|\(deleted\).$)# #g' |
grep "$1" |
cut -d' ' -f1
)
)
if [[ ${files[#]} ]]; then
for f in ${files[#]}; do
echo "fd $f match... Try to copy this fd to another place quickly!"
done
else
echo >&2 "No matching fd found..."
exit 2
fi
Not tested on non GNU-Linux

is `cap` a reserved word? - zsh completion?

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.

Error while running command from cron (tcsh)

When I'm running this command from shell(tcsh), it executes perfectly-
cal | tail -6 | sed -e 's/^.\{3\}//' -e 's/.\{3\}$//' | tr -s '[:blank:]' '\n' | head -21 | tail -20 | tr -s '\n' ' ' | grep -w `date "+%e"` ; /usr/bin/bash -lc "if [ "$?" == 0 ] ; then echo xyz ; fi"
But when I put the exact same thing in a crontab, I get this error mail from my machine-
Subject: Output from "cron" command
Content-Length: 244
Your "cron" job on uatserver
cal | tail -6 | sed -e 's/^.\{3\}//' -e 's/.\{3\}$//' | tr -s '[:blank:]' '\n' | head -21 | tail -20 | tr -s '\n' ' ' | grep -w `date "+
produced the following output:
Usage: grep -hblcnsviw pattern file . . .
I'm sure that even my crontab commands are executed using tcsh as it is set to be the default.
p.s- My machine:
SunOS uatserver 5.10 Generic_127112-11 i86pc i386 i86pc
Your problem is that the PATH variable is not the same. Solaris has different flavors of grep
examples:
/usr/bin/grep
/usr/xpg4/bin/grep
You crontab ran /usr/bin/grep instead of /usr/xpg4/bin/grep. The two versions of grep have some different options.

Unix script to delete file if it contains single line

Consider I have a file abcde.txt which may contain one or more lines of text. I want a script that will DELETE the file if it contains single line.
Something like, if 'wc -l abscde.txt' = 1 then rm abscde.txt
My system : Solaris
Here's a simple bash script:
#!/bin/bash
LINECOUNT=`wc -l abscde.txt | cut -f1 -d' '`
if [[ $LINECOUNT == 1 ]]; then
rm -f abscde.txt
fi
delifsingleline () {
if [ $(cat $1 | wc -l) = "1" ]
then
echo "Deleting $1"
echo "rm $1"
fi
}
Lightly tested on zsh. Should work on bash as well.
This is (mostly) just a reformat of Ben's answer:
wc -l $PATH | grep '^1 ' > /dev/null && rm -f $PATH

Resources