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

通过管道将wget输出传入sh执行时的换行符问题

问题

我尝试用wget下载Bash脚本并通过管道传给sh执行时遇到了问题:

  • 分步骤执行(先下载脚本到本地再运行)完全正常
  • 管道执行时脚本解析GitHub API返回的JSON失败,提示「无效字符串(控制字符未转义)」——JSON里的换行符直接显示成了实际换行;但本地保存后执行时,JSON里的换行符以\n转义形式存在,解析正常

执行的管道命令:

wget -q --no-cache https://gist.githubusercontent.com/devklick/be9cbe0b384958a7e7ce115f7df25e5a/raw/27153ef3109e7561e45f0fe43e9a10276da78252/install.sh -O - | sh -s linux

涉及的Bash脚本内容:

#!/bin/bash

target_os=$1
echo "Target OS '$target_os'"

zip_path="$HOME/Downloads/gdman.zip"
echo "Asset download path '$zip_path'"

install_dir="$HOME/gdman"
echo "App install path '$zip_path'"

# Download the latest release information from GitHub API
echo "Finding latest version"
response=$(curl -s https://api.github.com/repos/devklick/GDMan/releases/latest)
echo $response

# Extract the browser download URL for the asset
download_url=$(echo "$response" | jq -r '.assets[] | select(.name | test("'${target_os}'")) | .browser_download_url')
echo "Found download '$download_url'"

原因分析

问题核心是执行脚本的Shell环境差异:

  • 本地执行时,脚本开头的#!/bin/bash指定用Bash运行,Bash的echo默认不会解析字符串中的转义序列(比如\n),JSON里的转义换行符会以\n形式保留,jq能正常解析。
  • 管道执行时用的是sh -s,这里的sh通常是POSIX兼容的Shell(比如Dash),它的echo会自动解析转义序列,把JSON里的\n转换成实际换行符,直接破坏JSON结构;再加上脚本里echo $response未加双引号,Shell会对变量内容做分词处理,进一步打乱JSON格式,最终导致jq报错。

解决方法

无需保存脚本到本地,通过以下两种方式即可解决:

1. 强制用Bash执行脚本

把管道命令里的sh改成bash,确保脚本用Bash运行,避免POSIX Shell的echo解析转义序列:

wget -q --no-cache https://gist.githubusercontent.com/devklick/be9cbe0b384958a7e7ce115f7df25e5a/raw/27153ef3109e7561e45f0fe43e9a10276da78252/install.sh -O - | bash -s linux

2. 修改脚本代码兼容多Shell

如果无法修改执行的Shell,可以调整脚本里的输出逻辑,让行为在不同Shell下保持一致:

  • 给echo的变量加上双引号,避免分词破坏JSON结构:echo "$response"
  • 用printf替代echo,printf在不同Shell里的行为更统一,不会自动解析转义序列:printf "%s\n" "$response"

修改后的关键代码片段:

# Download the latest release information from GitHub API
echo "Finding latest version"
response=$(curl -s https://api.github.com/repos/devklick/GDMan/releases/latest)
printf "%s\n" "$response"  # 替换原来的echo $response

# Extract the browser download URL for the asset
download_url=$(echo "$response" | jq -r '.assets[] | select(.name | test("'${target_os}'")) | .browser_download_url')

(注:脚本里还有一处小错误:echo "App install path '$zip_path'"应该改为$install_dir,不过这和当前JSON解析问题无关)


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:25:37