You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache服务器下Bash CGI脚本文件上传失败问题求助

Apache下Bash CGI脚本文件上传失败问题

问题背景

处理文件传输的POST请求时,Apache服务器上的Bash CGI脚本无法完成文件上传。定位到/dev/stdin未正常输出二进制流,使用轻量级CMS Lichen时也出现该问题。以下是简化后的错误场景及排查过程。

简化场景

HTML上传表单

<form action="http://guestserver/cgi-bin/upload.cgi" method="post" enctype="multipart/form-data">
    <p><input type="file" name="filename" id="file"></p>
    <p><input type="submit" value="Upload"></p>
</form>

CGI脚本(upload.cgi)

#!/bin/sh

#  Exit immediately if a command exits with a non-zero status.
set -e

# replace spaces with underscores
#   which is done by tr "thisGetsReplaced" "byThis" ;
#   -s means squeeze repeated occurence
#   echo $PATH_INFO | 
#   gets filename and passes output to next (by '|')
sanitized=$(echo $PATH_INFO | tr -s ' ' '_')

# move one dir up and look if file exists there
if [ -f ..$sanitized ]; then
    cat /dev/stdin > /dev/null
    echo 'Status: 409 Conflict'
    echo 'Content-Type: text/plain'
    echo ''
    echo 'File already exists.'
    exit 0
fi

# Actual file write
mkdir -p ..$(dirname $sanitized)
cat /dev/stdin > ..$sanitized # line that throws error

# I guess if file write at this point was successful 
#        it exits with something non-zero
#        so the script is STOPPED
echo 'Status: 204 No Content'
echo "X-File-Name: $(basename $sanitized)"
echo "X-File-Path: $(dirname $sanitized)"
echo ''

发现$PATH_INFO不包含上传文件名,导致上传失败。生产环境中虽能创建正确文件名,但文件为空,疑惑该现象的原因。

测试验证

编写test.cgi验证数据传输及PATH_INFO为空的问题:

#!/bin/sh

echo "Content-Type: text/html"
echo "<html><head></head><body>"

echo SERVER_SOFTWARE = $SERVER_SOFTWARE
echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE
echo SERVER_PROTOCOL = $SERVER_PROTOCOL
echo SERVER_PORT = $SERVER_PORT
echo REQUEST_METHOD = $REQUEST_METHOD
echo HTTP_ACCEPT = $HTTP_ACCEPT
echo PATH_INFO = $PATH_INFO

dd count=1 bs=$CONTENT_LENGTH # prints file content

echo "</body></html>"

执行后输出:

SERVER_SOFTWARE = Apache/2.4.55 (Unix)
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.1
SERVER_PORT = 80
REQUEST_METHOD = POST
HTTP_ACCEPT =
PATH_INFO =
------WebKitFormBoundaryMNBsYvUe3DbH9tpE Content-Disposition: form-data; name="filename"; filename="uploaded file.jpg" Content-Type: image/jpeg ÿØÿàJFIFÿÛC %# , #&')*)-0-(0%()(ÿÀ,àÿÄÿÄ; !"#$312%4CB“5ADQRcdƒabe„”•ÿÚ?•ñ£Ö˜þFßE%ò}õ[/ì³è1Æ'¬YÇ­çªÙæÞõÑTÚuJn4îÝ)ÎV“¦­9îª ©“1í”»ge¢R…Z¿MÑŽ¼ÜÃÛ—d´¯±¦#ø4¦‚ðœDÐŽæ…c4û°e¥4ê×1žOO qu»Ö:ûïAB¬?ÙܶbZÎf³ª‹¹yçDÖÒáSªµù¦

最后一段为dd命令输出的文件内容(已截断),证明文件数据已传输,但未被服务器保存。

错误日志分析

Apache错误信息:Premature end of script headers: upload.cgi

/var/log/httpd/error_log日志:

dirname: missing operand
Try 'dirname --help' for more information.
/srv/http/cgi-bin/upload.cgi: line 20: ..: Is a directory
[Mon Mar 06 12:29:04.166828 2023] [cgid:error] [pid 297:tid 140340891719360] [client 192.168.56.1:63168] Premature end of script headers: upload.cgi, referer: http://localhost:5500/

错误指向脚本第19行mkdir -p ..$(dirname $sanitized),因$sanitized由空的$PATH_INFO生成,导致dirname缺少操作数执行失败。

需求:解决该问题,实现文件正确上传至服务器。


内容的提问来源于stack exchange,提问作者proto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:55:02