添加微信

添加微信

微信公众号
签证代办电话:

400-8888-88999

当前位置: 首页 > 签证百科

如何编写接受shell中参数的CGI脚本?

发布时间: 浏览次数:0 文章来源:其他

CGI程序可以通过Web浏览器(用户代理)发送的参数来调用。至少有两种方法可以调用CGI程序:GET方法和POST方法。在GET方法中,参数以名为QUERY_S
 

CGI程序可以通过Web浏览器(用户代理)发送的参数来调用。至少有两种方法可以调用CGI程序:GET方法和POST方法。在GET方法中,参数以名为QUERY_STRING的环境变量的形式提供给CGI程序。参数采用键值对的形式(例如user=george),某些字符以十六进制编码,空格以加号编码,并用&号连接在一起。在POST方法中,参数则通过标准输入提供。

关联数组

最佳方法是将键值对放入关联数组中。关联数组可在ksh93和bash 4.0中使用,但在POSIX或Bourne Shell中不能使用。它们被设计用来存储键值对,其中键可以是任意字符串,因此似乎适合这个任务。

# Bash 4+# 读取cgi输入字符串if [[ $QUERY_STRING ]]; then query=$QUERY_STRINGelse read -r queryfi# 设置一个关联数组来保存查询参数declare -A params# 遍历 key=value+%41%42%43 元素# 分离 key 和 value,并对 value 进行解码while IFS='=' read -r -d '&' key value; do # 解码步骤: # 1. 将 \ 替换为 \\. 第4步将把它们改回 \ # 2. 将加号替换为空格 # 3. 将百分号替换为 \x # 4. 使用 printf %b 将其扩展为 \-转义 value=${value//\\/\\\\} value=${value//+/ } value=${value//'%'/\\x} printf -v 'params[$key]' %b "$value"done <<< "$query&"# 现在我们可以使用名为 params 的关联数组中的参数# 如果我们需要键列表,则为 "${!params[@]}"。

上述代码中的注释解释了如何从CGI输入字符串中提取查询参数,将其存储在关联数组中,并对查询参数进行解码。在解码过程中,将转义字符进行转义,将加号替换为空格,将百分号转换为\x,并使用printf %b将其转换为特殊字符。最后,可以使用关联数组中的参数进行后续操作,或者使用"${!params[@]}"获取关联数组中的键列表。

如何编写接受shell中参数的CGI脚本?

printf的-v varname选项在支持关联数组的每个bash版本中都可用,因此我们可以在这里使用它。与调用子shell相比,其效率要高得多。我们还避免了如果值恰好为-n时,使用echo -e可能会出现的潜在问题。

从技术上讲,CGI规范允许在一个查询中多次使用同一个键。例如,group=managers&member=Alice&member=Charlie就是一个完全合法的查询字符串。本页上没有任何一种方法处理这种情况(至少不是我们认为的“正确”方式)。幸运的是,你很少会编写这样的CGI;而且无论如何,你没有被迫在这个任务中使用bash。处理QUERY_STRING的快速、简单且危险的方法是将&转换为;,然后使用eval命令运行这些赋值。然而,强烈不建议使用eval。也就是说,我们总是尽量避免使用eval,只要有其他方式可以绕过它。

更早的Bash Shell

如果你没有关联数组,不要轻率使用eval。一个更好的方法是逐个提取每个变量/值对,并将它们分配给Shell变量,而不执行它们。这需要间接变量赋值,也就是使用一些特定于Shell的技巧。我们将使用Bash语法来编写此代码;转换为ksh或Bourne Shell由您自行完成。

如何编写接受shell中参数的CGI脚本?

# Bash 3.1 +# 读取cgi输入字符串if [[ $QUERY_STRING ]]; then query=$QUERY_STRINGelse read -r queryfi# 在bash中,变量名称限制为ASCII字母数字和下划线# 进行变量名称的净化处理sanitize() { local LC_ALL=C # 仅考虑ASCII字母 printf %s "${1//[![:alnum:]_]/_}"}# 查询字符串类似于 name=Fred+Flintstone&city=Bedrock# 将其视为使用 & 连接的 key=value 表达式列表。# 遍历列表并执行每个赋值操作。while IFS='=' read -r -d '&' var value; do # 为确保生成的变量名有效,在前面加上 "get_", # 并将任何无效字符替换为下划线。 # 1foo-bar => get_1foo_bar var=$(sanitize "get_$var") value=${value//\\/\\\\} value=${value//+/ } value=${value//'%'/\\x} printf -v "$var" %b "$value"done <<< "$query&"# 现在你可以使用 "get_name" 变量进行后续操作。# 如果我们需要键列表,则为 "${!get_@}"。

