I'm scripting a small program for my company and I'm using PS3 and select to display the menu, the problem is that instead of printing a menu like this one:
1. SharePoint
2. AWS
3. Connect Direct
4. Proofpoint
5. DELL
6. Sair
The program prints it like this:
1. SharePoint 3. Connect Direct 5. DELL
2. AWS 4. Proofpoint 6. Sair
Here's the code:
function postagem(){
clear
quodZip
PS3="Plataforma que deseja enviar o arquivo [1-5]: "
select i in 'SharePoint' 'AWS' 'Connect Direct' 'Proofpoint' 'DELL' 'Sair'
do
case "$i" in
"SharePoint")
plataforma="Share Point";
break
;;
"AWS")
plataforma="AWS";
break
;;
"Connect Direct")
plataforma="Connect Direct";
break
;;
"Proofpoint")
plataforma="Proofpoint";
break
;;
"DELL")
plataforma="DELL";
break
;;
"Sair")
exit;
;;
*)
echo ''
echo "Opcao invalida, escolha novamente"
;;
esac
done
}
Use the COLUMNS variable before select.
function postagem(){
COLUMNS=0
clear
quodZip
PS3="Plataforma que deseja enviar o arquivo [1-5]: "
select i in 'SharePoint' 'AWS' 'Connect Direct' 'Proofpoint' 'DELL' 'Sair'
do
case "$i" in
"SharePoint")
plataforma="Share Point";
break
;;
"AWS")
plataforma="AWS";
break
;;
"Connect Direct")
plataforma="Connect Direct";
break
;;
"Proofpoint")
plataforma="Proofpoint";
break
;;
"DELL")
plataforma="DELL";
break
;;
"Sair")
exit;
;;
*)
echo ''
echo "Opcao invalida, escolha novamente"
;;
esac
done
}
Related
I am using a nested function to partition and making the filesystem for drives attached to a new Linux box.
I am having a strange issue trying to break out of all loops.
I am keeping track of the nested loop index and using "break n".
When the user replies "n" to the question "Do you have any additional drives to partition?" i expect to break out of all nested loops and continue with the script, but what happens is that the question gets asked again.
Can you help me figure this out?
INIT_STARTED=0
chooseDisks()
{
INIT_STARTED=$((INIT_STARTED+1))
# Choosing which drive to work on
read -p "Please type the name of the disk you want to partition: " DISK
while true; do
read -p "Are you sure you want to continue ? y (partition)/n (choose another drive) /x (continue) " ynx
case $ynx in
[Yy]* )
containsElement "$DISK"
if [ $? == 1 ]; then
initializeDisk $DISK
# remove element from found disk to prevent trying to partition it again.
delete=($DISK)
FOUNDDISKS=( "${FOUNDDISKS[#]/$delete}" )
else
echo "${red}$DISK is not a valid choice, please select a valid disk.${reset}"
chooseDisks
fi
break;;
[Nn]* )
chooseDisks
break $((INIT_STARTED));;
[Xx]* )
return
break;;
* ) echo "Please answer y or n. x to continue the script.";;
esac
done
# Any additional disks to partition?
while true; do
read -p "Do you have any additional drives to partition ? y/n " yn
case $yn in
[Yy]* )
#chooseDisks $FOUNDDISKS
chooseDisks
break $((INIT_STARTED));;
[Nn]* )
return
break $((INIT_STARTED));;
* ) echo "Please answer y or n";;
esac
done
}
I expect this:
break $((INIT_STARTED));;
to end the nth loop and exiting the function.
Don't play with nested logic break, just use some variable like $userStop and instead of while true; do put
userStop = false
while[!${userStop}]
do
#...
# replace break $((INIT_STARTED));; by
# userStop = true
I ended up changing the code to avoid breaking within a loop.
Thanks guys for directing me the right way.
David
i expect to break out of all nested loops and continue with the script
You can run the function in a subshell and use exit.
chooseDisks()
{
if [ "$1" -eq 0 ]; then
echo "The user entered it all!"
exit 0
fi
echo "The user is still entering... $1"
( chooseDisks $(($1 - 1)) )
}
# Imagine the user 5 times enters something
( chooseDisks 5 )
But the best would be to refactor your code to just have a big while true; do loop in the beginning. There is no need to make this function recursive.
I have this function
function doit {
echo " Do you want to continue? {y/n} "
case $opt in
y) ??????
n) exit ;;
esac
echo " 32b or 64b? {32/64} "
case $opt in
32) do32 ;;
64) do64 ;;
esac
}
How do I make this work ? I need to keep moving forward in the same function after the YES is chosen.
This is extremely unclear, but I guess you mean
doit () {
read -p " Do you want to continue? {y/n} " opt
case $opt in
y) ;;
n) return 1 ;;
esac
read -p " 32b or 64b? {32/64} " opt
case $opt in
32) do32 ;;
64) do64 ;;
esac
}
The option to do nothing at all in the y case seems to be the answer to your question. But notice also the use of return rather than exit to leave the function, the absence of a function keyword in the function declaration (this is only a matter of preference really; but I see no advantage of the Bash-only syntax variant), and the use of read to read input (I guess that's what you wanted here?). The return argument 1 signals failure to the caller, so you can say e.g.
doit || echo "$0: doit failed or aborted" >&2
Strictly speaking, the first case only needs an n branch; you'll notice that the code simply falls through if the answer is not either n or y, and this behavior is actually suitable for the y case too. Where this is not the case, a final *) case can be used to handle all the otherwise unhandled values.
I wouldn't use a case statement when you only care about one of the branches:
function doit {
read -p " Do you want to continue? {y/n} " ans
[[ $ans == [nN]* ]] && return 1
PS3=" 32b or 64b? "
select size in 32 64; do
case $size in
32|64) break ;;
esac
done
do${size}
}
Can someone help and tell me why this isn't working?
I have checked the script and solved some problems but it still doesn't works fine and I can't find the mistake.
#!/bin/bash
#variabelen
IP="192.168.0."
array=($#)
#functies
What's wrong with the array? My linux told me that there is a syntax error on line 12 so with that array but he doesn't tell me what.
function Sorteer(){
array=($(printf '%s\n' "$#"|sort -nu))
for i in ${array[#]};do
ping -c -1 "IP"$i
done
}
function Telbij(){
# given number $i +200
b=$(( $i + 200 ))
if (( b > 255 ))
then
echo "Neem kleiner getal";
else
ping -c 1 "IP"$b;
fi
}
function XXYY() {
#ping 65-68 = ping 65 66 67 68
start=${1%-*}
end=${1#*-}
for ((i=start;i<=end;i++));do
ping -c 1 "$IP"$i
done
}
The mistake is in the if else function: http://prntscr.com/7gr8yf
But I don't know what that means: "The mentioned parser error was in this else clause."
if [ "$#" -eq 0 ]; then
echo "Er moet minimaal 1 parameter worden meegegeven "
exit 0
else
case
-h -help ) echo "Geef de laatste cijfers van het IP-adres van de pc's om te testen.";;
XX-YY ) XXYY;;
-t ) Telbij;;
- sort ) Sorteer;;
esac
fi
done
Don't know what's specifically not working but,
in Sorteer function you should double quote array expansions to avoid re-splitting elements.
Try change to following:
function Sorteer(){
array=($(printf '%s\n' "$#"|sort -nu))
for i in "${array[#]}";do
ping -c -1 "IP"$i
done
}
Now your case operator should be like:
case $some_value in
-help ) echo "Geef de laatste cijfers van het IP-adres van de pc's om te testen.";;
XX-YY ) XXYY;;
-t ) Telbij;;
-sort ) Sorteer;;
esac
This will fix your if issue as well
Basically I have to make my linux program do the same thing as my MS-DOS. Could someone help with pointers and things like that?
All the program currently does, is pull a menu for basic, advanced account creation and close.
Advanced has nothing in atm, and close does what you expect. Basic then asks you for:
Full name
Username
Password
It then saves it all in a .log file (after checking for usernames already entered) along with the exact time of creation. For example:
Badja
John Doe
123
23/04/2015 15:07:32.61
#echo off
c:
:1
set curdir=%test%
echo Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in.
echo.
echo [1] Basic Account Creation
echo [2] Advanced Account Creation
echo [3] Exit
echo.
REM Menu choices
set /p cat=
if %cat%==1 (
goto 2
) else if %cat%==2 (
goto 3
) else if %cat%==3 (
goto 5
) else (
goto 4
)
:2
REM Basic account creation
echo Welcome to basic account creation.
REM user enters details
REM Username
echo Please Enter a Username
set /p username=
echo.
REM Real Name
echo Please enter your full name
set /p fullname=
echo.
REM Password
echo Please enter a password
set /p password=
echo.
REM Real name
REM Save to file
if exist %username%.log (
echo User name already exists, please enter a new user name to create an account, or return to the log in screen
goto 1
) else (
echo %username% >> %username%.log
echo %fullname% >> %username%.log
echo %password% >> %username%.log
echo %date% %time% >> %username%.log )
timeout /t 3 /nobreak > NUL
REM pause
goto end
:3
REM Advanced account creation
echo Welcome to advanced account creation.
echo This is not complete, please return to main menu.
Pause
goto 1
:4
REM Error
echo error
echo.
goto 1
:5
REM Exit
echo Goodbye.
goto end
:end
exit​
I know there are a few things that can't be copied over to linux, but I just don't know where to start, this is my basis:
PS3='Please enter your choice: '
options=("cat 1" "cat 2" "end")
select opt in "${options[#]}"
do
case $opt in
"cat 1")
echo "Basic"
;;
"cat 2")
echo "Advanced"
;;
"end")
break
;;
*) echo invalid option;;
esac
done
Any help would be amazing guys!
function choice1 {
echo "Do stuff here to create an account"
}
function choice2 {
echo "Get the point?"
}
function choice3 {
exit
}
#### Main
echo "Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in."
echo
echo "[1] Basic Account Creation
[2] Advanced Account Creation
[3] Exit"
echo
read CHOICE #### This loads your choice into a variable
eval choice"$CHOICE" ### This is evaluation awesomeness
If the eval seems strange, you can go with a more traditional case...esac statement to call the various functions. I would suggest getting your menu cycling and escaping the way that you want before adding in your special function.
clear
echo "Welcome to OP-SYS Account creation. Please choose which mode you would like to continue in."
echo
echo "[1] Basic Account Creation
[2] Advanced Account Creation
[3] Exit"
echo
I want my calendar to correctly handle months with leading zeros
for example: "cal 01" or "cal 01 2012"
How do I write the code to make my calendar to correctly handle months with leading zeros?
This is my code so far:
$ cat cal
#cal: nicer interface to /usr/bin/cal
case $# in
0) set 'data';m=$2; y=$6 ;; # no argu: use today
1) m=$1; set 'data'; y=$6 ;; # 1 rg: use this year
*) m=$1; y=$2 ;; # 2 ags: month and year
esac
case $m in
jan*|Jan*) m=1 ;;
feb*|Feb*) m=2 ;;
mar*|Mar*) m=3 ;;
apr*|Apr*) m=4 ;;
may*|May*) m=5 ;;
jun*|Jun*) m=6 ;;
jul*|Jul*) m=7 ;;
aug*|Aug*) m=8 ;;
sep*|Sep*) m=9 ;;
oct*|Oct*) m=10 ;;
nov*|Nov*) m=11 ;;
dec*|Dec*) m=12 ;;
[1-9]|10|11|12) ;; # numeric month
*) y=$m; m="" ;; # plain year
esac
/usr/bin/cal $m $y # run the real one
$
You can do multiple regex matching in your case statement, i.e.
case $m in
01|1|jan*|Jan*) m=1 ;;
02|2|feb*|Feb*) m=2 ;;
....
Else, you could use shell parameter substitution to remove any leading 0's, i.e.
# as a way to demonstrate param sub on $1 etc, load values to $1 and $2
set -- 01 02
echo ${1#0}
echo ${2#0}
# output
1
2
Edit
For your follow-up question
Example, the current month is November, 2005, if you run "cal 01", you should print out the calendar of Jan. 2006
Try this:
# if the month input is less than the current month, assume the next year
if (( ${y:-0} == 0 && m < $(/bin/date +%m) )) ; then
y=$(/bin/date +%Y)
((y++))
fi
${y:-0} is one of several parameter checking syntaxs provided by most shells that allows a default value to be substituted if the var value is completely unset (not set at all) or = "". So in this case, if y wasn't set by the command line, it will appear as 0 in this evaluation, allowing the && section to be be executed to test the month, etc.
You'll need to extend your case $# processing to allow for 1 argument, that is assumed to be a month value.
I hope this helps.