Bash thinks input is incorrect when it is? - linux

I have this script, but on line 51, when I answer "y", bash skips that and tells me to "answer y or n" (skips to line 58):
debianDeps() {
apt-get install git cmake build-essential liblua5.2-dev \
libgmp3-dev libmysqlclient-dev libboost-system-dev
}
fedoraDeps() {
yum install git cmake gcc-c++ boost-devel \
gmp-devel community-mysql-devel lua-devel
}
bsdDeps() {
cd /usr/ports/shells/bash && make install clean BATCH=yes
cd /usr/ports/devel/git && make install clean BATCH=yes
cd /usr/ports/devel/cmake && make install clean BATCH=yes
cd /usr/ports/lang/gcc47 && make install clean BATCH=yes
cd /usr/ports/lang/luajit && make install clean BATCH=yes
cd /usr/ports/devel/boost-libs && make install clean BATCH=yes
cd /usr/ports/math/gmp && make install clean BATCH=yes
cd /usr/ports/databases/mysql-connector-c && make install clean BATCH=yes
}
libInstall() {
echo "Libraries and Build Tools... Installed"
}
bsdBuild() {
echo "Building on FreeBSD"
mkdir build && cd build
CXX=g++47 cmake ..
echo "Build on $cpuCores threads with $coreBuild processes? (experimental but loads faster) y or n "
read $ans1_4
if [[ $ans1_4 = "y" ]]; then
echo -e $greenText"Building on $cpuCores threads with $coreBuild ."$none
make -j $coreBuild
elif [[ $ans1_4 = "n" ]]; then
echo -e $blueText"Building on a single thread."$none
make
else
echo "answer y or n"
echo -e $redText"Answer y or n"$none
fi
}
genBuild() {
echo "Building..."
mkdir build && cd build
cmake ..
echo "Build on $cpuCores threads with $coreBuild processes? (experimental but loads faster) y or n "
read $ans1_4
if [[ $ans1_4 = "y" ]]; then
echo -e $greenText"Building on $cpuCores threads with $coreBuild ."$none
make -j $coreBuild
elif [[ $ans1_4 = "n" ]]; then
echo -e $blueText"Building on a single thread."$none
make
else
echo -e $redText"Answer y or n"$none
fi
}
clean() {
mkdir objs/
mv *.o objs/
echo "There might be a few leftover files."
}
###
### Script starts here
###
#check if root
if [[ $EUID -ne 0 ]]; then
echo "You must be root to use this script, press enter to exit."
read end
exit 1
fi
#OS dependencies and other stuff
echo "Chose your Operating System. {Supported OS: Debian, Ubuntu, Fedora, CentOS, FreeBSD} "
read ans1
if [[ $ans1 = "Fedora" ]] || [[ $nas1 = "CentOS" ]]; then
echo -n "Should the script install dependencies? y or n"
read ans1_1
if [[ $ans1_1 = "y" ]]; then
fedoraDeps
elif [[ $ans1_1 = "n" ]]; then
break
else
echo "Answer 'y' or 'n' "
fi
elif [[ $ans1 = "Debian" ]] || [[ $ans1 = "Ubuntu" ]]; then
echo -n "Should the script install dependencies? y or n"
read ans1_1
if [[ $ans1_1 = "y" ]]; then
debianDeps
elif [[ $ans1_1 = "n" ]]; then
break
else
echo "Answer 'y' or 'n' "
fi
elif [[ $ans1 = "FreeBSD" ]]; then
echo -n "Should the script install dependencies? y or n"
read ans1_1
if [[ $ans1_1 = "y" ]]; then
bsdDeps
elif [[ $ans1_1 = "n" ]]; then
break
else
echo "Answer 'y' or 'n' "
fi
else
echo "Pick a valid OS"
fi
#Compiling here
echo -n "Are we on FreeBSD? y or n"
read ans1_2
if [[ $ans1_2 = "y" ]]; then
bsdbuild
elif [[ $ans1_2 = "n" ]]; then
genBuild
else
echo "Answer y or n"
fi
echo "Should the folder be cleaned? y or n"
read ans1_3
if [[ $ans1_3 = "y" ]]; then
clean
elif [[ $ans1_3 = "n" ]]; then
echo "Exiting..."
exit 1
else
echo "Answer y or n"
fi

read $ans1_4 should be read ans1_4 I made a little mistake there.

Related

Exit code 137 with nixpkgs, despite not changing anything

