This script should accept a set of search terms and return a formatted URL to search google.
$ ./google_search.sh albert einstein
https://www.google.com/search?q=albert+einstein
It does that just fine, so I decided to add an option to search a specific site, or ignore that site, using a -s
or -S
flag.
$ ./google_search.sh -s wikipedia.org albert einstein
https://www.google.com/search?q=albert+einstein+site%3Awikipedia.org
This works the first time you run the script, but fails on every following attempt.
$ ./google_search.sh -s wikipedia.org albert einstein
https://www.google.com/search?q=albert+einstein
$ ./google_search.sh -s wikipedia.org albert einstein
https://www.google.com/search?q=albert+einstein
Opening a new Terminal window or restarting Terminal both clear this problem and allow one more attempt before failing.
The script:
#!/bin/bash
# original source of concatenate_args function by Tyilo:
# http://stackoverflow.com/questions/9354847/concatenate-inputs-in-bash-script
function concatenate_args
{
string=""
ignorenext=0
for a in "$@" # Loop over arguments
do
if [[ "${a:0:1}" != "-" && $ignorenext = 0 ]] # Ignore flags (first character is -)
then
if [[ "$string" != "" ]]
then
string+="+" # Delimeter
fi
string+="$a"
elif [[ $ignorenext = 1 ]]
then
ignorenext=0
else
ignorenext=1
fi
done
echo "$string"
}
qry="$(concatenate_args "$@")"
glink="https://www.google.com/search?q="
site=""
while getopts :s:S: opt; do
case $opt in
s) site="+site%3A$OPTARG" ;;
S) site="+-site%3A$OPTARG" ;;
esac
done
url=$glink$qry$site
echo $url
# open -a Firefox $url
What needs to change to make this script more reliable?
This is behaving like your are sourcing the script instead of executing it. If you use a dot and a space before the script, it causes the script to be executed line by line inside your current shell instead of creating a new shell. This allows environment variables that are changed inside the script to leak into your current shell's environment, which can make one run of the script not behave the same as the next.
In this case, it appears to be the use of getopts. getopts updates an environment variable each time it is called so it can keep track of which argument is being examined. The second time you source the script, it thinks that all the arguments have already been examined, so your argument ends up being ignored.