Bash脚本中echo "$d"无输出问题排查求助
我帮你梳理下脚本里导致echo "$d"无输出的核心问题,以及对应的修复方案:
1. 最关键的错误:没读取文件内容,只存了文件名
你现在的t=$fil只是把文件名ciphertext.gz赋值给了变量t,后续循环遍历的是文件名的字符(比如c、i、p这些),而不是ciphertext.gz里的加密内容。这直接导致后续的字符替换逻辑根本没处理目标文件,d自然没有有效内容。
修复方式:用命令替换读取文件内容,如果是压缩文件,要先解压再读:
# 如果是未压缩的文本文件,用这个: t=$(< "$fil") # 如果是gzip压缩文件,先解压读取: t=$(gunzip -c "$fil")
2. 字母表变量a缺了字母W
你定义的a="ABCDEFGHIJKLMNOPQRSTUVXYZ"里漏掉了字母W,这会导致如果文件内容或密钥里出现W/w,后续无法在字母表中匹配到对应字符,计算索引时出错,最终d无法正确拼接。
修复:补全完整的大写字母表:
a="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3. 密钥转换的tr命令有漏洞
你写的k=$(echo "$k" | tr [a-vx-z] [A-VX-Z] )漏掉了w/W的转换,输入的w/w会保留小写,而字母表a全是大写,匹配不到就会导致索引计算异常。直接改成全小写转大写更稳妥:
# 方法1:用tr命令 k=$(echo "$k" | tr '[a-z]' '[A-Z]') # 方法2:用bash内置的大小写转换,更高效 k=${k^^}
4. m变量的重复赋值覆盖了参数逻辑
脚本里先写了m=${1:+-}(意思是如果传入命令行参数,m设为-),但紧接着又写了m=-,这会直接覆盖之前的参数判断,不管有没有传-d,m都是-,如果原本是靠m区分加密/解密逻辑,这部分功能就失效了。
修复:删掉重复的m=-,保留参数判断:
m=${1:+-}
5. 确保d的拼接逻辑完整
你给出的代码里d="${...}是截断的,这里给你补全完整的替换逻辑(假设是类似凯撒密码的字符偏移替换):
for ((i=0;i<${#t};i++)); do # 取出当前文本的单个字符 char_t=${t:$i:1} # 计算该字符在字母表中的索引 p1=${a%%$char_t*} idx_t=${#p1} # 如果字符不在字母表中(比如符号、数字),直接保留到d if [[ $idx_t -eq ${#a} ]]; then d+="$char_t" continue fi # 取出密钥对应位置的字符(循环使用密钥) char_k=${k:$((i%${#k})):1} p2=${a%%$char_k*} idx_k=${#p2} # 根据m的值计算新索引(加密是+,解密是-) idx_new=$(( (idx_t $m idx_k) % ${#a} )) # 处理解密时可能出现的负数索引 if [[ $idx_new -lt 0 ]]; then idx_new=$(( idx_new + ${#a} )) fi # 把新字符拼接到d中 d+="${a:$idx_new:1}" done
把这些修复点整合后,再执行echo "$d"应该就能输出处理后的内容了。如果还是有问题,可以检查下ciphertext.gz是否确实有有效文本内容,避免是空文件或者非文本的二进制压缩包。
内容的提问来源于stack exchange,提问作者Pod