I'm using Miso, a Haskell backend for JS, and my code was compiling fine yesterday. However, as I try to compile today I get this:
Preprocessing executable 'simple' for miso-1.8.0.0..
Building executable 'simple' for miso-1.8.0.0..
[1 of 1] Compiling Main ( exe/Main.hs, dist/build/simple/simple-tmp/Main.js_o )
Linking dist/build/simple/simple.jsexe (Main)
/nix/store/7crry947d1xvp1f15c6q089l0gcy5hpc-stdenv-linux/setup: line 1315: 3887 Killed ./Setup build
error: builder for '/nix/store/zaw5k6i7lqgxlw7i8aaxvqhknjky3f5x-miso-1.8.0.0.drv' failed with exit code 137
It seems like code 137 is a memory error, but the only thing open was my terminal. I've tried uninstalling and reinstalling nix, reinstalling Haskell, but no dice.
EDIT: Here an excerpt of the script.
for curPhase in $phases; do
if [[ "$curPhase" = buildPhase && -n "${dontBuild:-}" ]]; then continue; fi
if [[ "$curPhase" = checkPhase && -z "${doCheck:-}" ]]; then continue; fi
if [[ "$curPhase" = installPhase && -n "${dontInstall:-}" ]]; then continue; fi
if [[ "$curPhase" = fixupPhase && -n "${dontFixup:-}" ]]; then continue; fi
if [[ "$curPhase" = installCheckPhase && -z "${doInstallCheck:-}" ]]; then continue; fi
if [[ "$curPhase" = distPhase && -z "${doDist:-}" ]]; then continue; fi
if [[ -n $NIX_LOG_FD ]]; then
echo "#nix { \"action\": \"setPhase\", \"phase\": \"$curPhase\" }" >&$NIX_LOG_FD
fi
showPhaseHeader "$curPhase"
dumpVars
# Evaluate the variable named $curPhase if it exists, otherwise the
# function named $curPhase.
local oldOpts="$(shopt -po nounset)"
set +u
eval "${!curPhase:-$curPhase}"
eval "$oldOpts"
if [ "$curPhase" = unpackPhase ]; then
cd "${sourceRoot:-.}"
fi
done
}
Line 1315 is eval "$oldOpts".
I fixed it by changing the amount of memory the Ubuntu virtual machine used by editing .wslconfig. Even though it was enough before, 8 GB couldn't cut it, so doubling it to 16 worked.

What does "-?" mean in bash script

I have this script I am looking at, learning scripting but I cannot figure out what this line means:
if [[ $1 = "-?" ]]
I understand the $1 is first argument, but the after the equals I cannot figure it out the -?.h
if [[ $1 = "-?" ]]
then
echo "Use is: 235.sh <username>"
exit 1
I think it would be checking to see if the first argument is a string equal to -?
You can check this by running:
# [[ "a" = "-?" ]] && echo true
# [[ "-a" = "-?" ]] && echo true
# [[ "a-?" = "-?" ]] && echo true
# [[ "-?" = "-?" ]] && echo true
true
I would guess that is comparing something to the string "-?".

Looping a bash script

