如何在Node.js中获取process.argv的原始字节而非UTF-8解码内容?
在Node.js中获取命令行参数的原始字节(绕过UTF-8解码)
问题背景
当向Node.js传入非UTF-8有效字节并尝试从process.argv读取时,会得到替换字符U+FFFD。示例如下:
$ node -e "console.log(process.argv[1].codePointAt(0).toString(16))" $'\x7f' 7f $ node -e "console.log(process.argv[1].codePointAt(0).toString(16))" $'\x80' fffd
而C语言实现的命令行工具则能直接获取原始字节:
$ echo -n $'\x7f' | xxd 00000000: 7f . $ echo -n $'\x80' | xxd 00000000: 80 .
问题:有没有办法在Node.js中获取传入程序的参数原始字节,而不经过UTF-8解码?
解决方案
Node.js的process.argv会将命令行参数自动解码为UTF-8字符串,因此无法直接从中获取原始字节。但可以通过以下方式实现需求:
1. 类Unix系统下读取/proc/self/cmdline(稳定方案)
在Linux、BSD等类Unix系统中,/proc/self/cmdline文件以null字节分隔的形式存储了进程的原始命令行参数序列。可以读取该文件并解析:
const fs = require('fs'); // 以binary编码读取,保留原始字节 const cmdlineContent = fs.readFileSync('/proc/self/cmdline', 'binary'); // 按null字节分割得到原始参数列表(第一个元素是Node.js可执行文件路径) const rawArgs = cmdlineContent.split('\0').filter(arg => arg.length > 0); // 取传入的第一个自定义参数(示例中为$'\x80') const targetArg = rawArgs[2]; // 将二进制字符串转为Buffer,即可操作原始字节 const argBuffer = Buffer.from(targetArg, 'binary'); console.log(argBuffer.toString('hex')); // 输出80
测试命令:
$ node get-raw-arg.js $'\x80' 80
2. 使用Node.js内部API(非稳定,不推荐生产环境)
Node.js提供了未公开的内部API process.getArgv(),它返回一个Buffer数组,每个元素对应一个命令行参数的原始字节:
// 注意:此API为内部实现,不同Node.js版本可能存在变化或移除 const rawArgBuffers = process.getArgv(); // rawArgBuffers[0]是Node.js可执行文件路径,rawArgBuffers[1]是脚本路径,rawArgBuffers[2]是传入的自定义参数 console.log(rawArgBuffers[2].toString('hex')); // 输出80
测试命令:
$ node -e "console.log(process.getArgv()[2].toString('hex'))" $'\x80' 80
Windows系统下的替代方案
Windows没有/proc文件系统,可以通过调用系统命令wmic获取进程命令行,解析wmic process where processid=%PID% get commandline的输出并提取原始字节,需注意Windows对命令行参数的编码处理逻辑。
内容的提问来源于stack exchange,提问作者user3064538
相关产品推荐
相关产品推荐

