Bash中$(command)执行kcadm命令产生多余换行的原因及解决
命令替换$(kcadm get users)未删除末尾换行的排查与解决
问题背景
按照Bash手册明确说明,$(command)形式的命令替换会丢弃command输出的所有末尾换行符,但执行output=$(kcadm get users)时,变量output却始终带有一个末尾换行符。尝试output=$(kcadm get users) > /dev/null 2>&1也无济于事——直接执行kcadm get users > /dev/null 2>&1可以完全抑制输出,说明输出本身是正常的stdout内容,但命令替换未按预期处理。
注:kcadm是调用Java程序生成JSON输出的Shell脚本别名。
补充说明:此问题核心并非“如何移除变量末尾换行”,而是排查命令替换未按手册定义删除末尾换行的成因,常规的换行移除方法不适用。
可能成因及排查步骤
1. 检查kcadm脚本的实际逻辑
首先通过type kcadm找到别名对应的实际脚本路径,查看脚本内容:
- 确认脚本是否在调用Java程序后添加了额外的输出操作(比如
echo、printf '\n'),这类操作会在JSON输出后插入额外换行,若脚本逻辑导致换行后还有其他字符,会让命令替换无法识别为“末尾换行”。 - 检查脚本是否对Java程序的输出做了额外处理(比如管道、重定向),可能意外引入了多余字符。
2. 分析输出的字节结构
直接查看kcadm get users的原始输出字节,确认末尾字符:
kcadm get users | od -c
对比命令替换后的变量内容:
output=$(kcadm get users) echo -n "$output" | od -c
如果原始输出末尾是\n但变量中仍保留,大概率是输出中\n前存在非换行空白字符(比如Windows风格换行的\r、空格、制表符),导致\n并非真正的末尾字符,命令替换只会删除连续的末尾纯换行符。
3. 验证Bash命令替换的基准行为
用简单命令验证Bash的默认逻辑,排除环境异常:
# 测试:输出单个换行,命令替换后应无内容 test_output=$(echo) echo -n "$test_output" | od -c # 无输出,说明末尾换行被正常删除 # 测试:输出内容加Windows风格换行 test_output=$(printf "hello\r\n") echo -n "$test_output" | od -c # 输出包含\r,说明\r导致\n未被识别为末尾换行
解决方法
针对Windows风格换行(\r\n)
如果是Java程序输出了\r\n,用tr删除多余的\r:
output=$(kcadm get users | tr -d '\r')
针对脚本额外输出
如果kcadm脚本在调用Java后添加了不必要的echo或换行语句,直接修改脚本移除多余操作。比如脚本中若存在:
java -jar kcadm.jar get users echo
就删掉echo这一行。
强制移除末尾换行
若仍无法定位成因,可手动强制清除变量末尾的换行:
output=$(kcadm get users) output=${output%$'\n'} # 移除末尾单个换行 # 或移除所有连续末尾换行 output=$(printf "%s" "$(kcadm get users)")
内容的提问来源于stack exchange,提问作者QF0
相关产品推荐
相关产品推荐

