I have a test script the needs to read the variable 'LAB' and e-mail the correct company.
I've looked but can't find anything that has worked yet.
Any thoughts?
#!
#
LAB=3
#
if [ "$LAB" = "$1" ];then
echo "Got Zumbrota" && ./mailZ
fi
#
if [ "$LAB" = "$2" ];then
echo "Got Barron" && ./mailB
fi
#
if [ "$LAB" = "$3" ];then
echo "Got Stearns" && ./mailS
fi
If this a bash script, start your file with
#!/bin/bash
and use -eq for integer comparison and since LAB is an integer in your script
if [ $LAB -eq $1 ]
These cascading if statements can be condensed into a case statement:
case "$LAB" in
1) echo "Got Zumbrota" && ./mailZ
;;
2) echo "Got Barron" && ./mailB
;;
3) echo "Got Stearns" && ./mailS
;;
*) echo "don't know what to do with $LAB"
;;
esac
Related
#!/bin/bash
var="true"
i=1
while $var
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
exit
fi
done
Script is Working Fine. I Enter true the loop will iterate for false the script stops.
I want the script will continue asking "Enter Value" if any other value instead of true or false will be entered.
This would do the same with a more academic syntax:
i=0
while :; do
printf 'Enter value (true/false): '
read -r var
case $var in
true)
i=$((i + 1))
printf 'Iteration : %d\n' $i
;;
false)
printf 'Exiting the process\n'
break
;;
*)
printf 'Invalid Choice.\nAvaialable Choices are true or false\n'
;;
esac
done
You might find this to be a cleaner solution:
i=0
while true; do
read -p "enter value: " myinput
if [[ $myinput = true ]]; then
echo "iteration $i"
i=$((i+1))
elif [[ $myinput = false ]]; then
echo "exiting"
exit
else
echo "invalid input"
fi;
done;
The issue I see with your current code is that it is unclear which command's exit status $? refers to. Does it refer to the echo in the previous elif block? Or the last condition check? Or something else entirely?
I'm new in bash. I tried that:
#!/bin/bash
i=1
while [[ $var != "false" ]]
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
fi
done
I changed while $var with while [[ $var ]] because while works like if. It runs the given command. In there it is $var's value.
And I moved exit to first elif expression's end. So if user type false program will exit.
Restricting user from trying multiple invalid attempt in shell scripting. I wrote the below script but somehow it's not getting me desire output. I have shared the script and script output both. Kindly help. Here I wanted script to terminate if user tried more than 3 times.
While true
do
echo -n "Enter yes or no"
read opt
case $opt in
yes) break ;;
no) break ;;
*) echo "Invalid input"
while [[ $err -le 3 ]]
do
If [[ $err -le 3 ]]
then
echo "err: $err"
((err++))
break
else
echo "Max limit crossed"
exit 1
fi
done
;;
esac
done
This was a nice question and I had a lot of fun solving it. I have to mention that I'm new to shell programming.
n=0
until [ $n -ge 3 ]
do
read line
if [ "$line" = "XYZ" ]; then
echo "Accepted"
break
else
n=$[$n+1]
echo " trying " $n "times "
fi;
done
This article helped me a lot to solve it.
Try:
#!/bin/bash
ANSWER=
max=3
while true; do
echo "Enter yes or no:"
read -r ANSWER
[[ $ANSWER == "yes" || $ANSWER == "no" ]] && break
echo Invalid Input
ANSWER=
((--max))
[[ $max -le 0 ]] && { echo "Max limit crossed"; exit 1; }
done
Problem:
I need to make this bash script to choose based on the user inputs. Example how can i add choices? such that user just select from 1 to 3 and that is set in variable CLUSTER_NAME.
choices are test.com, try.com and me.com
Script
#!/bin/bash
sops_ops() {
sops --version
if [ "$?" -eq "0" ]; then
echo "proceed sops ops"
else
echo "check sops binary"
fi
read -p 'Enter cluster_NAME: = ' CLUSTER_NAME
test_environment="test.com"
test1_environment="test1.com"
test2_environment="test2.com"
case "${$CLUSTER_NAME}" in
prod.$test_environment) ;;
dev.$test1_environment) ;;
stage.$test2_environment) ;;
test.$test_environment) ;;
*) echo "Invalid option: ${CLUSTER_NAME}" 1>&2 && exit 1 ;;
if [ $CLUSTER_NAME = test.$test_env ];then
printf "got cluster $CLUSTER_NAME"
elif [ $CLUSTER_NAME = "test.test.com" ];then
printf "got dev cluster $CLUSTER_NAME"
echo "not found cluster"
else
echo "Environment not available"
fi
}
sops_ops
Question:
How do I do that?
Any help is appreciated!
I'm writing a script that makes a while loop for me, that I doesn't have to write a one line while loop again and again.
Short explanation:
The command "loop" will execute the command parameter -n times and with -p seconds pause. You can use -e to echo the command and not execute it. -v to show all parameters. Additionally its possible to use the iterator of the while loop.
Playing around with it, I've found a bug.
loop --verbose --times 5 'touch testfile$i'
#loop the touch command 5 times and generate the testfiles 0 to 4
same as:
loop -v -n 5 'touch testfile$i'
It generate "testfile0" to "testfile4" but also a file named "0"
Do somebody know why the file "0" will be generated?
And what do you think about a command like that? Would you like to use it?
Best
Steven
#!/bin/bash
# easy to use loop command
#
# Autor: Steven Wagner
# Date: 22 June 2018
# Version: 0.1
TIMES=0
FREQUENCY=0
PAUSE="0"
VERBOSE=false
ECHOONLY=false
SILENCE=false
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-n|--times)
temp="$2"
if [[ $temp =~ ^[[:digit:]]+$ ]];
then
TIMES=$temp
else
echo "ERROR: value is not a digit"
exit
fi
shift # past argument
shift # past value
;;
-p|--pause)
#PAUSE="$2"
temp="$2"
PAUSE=$temp
#if [[ $temp =~ ^[[:digit:]]+$ ]];
#then
# PAUSE=$temp
#else
# echo "ERROR: value is not a digit"
# exit
#fi
shift # past argument
shift # past value
;;
-v|--verbose)
VERBOSE=true
shift # past argument
;;
-e|--echo-only)
ECHOONLY=true
shift # past argument
;;
-s|--silence)
SILENCE=true
shift # past argument
;;
--*)
echo "Error \"$key\" not known"
shift #past argument
;;
-*)
i=0
while [[ $i -lt ${#key}-1 ]]
do
char=${key:$[$i+1]:1}
case $char in
v)
VERBOSE=true
;;
e)
ECHOONLY=true
;;
s)
SILENCE=true
;;
esac
(( i++ ))
done
shift # past argument
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[#]}" # restore positional parameters
#Pause make sleep command
pause=""
if [ $PAUSE > 0 ]
then
pause="sleep $PAUSE"
fi
#times make while control-command
times=""
if [ $TIMES != 0 ]
then
times="[ \$i -lt \$TIMES ]"
else
times="true" #infinity loop
fi
#Echo Only
command=$#
if $ECHOONLY
then
command="echo $#"
fi
#Silence
silence=""
if $SILENCE && ! $ECHOONLY
then
silence="&>/dev/null"
fi
if $VERBOSE
then
echo "pause = $PAUSE"
if [ $TIMES != 0 ]
then
echo "times = $TIMES"
else
echo "times = infinity"
fi
if $ECHOONLY; then echo "echo only = yes"; fi
if $SILENCE; then echo "silence = yes"; fi
echo "command = '$#' $silence"
echo
fi
#start the loop
timestamp=$(date +%s%N)
eval "
i=0
while $times
do
eval '$command' $silence
$pause
(( i++ ))
done
"
if $VERBOSE
then
echo
echo "duration: $[($(date +%s%N)-$timestamp)/1000000]ms"
fi
For some reason, I can't figure out how to test truth in bash:
#!/bin/bash
FORCE_DELETE=""
BE_VERBOSE=""
OPTIND=1
while getopts ":fv" FLAG "$#" ; do
if [[ "$FLAG" == "f" ]] ; then
FORCE_DELETE="true"
fi
if [[ "$VALUE" == "v" ]] ; then
BE_VERBOSE="true"
fi
if [[ "$FLAG" == "?" ]] ; then
echo "Usage: $0 [-fv] file ..."
exit 1
fi
done
shift `expr $OPTIND - 1`
if [[ "$FORCE_DELETE" == "true" && "BE_VERBOSE" == "true" ]] ; then
echo "FORCE_DELETE AND BE_VERBOSE $#"
elif [[ "$FORCE_DELETE" == "true" ]] ; then
echo "FORCE_DELETE $#"
elif [[ "$BE_VERBOSE" == "true" ]] ; then
echo "BE_VERBOSE $#"
else
echo "$#"
fi
exit 0
Transcript:
$ test a b
a b
$ test -f a b
FORCE_DELETE a b
$ test -v a b
a b
$ test -fv a b
FORCE_DELETE a b
Why does my bash script respond to the -f flag but not the -v flag?
Most likely a typo :
[[ "$VALUE" == "v" ]],
this should be
[[ "$FLAG" == "v" ]]
You specifically ask about testing true/false. These are built in to the language rather than using strings, and you don't need the [[ test. Here is how I would write this:
#!/bin/bash
force_delete=false # Don't use UPPERCASE
be_verbose=false # they could collide with reserved variables
# OPTIND does not need to be initialised
while getopts :fv flag
do
# appears one of your if statements is incorrect
# a case is often used with getopts
case $flag in
f) force_delete=true
;;
v) be_verbose=true
;;
\?) echo "Usage: $0 [-fv] file ..."
exit 1
;;
esac
done
shift $((OPTIND-1)) # don't create a child process for simple arithmetic
if $force_delete && $be_verbose
then
echo "force_delete AND be_verbose $#"
elif $force_delete
then
echo "force_delete $#"
elif $be_verbose
then
echo "be_verbose $#"
else
echo "$#"
fi
# Bash exits 0 by default