在 Bash 中使用 grep 验证参数中的 http:// 或 https://

发布于 2025-01-13 05:28:24 字数 381 浏览 2 评论 0原文

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

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

输出总是跳转到最后一个|| echo 'Ce script supporte seulement les URLs commencant par https:// ou http://' 即使我的参数 1 有 http:// 或 https://。

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

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

The output always jumps to the last || echo 'Ce script supporte seulement les URLs commencant par https:// ou http://' even if my argument 1 have http:// or https://.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如此安好 2025-01-20 05:28:24

这可能会让你走上正确的道路

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

This may set you on the right path

echo "$1" | grep -Eiq '^https?://' 2>/dev/null || echo "fail"
吃→可爱长大的 2025-01-20 05:28:24

假设不失一般性,您的脚本是用一个参数调用的,即 http://something

echo $1 | grep -i "http://" $1 不会在 http://something 输出的字符串 http:// 中查找 http:// >echo 到管道,因为 grep option(s) regexp argument 忽略其标准输入,而是读取由参数命名的文件。因此,它尝试读取一个名为 http://something 的文件,该文件当然不存在。但由于您已重定向 2>/dev/null ,告诉您此情况的错误消息会消失,因此您只会收到抱怨 URL 的消息并退出。

执行 echo $1 | grep -i "http://" (对于 https 也类似)可以工作,但非常笨拙。它还将(匹配的)URL 输出到 stdout,您没有重定向该 URL,因此它可能会出现在您的终端上,这可能是您想要的,也可能不是您想要的。一般来说,只要参数可能包含空格(或其他 IFS 分隔符)或任何通配符(通配符),但有效的 URL 不能执行第一个操作,您就应该使用 echo "$1" ...并且几乎从不执行最后一个,因此在这种特定情况下它不太重要。

此外,grep 将匹配,从而接受包含 http:// 或 https:// 但不以它开头的 URL,如下所示需要回显消息状态。如果您只想在开头匹配,请在正则表达式中使用 ^

更有效的解决方案是使用来自此处字符串的输入的单个 grep (在扩展模式下使用 ^https? 表示“http 或 https,但仅在开头”):

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) 

甚至更高效(根本没有 grep )如果您可以只使用小写字母(实际上人们总是使用小写字母作为 URL 方案,即使标准规定应该接受大写字母)是:

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

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
七婞 2025-01-20 05:28:24

作为 grep 甚至 bash 正则表达式匹配的替代方案,您可以使用模式匹配。

if [[ $1 != http?(s)://* ]]; then

As an alternative to grep or even bash's regular expression matching, you can use pattern matching.

if [[ $1 != http?(s)://* ]]; then
梦幻之岛 2025-01-20 05:28:24

如果您需要不区分大小写的匹配

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

If you need case insensitive match

shopt -s nocasematch
if [[ ! "$1" =~ ^https?:// ]]
then
    echo 'ERROR' >&2
fi
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文