问题
*Edited to update status
I am trying to make a bash file that will allow you to select an option, output the answer and then loop back to the menu selection. As of right now, the code I have is:
#!/bin/sh
echo off
echo "........................................."
echo "Select the process you would like to run."
echo.
echo "1 - Free Disk Space Available"
echo "2 - List Directories"
echo "3 - Show Running Processes"
echo "4 - TCP Connection"
echo "5 - Network Interfaces"
echo "6 - List Directories"
echo "7 - Show Computer Hostname"
echo "8 - Routing Table"
echo "9 - Computer Uptime"
echo "10 - Available Block Devices"
echo "11 - Mount Device"
echo "........................................."
echo -n "Input desired function number and press ENTER: "
read selection
while [ {selection} ]
do
if [ $selection == 1 ]; then echo df -h
break
elif [ $selection == 2 ]; then echo ls -l /home
break
elif [ $selection == 3 ]; then echo ps -A
break
elif [ $selection == 4 ]; then echo netstat -a
break
elif [ $selection == 5 ]; then echo ifconfig
break
elif [ $selection == 6 ]; then echo $PATH
break
elif [ $selection == 7 ]; then echo hostname
break
elif [ $selection == 8 ]; then echo route
break
elif [ $selection == 9 ]; then echo uptime
break
elif [ $selection == 10 ]; then echo blkid
break
elif [ $selection == 11 ]; then echo mount
break
else
echo "Please enter a valid option"
fi
done
The output I get is an error that infinitely loops with
[: 2: unexpected operator
If anyone could help me out or guide me in the right direction I would greatly appreciate it.
回答1:
For menus, use the select command. Here, I'm using bash to store the options into an array.
#!/bin/bash
echo ".............................................................................."
echo "Select the process you would like to run by pressing the corresponding number."
choices=(
"Free Disk Space Available"
"List Directories"
"Show Running Processes"
"TCP Connection"
"Network Interfaces"
"List Directories"
"Show Computer Hostname"
"Routing Table"
"Computer Uptime"
"Available Block Devices"
"Mount Device"
)
PS3="Input desired function number and press ENTER: "
select selection in "${choices[@]}"
do
case "$selection" in
"${choices[0]}" ) echo df -h ;;
"${choices[1]}" ) echo ls -l /home ;;
"${choices[2]}" ) echo ps -A ;;
"${choices[3]}" ) echo netstat -a ;;
"${choices[4]}" ) echo ifconfig ;;
"${choices[5]}" ) echo $PATH ;;
"${choices[6]}" ) echo hostname ;;
"${choices[7]}" ) echo route ;;
"${choices[8]}" ) echo uptime ;;
"${choices[9]}" ) echo blkid ;;
"${choices[10]}" ) echo mount ;;
esac
done
If you want to break out of the menu, you would do
"${choices[10]}" ) echo mount; break ;;
Or add a "Quit" choice
回答2:
not too long ago some team mate who is not a lot of experienced in Unix asked me to give him an example of a Bash menu. So I sent him this. Hope it helps you. You dont need to loop if you chain the functions recursively.
function Main_Menu() {
clear
echo "Select an option ..."
printf "\n"
echo "1 - Check CPU"
echo "2 - Check disk utilization"
echo "3 - About"
echo "4 - Exit"
read -n 1 user_input
if [[ "$user_input" == "1" ]]
then
Check_CPU
elif [[ "$user_input" == "2" ]]
then
Check_disk_utilization
elif [[ "$user_input" == "3" ]]
then
About
elif [[ "$user_input" == "4" ]]
then
clear
echo "Chau!!"
else
Main_Menu
fi
}
function Check_CPU(){
clear
cpu_values=$( top -b -n2 -p 1 )
echo "****************************"
echo "****************************"
echo "**Current CPU values*"
echo "****************************"
echo "****************************"
echo "$cpu_values"
echo "****************************"
echo "Press ESC to go back or any other key to update..."
printf "\n"
read -n 1 user_input
if [[ "$user_input" == $'\e' ]]
then
Main_Menu
else
Check_CPU
fi
}
function Check_disk_utilization(){
clear
disk_utilization=$( df -h )
echo "****************************"
echo "****************************"
echo "**Current Disk Utilization*"
echo "****************************"
echo "****************************"
echo "$disk_utilization"
echo "****************************"
echo "Press ESC to go back or any other key to update..."
printf "\n"
read -n 1 user_input
if [[ "$user_input" == $'\e' ]]
then
Main_Menu
else
Check_disk_utilization
fi
}
function About(){
clear
echo "--------------------------------------------------"
printf "\n"
echo "This script was written by XXXXX"
echo "2017, Montevideo"
printf "\n"
echo "--------------------------------------------------"
echo "Press ESC to go back..."
printf "\n"
read -n 1 user_input
if [[ "$user_input" == $'\e' ]]
then
Main_Menu
else
About
fi
}
Main_Menu
Regards!
回答3:
Solution before your first edit
In bash commands are case-sensitive. There is an echo command, but no Echo or ECHO command. Same goes for if and so on.
Simply replace all ECHO with echo, IF with if, and ELIF with elif.
Solution after your first edit
The while [ {selection} ] looks odd. As a simple test, remove it (including the do and done) without replacement.
Solution for (probably) upcoming edits
echo df -hdoes not run thedf -hcommand, but only prints the literal stringdf -h. Just writedf -hwithout theechoto run it.The
while-loop should include thereadcommand, so that a user can make a new selection, if the previous selection was not valid. Move thereadcommand inside the loop and adjust the loop condition. With the current structure,while truewould be ok.
回答4:
Do not use quote, you have to use backtick ` or $() for the commands.
'ps -A' should be ps -A or $(ps -a).
来源:https://stackoverflow.com/questions/46453114/creating-a-bash-file-with-a-looped-menu-linux