Can somone help me with this: so i have this script
#!/bin/bash
echo -n "Enter a value for X:(999 to exit): "
read x
until [[ $x == 999 ]]
do
echo -n "Enter a value for Y: "
read y
echo "X="$x
echo "Y="$y
((a=y+x))
echo "X+Y="$a
((s=y-x))
echo "X-Y="$s
((m=y*x))
echo "X*Y="$m
((d=y/x))
echo "X/Y="$d
((m=y%x))
echo "X%Y="$m
echo -n "Enter a value for X:(999 to exit): "
read x
if [[ $x == 999 ]];
then
exit 0
fi
done
exit 0
but i didnt know how to write the rest of it, the missing thing is:
Use the two command line arguments when the script starts if the user supplied them, and then prompt for more numbers to continue in the loop.
Am guessing the arguments you are looking from the user are x and y values. The easiest way to check if user provided arguments is to use $# which gets you the number of arguments given by the user.
So use it like this:
if [ "$#" -eq 2 ]; #2 arguments provided by user
then
x=$1
...
fi
Related
So I am learning bash and wanted to make a script to 'automate' a collection of kali tools. Basically I do not understand why the if statement code is being triggered regardless if condition is true or false.
#!/bin/bash
#requires root or sudo priv
#check for a successful ping
target_ip=$1
nmap_opt = " "
#nmap options variables --
nmap_os="-O"
nmap_version="-sV"
nmap_udp="-sU"
nmap_stealth="-sS"
nmap_aggr="-A"
nmap_option_input_temp=""
ping $target_ip -c 5
if [ $? -eq 0 ]; then
echo "successful ping on" $target_ip
else
echo "ping unsuccessful, check VPN connection or host may be down"
exit 1
fi
read -p "enter pathway for nmap output: " nmap_file
read -p "detect os? (y/n) " nmap_option_input_temp
#add loops for y/n user input
if [[ ${nmap_option_input_temp} -eq "y" ]];
then
nmap_opt="${nmap_opt} ${nmap_os}"
elif [[ ${nmap_option_input_temp} -eq "n" ]];
then
nmap_opt=$nmap_opt
else
echo "invalid option"
fi
read -p "detect version? (y/n) " nmap_option_input_temp
#add loops for y/n user input
if [[ ${nmap_option_input_temp} -eq "y" ]];
then
nmap_opt="${nmap_opt} ${nmap_version}"
elif [[ ${nmap_option_input_temp} -eq "n" ]];
then
nmap_opt=$nmap_opt
else
echo "invalid option"
fi
echo "nmap selected option/s:" $nmap_opt
echo $nmap_option_input_temp
#starting nmap..
sudo nmap $nmap_opt -oN $nmap_file $target_ip
this is the nmap_opt variable echo out even when both inputs are 'n'
nmap selected option/s: -O -sV
Let me know if there is anything I missed in the explanation!
-eq is for integer comparisons. Use ==:
if [[ "${nmap_option_input_temp}" == y ]];
And fix your quotes. Fixed strings like y don't need to be quoted. Inside [[, variables don't need to be quoted, but IMO you should quote them anyway for consistency.
This error would be more easily spotted if you used the more conventional:
if [ "${nmap_option_input_temp}" -eq y ]; # Still incorrect!!
since you would get a nice error message.
Note that the fix with [ is slightly different, and you should use a single =:
if [ "${nmap_option_input_temp}" = y ];
The == operator is a bashism which does not really add any value. But really, you should not be using if/elif at all here. This is the perfect place for a case statement:
case "${nmap_option_input_temp}" in
y) nmap_opt="${nmap_opt} ${nmap_os}";;
n) ;;
*) echo "invalid option" >&2 ;;
esac
Made a script that the user gives a "parameter" and it prints out if it is a file, directory or non of them. This is it :
#!/bin/bash
read parametros
for filename in *
do
if [ -f "$parametros" ];
then
echo "$parametros is a file"
elif [ -d "$parametros" ];
then
echo "$parametros is a directory"
else
echo " There is not such file or directory"
fi
exit
done
Altough i want the user to be allowed to give only one word as a parameter. How do i make this happen ? (For example if user press space after first word there would be an error message showing "wrong input")
#!/bin/bash
read parametros
if [[ "$parametros" = *[[:space:]]* ]]
then
echo "wrong input"
elif [[ -f "$parametros" ]]
then
echo "$parametros is a file"
elif [[ -d "$parametros" ]]
then
echo "$parametros is a directory"
else
echo " There is not such file or directory"
fi
See http://mywiki.wooledge.org/BashFAQ/031 for the difference between [...] and [[...]].
You have to use the $#. It gives the number of the parameters.
The code will be something like:
if [ "$#" -ne 1 ]; then
printf 'ERROR!\n'
exit 1
fi
First, I'm curious why you want to restrict to one word - a file or directory could have spaces in it, but maybe you are preventing that somehow in your context.
Here are a few ways you could approach it:
Validate the input after they enter it - check if it has any spaces, eg: if [[ "parametros" == *" " ]]; then...
Get one character at a time in a while loop, eg with: read -n1 char
Show an error if it's a space
Break the loop if it's 'enter'
Build up the overall string from the entered characters
1 is obviously much simpler, but maybe 2 is worth the effort for the instant feedback that you are hoping for?
I'm trying to add up all numbers inputted by a user, however there is no limit on how many numbers a user can input for the addition. How do I code this in linux shell script?
I have this so far:
firstNumber=0
secondNumber=0
number=0
echo Please enter two numbers to add up
read firstNumber
read secondNumber
echo Would you like to keep adding numbers? YES OR NO
read answer
if answer = YES
then
echo Please add another number
read number
echo $(($firstNumber +$secondNumber + $number))
fi
while answer = NO
do
echo $(($firstNumber + $secondNumber))
done
as #dash-o recommended, a simple entry sequence ended with ENTER is the most simple approach:
#!/usr/bin/env sh
sum=0
echo "Please enter integer numbers to add, or just RETURN to end."
while read -r number && [ -n "$number" ]; do
if [ "$number" -eq "$number" ] 2>/dev/null; then
sum=$((sum + number))
echo "Sum is: $sum"
else
echo "$number is not a valid integer. Try again..." >&2
fi
done
Or to allow multiple integers entry per line:
#!/usr/bin/env sh
# Save the shell's options state
shelloptions="$(set +o)"
# Disable globbing to prevent filename expansion in parameters
set -o noglob
sum=0
echo "Please enter integer numbers to add, or RETURN to end."
# Read lines until empty REPLY
while read -r && [ -n "$REPLY" ]; do
# Split $REPLY as parameters
# Globbing is turned-off so filenames will not mess with entries
# shellcheck disable=SC2086 # Explicitly intended word splitting
set -- $REPLY
# Iterate numbers from the parameters array
for number in "$#"; do
# If $number is a valid integer
if [ "$number" -eq "$number" ] 2>/dev/null; then
sum=$((sum + number))
else
echo "$number is not a valid integer." >&2
fi
done
echo "Sum is: $sum"
done
# Restore the shell's options state
eval "$shelloptions"
I am trying to write a script which will check number of arguments for first and second number; if both variable entered, it will do the calculation; if one argument is missing, it will print error message.
Here what I've done so far:
#!/bin/bash
echo -n "Enter the first number: "
read num1
echo -n "Enter the second number: "
read num2
if [ $# -le 1 ]; then
echo "Illegal number of arguments"
exit
else
echo "The sum is: " $(( num1 + num2 ))
fi
I am always getting error message even though I enter both of the numbers. What am I missing? Please help.
Test Your Assigned Variables, Not Positional Parameters
Your variables num1 and num2 aren't positional parameters, and so the special parameter $# is probably not what you think it is. You should change your conditional to check that both variables are set. For example:
declare -i num1 num2
read -p 'Enter the first number: ' num1
read -p 'Enter the second number: ' num2
if [ -z "$num1" ] || [ -z "$num2" ]; then
echo "Illegal number of arguments" >&2
else
echo "The sum is: $((num1 + num2))"
fi
Looks like you are messing up command line arguments and variables you are reading interactively. $# has nothing to do with variables you declared and/or read from command line. It is the number of command line arguments. You need to check the variables you attempted to read from console:
#!/bin/sh
echo -n "Enter the first number: "
read num1
echo -n "Enter the second number: "
read num2
[ -z $num1 ] || [ -z $num2 ] && echo "Illegal number of arguments" && exit 1
echo "The sum is: " $(( num1 + num2 ))
On the other hand, if you really want to check command line arguments, the script will be even simpler:
#!/bin/sh
[ -z $2 ] && echo "Illegal number of arguments" && exit 1
echo "The sum is: " $(( $1 + $2 ))
Here $1 refers to the first argument, $2 refers to the second argument and so on. $0 refers to the name of the script itself.
So, the way you have your program setup right now, it takes input through the read command, but that isn't the same as passing in an argument.
You pass an argument through the CLI, for instance:
./sum.sh 5 2 # => 7
Where sum.sh is the name of the file and 5 and 2 are your arguments.
So, the reason you keep getting "Illegal number of arguments" is because in bash the $# variable holds the number of arguments, but since you're reading the values in from the code, $# will always less than 1 because no arguments have been provided.
What I think you're looking for is something like this:
#!/bin/bash
if [ $# -le 1 ]; then
echo "Illegal number of arguments"
exit
else
echo "The sum is: " $(( $1 + $2 ))
fi
This article is pretty good if you want to learn more: http://www.bashguru.com/2009/11/how-to-pass-arguments-to-shell-script.html
I want to make sure my bash script can correctly detect user's input argument. Specifically, user can only pass 1 or 2 or 3 into the script, otherwise the script will be terminated. I wrote the following code:
#!/bin/bash
for args in $#
do
echo $args
done
if [ "$#" != 1 ] && [ "$#" -ne 1 ]; then
echo "Illegal number of parameters"
exit 1
fi
This script can only capture when user does not give any input, but cannot check whether user indeed input the number 1 not other values.
By the way, I am not sure how to express "input argument can accept number 1 or 2 or 3".
$# is an integer, so you have to use integer comparison. You can for example say:
if [ "$#" -ne 1 ]; then
echo "illegal number of parameters"
exit 1
fi
To check that the parameter is either 1, 2 or 3, you can use this regular expression (see something related):
if [[ ! $1 =~ ^(1|2|3)$ ]]; then
echo "the number is not 1, 2 or 3"
exit 1
fi
To express "input argument can accept number 1 or 2 or 3" I would for example say "we can just accept the argument being either 1, 2 or 3".
First off you can detect if the string is null or empty simply by doing the following:
if [ -z "$1" ]
then
echo "Argument $1 contains nothing"
fi
That I would say is your first step, and will allow you to filter out args that have no content.
Following on from that, you'd most likely need to do some comparison work on $1, $2 & $3
I'll just check something and come back to this in a moment.
Update
Just had to go find one of my scripts and check something... :-)
One way I've handled the checking of parms in the past is something like the following
#!/bin/sh
while [ $# -gt 0 ] || [ "$#" -le 4 ]; do
case "$1" in
*[!1-9]*) echo "Text: $1";;
*) echo "Number: $1"
esac
case "$2" in
*[!1-9]*) echo "Text: $2";;
*) echo "Number: $2"
esac
case "$3" in
*[!1-9]*) echo "Text: $3";;
*) echo "Number: $3"
esac
shift
done
Basically a simple regex, if I have more than 0 parameters or less than 4 parameters then I allow it through to a case statement, which then checks the content of each parameter.
This one just has an echo in, but you could just as easy set some flags, and then decide how to continue based on those flags.
For simple range checking however, you might just want to use a one liner similar to the following:
if [[ $# -gt 0 && $# -lt 4 ]]; then echo "Correct number of parameters"; fi
Again setting a flag to use later rather than echoing the results.
I assume you mean the input can only be 1, 2 or 3, so using a case statement is the best way. $1 is the variable that stores your argument, if it is equal to 1 case will execute the code in the block corresponding to the value 1 and so on.
case "$1" in
1) ...
;;
2) ...
;;
3) ...
;;
*) echo "Invalid argument"
;;
esac