Perl中含&符号文件名在glob与qx()中异常的解决方法
问题解决与方案
一、带特殊字符文件名(如M&M.html)的异常处理
问题根源在两处:
- Perl调用脚本时,双引号包裹的文件名会被shell解析,
&这类特殊字符会触发shell后台命令逻辑,导致执行异常; - ksh脚本中用单引号包裹变量
'$symbol_file',阻止了变量展开,实际执行的是cat '$symbol_file'而非读取目标文件。
解决步骤:
修正ksh脚本:
替换原ksh代码:$symbol_file=$ARGV[0]; $file_content=qx(cat '$symbol_file');为:
symbol_file="$1" file_content=$(cat "$symbol_file")说明:
- ksh赋值时变量名前无需加
$; - 用
"$1"接收参数并加双引号,确保特殊字符被正确识别; - 用ksh标准的
$()做命令替换,替代非标准的qx()。
- ksh赋值时变量名前无需加
优化Perl的qx调用:
改用列表形式调用,跳过shell直接传递参数,彻底避免特殊字符解析问题:
将Perl中的:$qtr1=qx(./parse_qr_results.ksh "$file");改为:
$qtr1=qx(./parse_qr_results.ksh $file);列表形式下,Perl会把
$file作为独立参数传给脚本,不会经过shell解析。
二、使用inode作为参数传递的实现方案
glob无法直接获取inode,但可通过Perl的stat函数提取文件inode,再传给ksh脚本定位文件。
1. Perl端修改:
@all_files=glob("./report2/*html"); print "\nTotal files = $#all_files"; open(CONSOLIDATED,">/tmp/qtr_20230628.csv"); for my $file (@all_files) # 原代码中@filter2未定义,建议替换为@all_files或先完成过滤逻辑 { my $inode = (stat($file))[1]; # stat返回数组的第2个元素为inode编号 $qtr1=qx(./parse_qr_results.ksh $inode); print CONSOLIDATED "$qtr1"; }
2. ksh端修改:
inode="$1" # 根据inode在目标目录查找文件并读取内容 file_content=$(find ./report2 -inum "$inode" -type f -exec cat {} \;)
说明:
find的-inum参数匹配inode编号;-type f确保只匹配文件,排除目录;-exec cat {} \;直接读取匹配到的文件内容。
内容的提问来源于stack exchange,提问作者stack0114106
相关产品推荐
相关产品推荐

