在 Bash 中使用 grep 验证参数中的 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
输出总是跳转到最后一个|| 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这可能会让你走上正确的道路
This may set you on the right path
假设不失一般性,您的脚本是用一个参数调用的,即
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 )如果您可以只使用小写字母(实际上人们总是使用小写字母作为 URL 方案,即使标准规定应该接受大写字母)是:
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 forhttp://
in the stringhttp://something
which was output byecho
to the pipe, becausegrep option(s) regexp argument
ignores its stdin and instead reads the file named by the argument. Thus it tries to read a file namedhttp://something
which of course does not exist. But since you've redirected2>/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 useecho "$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: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:
作为
grep
甚至bash
正则表达式匹配的替代方案,您可以使用模式匹配。As an alternative to
grep
or evenbash
's regular expression matching, you can use pattern matching.如果您需要不区分大小写的匹配
If you need case insensitive match