上述代码中的注释解释了如何从CGI输入字符串中提取查询参数,并将其存储在以get_为前缀的变量中。在处理变量名称时,使用sanitize()​函数对其进行净化处理,将无效字符替换为下划线。在对查询参数进行解码时,将转义字符进行转义,将加号替换为空格,将百分号转换为\x,并使用printf %b​将其转换为特殊字符。最后,可以使用以get_​为前缀的变量进行后续操作,或者使用${!get_@}​获取以get_​为前缀的变量的键列表。

虽然这可能不太清晰,但它避免了eval存在的巨大安全问题:执行用户可能输入到网络表单中的任意命令。显然,这是一个改进。

错误的方式

# 不要这样做!## 读取cgi输入字符串if [ "$QUERY_STRING" ]; then query=$QUERY_STRINGelse read queryfi# 对编码字符串进行一些转换,比如 "&"(留给读者作为练习)# 在字符串上运行 eval 命令eval "$query"# 坐下来,发现用户在 Web 表单字段中输入了 "/bin/rm -rf /" 等命令,即使不是管理员也会破坏文件系统的某些部分。# 另一个危险的字符串可能是一个fork bomb(分叉炸弹)。

上述代码中的注释解释了在CGI脚本中不要使用eval​执行字符串。使用eval​可以执行任意的代码,这可能导致安全漏洞,因为用户可以通过Web表单将任意代码注入脚本中,从而破坏系统或获取敏感信息。因此,应该避免使用eval​命令,而是使用其他安全的方法来处理CGI输入字符串,例如在先前的示例中使用的循环和字符串处理函数。

如何编写接受shell中参数的CGI脚本?

这个例子还在这个页面上的唯一原因是每当我们删除不好的例子时,总会有人重新编写。所以,这是你的不良示例,而且还有多层警告不要使用它。

用户评论

情字何解ヘ

学习了这篇文章后,我尝试通过Shell编写了一个简单的CGI程序,输入参数非常灵活。

    有9位网友表示赞同!

残花为谁悲丶

遵循指南的步骤,我成功地创建了一个可处理环境变量的脚本来处理GET请求数据。

    有19位网友表示赞同!

玩味

通过实践和修改文章中的示例代码,我对如何在Shell中实现CGI脚本有了更深的理解。

    有8位网友表示赞同!

一别经年

这个教程让我了解到Shell编程在Web开发中也可以很强大,尤其是用于构建基于文本的web服务。

    有9位网友表示赞同!

断秋风

遵循作者的引导步骤,编写一个可接收GET参数的Shell CGIs脚本变得简单明了,效率高。

    有18位网友表示赞同!

岁岁年年

我发现学习如何用Shell创建CGI脚本能够极大地减轻服务器的负担,特别是对于低资源环境。

    有16位网友表示赞同!

一个人的荒凉

感谢这篇教程,它让我熟悉了处理HTTP请求,并对如何在终端环境中响应用户交互有了新视角。

    有17位网友表示赞同!

良人凉人

成功编译并运行后,我为自己能够通过Shell构建实用的Web应用工具而感到自豪。

    有15位网友表示赞同!

残留の笑颜

阅读文章前预想会有技术难题,实际操作却发现步骤清晰、难点明确,让我容易上手。

    有7位网友表示赞同!

逃避

这篇文章是我在Linux系统中寻找CGI解决方案时最理想的起点之一。

    有10位网友表示赞同!

孤岛晴空

从零到一构建自己的CGIs脚本让我对Shell命令有了全新的认识,真是知识的升级!

    有11位网友表示赞同!

笑傲苍穹

实践过后我深刻理解了如何在脚本中处理URL查询参数和环境变量,功能强大。

    有20位网友表示赞同!

咆哮

通过详细的注释和示例代码,我很轻松地掌握了Shell CGi编程技巧,实操性很强。

    有20位网友表示赞同!

无寒

这次尝试编写 Shell CGI 脚本让我认识到文本编辑器的威力,代码简洁直观。

    有14位网友表示赞同!

屌国女农

文章中的实例使我能够立刻构建功能丰富的Web服务端脚本,满足用户基本需求。

    有7位网友表示赞同!

西瓜贩子

在实施自己的CGi脚本后,我意识到Shell编程具有很强的交互性和实用性。

    有8位网友表示赞同!

熏染

根据教程指导,我能高效地将简单逻辑应用到更复杂的CGi实现中,真是受益匪浅。

    有12位网友表示赞同!

墨染天下

这次实践让我理解了通过shell来处理web请求的本质和步骤,提升了技术水平。

    有8位网友表示赞同!

服从

在使用Shell编写CGi脚本过程中,我学习到了如何利用标准输入输出进行数据交互,实用性很强。

    有15位网友表示赞同!

相关推荐

签证在手 旅途无忧