Rejecting inputs that include WWW. in bash - bash

I am trying to block inputs of domains without www. in regex Bash.
Was using : \b(?:(?!www.)\w)+\b
Update:
Was able to resolve this issue by using the suggested expression.
Successfully Implemented As
while [[ ! $domain =~ www.*[.]([^\s]+) ]]; do
echo "Enter domain without www."
read domain
echo
done

You can determinate domains with "www." and then block them
With http/https:
http[s]*:\/\/www.*[.]([^\s]+)
without http/https:
www.*[.]([^\s]+)

Related

Difficulty using readlink in bash with mix of variables and string to return absolute paths

I have a config script where users can specify paths as variables in the header section. I want them to be able to use absolute paths, relative paths and variables (because this is actually called from another shell script from where they get the values for the variables). At the end of the script all the paths are written to a text file.
The challenge I have is that variables used within some of the paths can change in the middle of the script. I am having difficulties in re-evaluating the path to get the correct output.
### HEADER SECTION ###
DIR_PATH="$VAR1/STRING1"
InputDir_DEFAULT="$DIR_PATH/Input"
### END HEADER ###
...some code
if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi
...more code
# $InputDir_DEFAULT needs re-evaluating here
InputDir=$(readlink -m $InputDir_DEFAULT)
echo $InputDir >> $FILE
When I do as above and 'some condition' is met, the return of 'echo' is the absolute path for $VAR1/STRING1/Input, whereas what I want it the abs path for $VAR2/STRING2/Input.
Below is an alternative, where I try to stop InputDir_DEFAULT being evaluated until the end by storing itself as a string.
### HEADER SECTION ###
DIR_PATH="$VAR1/STRING1"
InputDir_DEFAULT='$DIR_PATH/Input' #NOTE: "" marks have changed to ''
### END HEADER ###
if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi
STRING_TMP=$InputDir_DEFAULT
InputDir=$(readlink -m $STRING_TMP)
echo $InputDir >> $FILE
This time 'echo' returns a mix of the evaluated variables and un-evaluated string: $VAR2/STRING2/$DIR_PATH/Input which (for me) looks like /home/ubuntu/STRING2/$DIR_PATH/Input. It's just the $DIR_PATH/ that shouldn't be there.
This feels like it should be relatively straightforward. I'm hoping I'm on the right path and that it's my use of "" and '' that's at fault. But I've tried lots of variations with no success.
When you initially set InputDir_DEFAULT, it is taking the currently set value for ${DIR_PATH}; even if you update ${DIR_PATH} later on, InputDir_DEFAULT will remain what it was set to earlier. To resolve this in your current script, you could set InputDir_DEFAULT again inside the if statement:
InputDir_DEFAULT=${DIR_PATH}/Input
Additionally, in your second attempt the single quoted value setting translates to the literal string value and does not expand to the variable's value:
InputDir_DEFAULT='$DIR_PATH/Input'
I would recommend referring to the "Quoting" section in the GNU Bash manual.
This is the solution I came to in the end. It's a mix of what was suggested by #ThatsWhatSheCoded and some other stuff to ensure that the user doesn't have to redefine variables anywhere other than in the header.
I expect there's a more elegant way of doing this, but this does work.
### HEADER SECTION ###
DIR_PATH_DEFAULT="$VAR1/STRING1"
InputDir_DEFAULT="$DIR_PATH_DEFAULT/Input"
### END HEADER ###
...some code
if [[ some condition ]]; then DIR_PATH="$VAR2/STRING2"; fi
### Checks whether $DIR_PATH_DEFAULT is used in any variables.
### If so and $DIR_PATH is different, will replace string.
### This will be done for all variables in a list.
if [[ ! "$DIR_PATH_DEFAULT" =~ "$DIR_PATH" ]]; then
for i in ${!var[#]}; do
var_def_val=${var[i]}_DEFAULT
STRING_TMP=${!var_def_val}
var_def=${var[$i]}_DEFAULT
if [[ $STRING_TMP == *"$DIR_PATH_DEFAULT"* ]] && [[ ! $var_def == "DIR_PATH_DEFAULT" ]]; then
STRING_TMP="${STRING_TMP/$DIR_PATH_DEFAULT/$DIR_PATH}"
eval "${var_def}=$STRING_TMP"
fi
done
fi
...more code
InputDir=$(readlink -m $InputDir_DEFAULT)

read -p regex validation

I am attempting to add regex validation to read -p, for example a domain name.
Current Code:
read -p "Do Something": dosomething
echo working on $dosomething
Thank you for the update as-per validating email, I trying to figure out if it is possible to apply regex validation at all to read -p.
Use a loop:
email=""
until [[ $email =~ $regex ]] ; do
read -p 'Enter your email: ' email
done
The regex
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
shown at EmailRegex.com isn't bash compatible, unfortunately.
Short answer: sure, this is something that read could hypothetically do. But bash's implementation of read does not have this feature, and I don't know of any POSIX-compatible shell that does, and POSIX itself does not include such a feature, although it seems like the kind of thing that an implementation could add as an extension if desired. If you like the feature enough, consider submitting a patch to bash to add it!
It's easy enough to build validation using read: just use a loop to read a value, check to see if it is valid, and if not, try again. You can write this as a bash function if you feel the need to do this on a regular basis.

How can I escape forward slashes in a user input variable in bash?

I'm working on a script to make setting up a Statamic site more efficient. The problem I'm running into is that the variable I'm using to replace a string in a file has unescaped forward slashes and is user input. How can I make sure that _site_url: http://statamic.com will become _site_url: http://example.com?
The code below will work as long as there are no forward slashes present.
echo "What's your site URL? Don't forget the protocol (ex. http://)!"
read -e SITE_URL
echo "%s/_site_url: http:\/\/statamic.com/_site_url: $SITE_URL/g
w
q
" | ex _config/settings.yaml
Since you specifically mentioned bash instead of Bourne shell or generic Unix shell, I'd recommend using Bash's built in search/replace feature:
echo "What's your site URL? Don't forget the protocol (ex. http://)!"
read -e SITE_URL
echo Escaped URL: ${SITE_URL//\//\\\/}
The problem is the delimiter in your ex command. We can put anything we'd like instead, I use # here :
Try doing this :
sed -i "s#_site_url: http://statamic.com/_site_url: $SITE_URL#g" _config/settings.yaml
Or with your ex command :
echo "What's your site URL? Don't forget the protocol (ex. http://)!"
read -e SITE_URL
echo "%s#_site_url: http://statamic.com#_site_url: $SITE_URL#g
w
q
" | ex _config/settings.yaml

BASH IP Address Check

I am working on a BASH shell script where I need to be able to check and see if the IP address returned from:
dig $HOSTNAME +short
is within a particular subnet or not. For example, if part of 192.168.10.x or 10.130.10.x then do z else do y.
I am not sure how to manipulate or check the IP address after I have it stored in a variable so that I can build out the logical test described above.
If your subnets are full class C then you can just do a substring check:
if [ ${IP#192.168.10.*} == ${IP} -a ${IP#10.130.10.*} == ${IP} ]
then
echo "not in either subnet"
else
echo "in one of the subnets"
fi
Edit: Note, this of course doesn't validate that the IPs are valid, but it alleviates the need for external tools.
I ended up using the following code to make it work:
if [[ "$IP" == *10.130.10.* || "$IP" == *192.168.10.* ]]; then
mount code goes here
fi
Thanks for everyone's help and explaining things to me to allow me to further learn about scripting. It is really appreciated!

to which subnet IP address belongs?

I have to write a script in bash , perl or python.
I got file with three columns (for manually manage connect-proxy)
SUBNET/IP socks_port socks_ip
1.2.3.* 1080 9.8.7.6
1.1.* 1080 6.8.7.6
I want to know to which subnet belongs IP address,
for example:
$ my_script 1.1.1.2
this IP belongs to 1.1.* subnet so I want back second line.
BASH: quick and dirty, use cut, then grep over the file.
PYTHON: use ip.rsplit() and then line.split()[].startswith() iterating through the file.
PERL: no idea.
Cheers!
If the file is in the format given (i.e. using *), it'll be fairly easy to use bash pattern matching to compare this to the ip address. However, as #Mark Drago pointed out, this format anything except octet-boundary subnets, so if you need to support arbitrary subnet boundaries, you need a better format.
Assuming you are using the "1.2.*" format, this should work:
#!/bin/bash
ip="$1"
found_match=false
while read subnet socks_port socks_ip; do
if [[ "$ip" == $subnet ]]; then # this'll do glob-style pattern matching against $subnet
echo "subnet=$subnet, socks_port=$socks_port, socks_ip=$socks_port"
found_match=true
break # assuming you don't want to check for multiple matches
fi
done </path/to/subnet/file
if ! $found_match; then
echo "No match found in subnet file"
fi

Resources