this is my first time dabbling in bash scripting and first time using this site. I'm working on script that's meant to provide the user with a list of software packages to install and then output their choices into a 2nd script file that can be run later to actually install their choices.
So far my script is semi working, but I need help figuring out how to;
A) Loop the script so once they've chosen a package it restarts and allows them to select another instead of ending the script
B) When they select "No" or "nN" to the confirmation it takes them back to choice list instead of wigging out and if they input anything other than yes/no it prompts for valid input
Here is my current script, I understand it's probably formatted horribly and most likely inefficient but it's my first time and only for a small school project I'm working on. Any help would be appreciated, thanks!
#!/bin/bash
#bash script to present list of packages for customer install output to txt
if [[ ! -e /home/aarone/pkglist.txt ]]; then
echo "Making package list script"
echo "#!/bin/bash" > /home/aarone/pkglist
chmod -R 777 /home/aarone/pkglist
fi
# Declare variable choice and assign value 4
choice=4
# print to stdout
echo "1. Antivirus GUI"
echo "2. Firewall GUI"
echo "3. MariaDB"
echo -n "Please choose a A package [1,2 or 3]? "
# Loop while the variable choice is equal 4
# bash while loop
while [ $choice -eq 4 ]; do
#read user input
read choice
# bash nested if/else
if [ $choice -eq 1 ]
then
echo "You have chosen word: Antivirus GUI"
apt show clamtk 2>/dev/null | egrep '^Description|^Download'
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get clamtk" >> pkglist
else
echo "Input not understood"
continue
fi
else
if [ $choice -eq 2 ] ; then
echo "You have chosen package: Firewall GUI"
apt show gufw 2>/dev/null | egrep '^Description|^Download'
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get gufw" >> pkglist
else
read choice
fi
else
if [ $choice -eq 3 ] ; then
echo "You have chosen package: Office"
apt show libreoffice 2>/dev/null | egrep '^Description|^Download'
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get libreoffice" >> pkglist
fi
else
echo "Please make a choice between 1-3 !"
echo "1. Antivirus GUI"
echo "2. Firewall GUI"
echo "3. Office application"
echo -n "Please choose a word [1,2 or 3]? "
choice=4
fi
fi
fi
done
Thank you #janos that's pretty much exactly what I wanted! :) The only other thing I'd like to change is the dir the script is created in (to something more default) so I can use it on any system.
I also made a small adjustment to each choice so the "No" prompt now works as well.
1)
echo "You have chosen package: Antivirus GUI"
apt show clamtk 2>/dev/null | egrep '^Description|^Download'
while true; do
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get install -y clamtk" >> "$pkglist"
break
elif [[ "$response" =~ ^([nN][oO]|[nN])+$ ]]
then
echo "Cancelled"
break
else
echo "Input not understood"
fi
done
;;
The case statement can help a lot to simplify the implementation of the menu.
To repeat steps, you can use an infinite loop:
while true; do
# ...
done
Applying the above suggestions, and then some,
the script can be corrected and improved:
#!/bin/bash
pkglist=/home/aarone/pkglist.txt
if [[ ! -e "$pkglist" ]]; then
echo "Making package list script"
echo "#!/bin/bash" > "$pkglist"
chmod -R 777 "$pkglist"
else
echo Package list script already exists. Exiting.
exit 1
fi
while true; do
echo "1. Antivirus GUI"
echo "2. Firewall GUI"
echo "3. MariaDB"
echo "x. Exit"
printf "Please choose a A package [1, 2 or 3]? "
read choice
case "$choice" in
1)
echo "You have chosen word: Antivirus GUI"
apt show clamtk 2>/dev/null | egrep '^Description|^Download'
while true; do
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get clamtk" >> "$pkglist"
break
else
echo "Input not understood"
fi
done
;;
2)
echo "You have chosen package: Firewall GUI"
apt show gufw 2>/dev/null | egrep '^Description|^Download'
while true; do
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get gufw" >> "$pkglist"
break
else
echo "Input not understood"
fi
done
;;
3)
echo "You have chosen package: Office"
apt show libreoffice 2>/dev/null | egrep '^Description|^Download'
while true; do
read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "apt-get libreoffice" >> "$pkglist"
break
else
echo "Input not understood"
fi
done
;;
*)
break
esac
done

How to check if a string contains brackets ")("?

