I'm somewhat new to the world of Bash scripting, and am still attempting to understand what most would consider to be the basics. I found this helpful guide which I have been pulling most of my information from, and despite it referring to "advanced" it actually covers the basics very well for a newcomer like myself.
At this point, I have written a script that works how I want it to, however I guess I'm what some might consider to be code conscious. So while my script does indeed work, I don't think I'm utilizing Bash's if/then/else statements properly.
Here is the small script I've written that basically checks for usernames, and whether or not they exist, via an API query. It allows a user to define a list via ./script.sh list
, or if they do not define a list it simply attempts all variations of letters ( {a..z}
):
#!/bin/bash
# variables
host='https://api.example.com/api/users/'
sleep=1
# check if jq install
if ! jq_loc="$(type -p "jq")" || [ -z "$jq_loc" ]; then
echo "no jq installed."
sleep 1
echo "we're going to install it now."
sleep 2
sudo apt-get install jq
fi
# specified list
if [ -n "$1" ] ; then
list=`cat $1`
for username in $list
do
#echo $username
sleep $sleep
VAL=`curl -s "$host$username" | jq -r ".id" | grep null`
#echo $VAL
if [[ $VAL == null ]]
then
echo -e "$username is available"
echo "$username" >> username.free
else
echo -e "$username is taken"
fi
done
fi
# no list specified
if [ $# -eq 0 ] ; then
list=`echo {a..z}{a..z}{a..z}`
for username in $list
do
#echo $username
sleep $sleep
VAL=`curl -s "$host$username" | jq -r ".id" | grep null`
#echo $VAL
if [[ $VAL == null ]]
then
echo -e "$username is available"
echo "$username" >> username.free
else
echo -e "$username is taken"
fi
done
fi
As I stated, the script works exactly how I want it to. But where my concern comes in at is if [ $# -eq 0 ] ; then
if [ $# -eq 0 ] ; then
and if [ -n "$1" ] ; then
if [ -n "$1" ] ; then
. I feel like I'm echoing for it to do the same function needlessly. For example, instead of having to tell it to perform the curl
command in each if
, is there a way I can consolidate these two if
's into a single one?
Hopefully I have explained this well enough, and if not please just comment and I can update this question accordingly.
Thanks in advance!
Your if statements cover all logical branches. Thus, the following code block will be executed either way. So there is no reason to duplicate it. Simply move it below the if statements.
for username in $list
do
#echo $username
sleep $sleep
VAL=`curl -s "$host$username" | jq -r ".id" | grep null`
#echo $VAL
if [[ $VAL == null ]]
then
echo -e "$username is available"
echo "$username" >> username.free
else
echo -e "$username is taken"
fi
done
Here is the code reworked to reduce the duplication:
#!/bin/bash
# variables
host='https://api.example.com/api/users/'
sleep=1
# check if jq install
if ! jq_loc="$(type -p "jq")" || [ -z "$jq_loc" ]; then
echo "no jq installed."
sleep 1
echo "we're going to install it now."
sleep 2
sudo apt-get install jq
fi
if [ -n "$1" ] ; then
# specified list
list=`cat $1`
else
# no list specified
list=`echo {a..z}{a..z}{a..z}`
fi
for username in $list
do
#echo $username
sleep $sleep
VAL=`curl -s "$host$username" | jq -r ".id" | grep null`
#echo $VAL
if [[ $VAL == null ]]
then
echo -e "$username is available"
echo "$username" >> username.free
else
echo -e "$username is taken"
fi
done
Rather than reading data into a variable and then working on that variable, a common technique is to just work on the data as it is read. To that end, I would offer the following edit of Micah's script:
#!/bin/bash
# variables
host='https://api.example.com/api/users/'
sleep=1
# check if jq install
type jq > /dev/null || sudo apt-get install jq
# Here is a bit of "magic". We create a process to generate the data
# that we want to use as input and redirect its output to be the input
# of the script so that the subsequent read handles it. (Note that it
# is totally unnecessary to do this, and we could just as easily pipe
# this data directly to the while/read loop, but for some reason I
# thought it would be instructive to see this technique.)
exec < <(
if [ -n "$1" ] ; then
cat $1
else
echo {a..z}{a..z}{a..z} | tr ' ' \\n
fi
)
while read username
do
sleep $sleep
if curl -s "$host$username" | jq -r ".id" | grep -q null
then
echo "$username is available"
echo "$username" >> username.free
else
echo "$username is taken"
fi
done
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.