Home > Software engineering >  Verification of http:// or https:// in an argument with grep in BASH
Verification of http:// or https:// in an argument with grep in BASH

Time:03-11

Input = ./q4.sh https://cdn.eso.org/images/thumb700x/eso1723a.jpg

echo $1 | grep -i "https://" $1 2> /dev/null || echo $1 | grep -i "http://" $1 2> /dev/null || echo 'Ce script supporte seulement les URLs commencant par https:// ou http://' && exit 1

output always jump to the last || echo 'Ce script supporte seulement les URLs commencant par https:// ou http://'

even if my argument 1 have http:// or https://

CodePudding user response:

Assuming without loss of generality your script is called with one argument which is http://something:

echo $1 | grep -i "http://" $1 does not look for http:// in the string http://something which was output by echo to the pipe, because grep option(s) regexp argument ignores its stdin and instead reads the file named by the argument. Thus it tries to read a file named http://something which of course does not exist. But since you've redirected 2>/dev/null the error message that would tell you this disappears, so you just get the message complaining about the URL and exit.

Doing echo $1 | grep -i "http://" (and similarly for https) would work, but is very clumsy. It also outputs the (matched) URL to stdout, which you didn't redirect, so it will probably appear on your terminal, which may or may not be what you want. In general you should use echo "$1" ... whenever the argument could contain whitespace (or other IFS delimiter) or any wildcard (glob) character(s), but a valid URL cannot do the first and almost never does the last so in this specific case it's less important.

Also that grep will match and thus accept a URL that contains http:// or https:// but does not begin with it, as the echo message states is required. If you want to match only at the beginning, use ^ in the regexp.

A more efficient solution would be a single grep (with ^https? in Extended mode meaning 'either http or https but only at beginning') with input from a herestring:

grep -Ei "^https?://" <<<$1 || echo "URL must begin ..." && exit 1
# if you don't want the matched URL output on stdout, 
# either redirect [1]>/dev/null or add q to the options (-Eiq) 

Even more efficient (no grep at all) if you can settle for lowercase-only (which in practice is what people always use for URL schemes, even if the standard says uppercase should be accepted) is:

case $1 in (http://* https://*) ;; (*) echo "URL must begin ..." ... ; esac

CodePudding user response:

This may set you on the right path

echo "$1" | grep -Eiq '^https?://' 2>/dev/null || echo "fail"

CodePudding user response:

If you need case insensitive match

shopt -s nocasematch
if [[ ! "$1" =~ ^https?:// ]]
then
    echo 'ERROR' >&2
fi
  • Related