I'm trying to check if an input string contains parentheses, which are: ()[]{}.
I wrote the following code:
#!/bin/bash
str="$1"
if [ -z "$str" ]; then
echo "Usage: $(basename $0) string"
exit 1
fi
if [[ "$str" == *['\{''}''\[''\]''('')']* ]];
then
echo "True"
else
echo "False"
fi
If the string contains any of these: []{} then the output is correct but if the string contains () then I get an error:
-bash: syntax error near unexpected token `('
These are the things I've tried so far:
*['\(''\)']*
*['()']*
*[()]*
Any idea how it should be written?
Edit #1:
[root#centolel ~]# date
Tue Nov 3 18:39:37 IST 2015
[root#centolel ~]# bash -x asaf.sh {
+ str='{'
+ '[' -z '{' ']'
+ [[ { == *[{}\[\]\(\)]* ]]
+ echo True
True
[root#centolel ~]# bash -x asaf.sh (
-bash: syntax error near unexpected token `('
[root#centolel ~]#
You can use this glob pattern with () and [] escaped inside [...]:
[[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
Testing:
str='abc[def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc}def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc[def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc(def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc)def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc{}def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abc}def' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
yes
str='abcdef' && [[ $str == *[{}\(\)\[\]]* ]] && echo "yes" || echo "no"
no

A universal bash script for installing with apt-get and yum

I'm trying to write a simple bash wrapper which abstracts yum and apt-get. Basically so we can do something like universal-install curl Here is what I have so far:
# universal-install
package=$1
apt=`command -v apt-get`
yum=`command -v yum`
if [ -n "$apt" ]; then
apt-get update
apt-get -y install $package
elif [ -n "$yum" ]; then
yum -y install $package
else
echo "Err: no path to apt-get or yum" >&2;
exit 1;
fi
Are there any errors or improvements/optimizations that can be made?
Take a look at how pacapt detects the OS:
# Detect package type from /etc/issue
_found_arch() {
local _ostype="$1"
shift
grep -qis "$*" /etc/issue && _OSTYPE="$_ostype"
}
# Detect package type
_OSTYPE_detect() {
_found_arch PACMAN "Arch Linux" && return
_found_arch DPKG "Debian GNU/Linux" && return
_found_arch DPKG "Ubuntu" && return
_found_arch YUM "CentOS" && return
_found_arch YUM "Red Hat" && return
_found_arch YUM "Fedora" && return
_found_arch ZYPPER "SUSE" && return
[[ -z "$_OSTYPE" ]] || return
# See also https://github.com/icy/pacapt/pull/22
# Please not that $OSTYPE (which is `linux-gnu` on Linux system)
# is not our $_OSTYPE. The choice is not very good because
# a typo can just break the logic of the program.
if [[ "$OSTYPE" != "darwin"* ]]; then
_error "Can't detect OS type from /etc/issue. Running fallback method."
fi
[[ -x "/usr/bin/pacman" ]] && _OSTYPE="PACMAN" && return
[[ -x "/usr/bin/apt-get" ]] && _OSTYPE="DPKG" && return
[[ -x "/usr/bin/yum" ]] && _OSTYPE="YUM" && return
[[ -x "/opt/local/bin/port" ]] && _OSTYPE="MACPORTS" && return
command -v brew >/dev/null && _OSTYPE="HOMEBREW" && return
[[ -x "/usr/bin/emerge" ]] && _OSTYPE="PORTAGE" && return
[[ -x "/usr/bin/zypper" ]] && _OSTYPE="ZYPPER" && return
if [[ -z "$_OSTYPE" ]]; then
_error "No supported package manager installed on system"
_error "(supported: apt, homebrew, pacman, portage, yum)"
exit 1
fi
}
As you can see it first checks /etc/issue, then failing that the script looks for the associated executable file for each package manager.
But heck, why not just use pacapt, instead of rolling your own?
If you're going to do this, why require the user to tell the script which tool to use?
#!/bin/bash
# Find our package manager
if VERB="$( which apt-get )" 2> /dev/null; then
echo "Debian-based"
elif VERB="$( which yum )" 2> /dev/null; then
echo "Modern Red Hat-based"
elif VERB="$( which portage )" 2> /dev/null; then
echo "Gentoo-based"
elif VERB="$( which pacman )" 2> /dev/null; then
echo "Arch-based"
else
echo "I have no idea what I'm doing." >&2
exit 1
fi
if [[ 1 -ne $# ]]; then
echo "Syntax: $0 PACKAGE"
exit 1
fi
$VERB "$1"
exit $?
Slightly better would to to look at /etc/issue to see what your distribution is and behave accordingly.
I was looking for a one-liner to install a package and couldn't find any so this was my final version:
if [ "" == "`which unzip`" ]; then echo "Unzip Not Found"; if [ -n "`which apt-get`" ]; then apt-get -y install unzip ; elif [ -n "`which yum`" ]; then yum -y install unzip ; fi ; fi
It's specific for the unzip package, but can be altered to any other package that is available on apt-get/yum.
Hope this will help someone :)
#!/bin/bash
# file: src/bash/aspark-starter/install-prerequisites-for-aspark-starter.sh
# caveat package names are for Ubuntu !!!
set -eu -o pipefail # fail on error , debug all lines
# run as root
[ "${USER:-}" = "root" ] || exec sudo "$0" "$#"
echo "=== $BASH_SOURCE on $(hostname -f) at $(date)" >&2
echo installing the must-have pre-requisites
while read -r p ; do
if [ "" == "`which $p`" ];
then echo "$p Not Found";
if [ -n "`which apt-get`" ];
then apt-get install -y $p ;
elif [ -n "`which yum`" ];
then yum -y install $p ;
fi ;
fi
done < <(cat << "EOF"
perl
zip unzip
exuberant-ctags
mutt
libxml-atom-perl
postgresql-9.6
libdbd-pgsql
curl
wget
libwww-curl-perl
EOF
)
echo installing the nice-to-have pre-requisites
echo you have 5 seconds to proceed ...
echo or
echo hit Ctrl+C to quit
echo -e "\n"
sleep 6
echo installing the nice to-have pre-requisites
while read -r p ; do
if [ "" == "`which $p`" ];
then echo "$p Not Found";
if [ -n "`which apt-get`" ];
then apt-get install -y $p ;
elif [ -n "`which yum`" ];
then yum -y install $p ;
fi ;
fi
done < <(cat << "EOF"
tig
EOF
)

Resources