将 wget 传输到 sh - 换行问题

问题描述 投票:0回答:1

我正在尝试使用

wget
下载 bash 脚本并将其通过管道传输到
sh
,但我遇到了问题。它在单独的步骤中工作正常(wget 下载,然后执行),但在管道到 sh 时则不然。该脚本可以在 this gist 中找到,但为了方便起见,我会将其包含在这个问题的底部。

我正在运行以下命令:

  • 下载脚本
  • 通过管道将其传输到 sh
  • 传入一个参数
    linux
wget -q --no-cache https://gist.githubusercontent.com/devklick/be9cbe0b384958a7e7ce115f7df25e5a/raw/27153ef3109e7561e45f0fe43e9a10276da78252/install.sh -O - | sh -s linux

当我运行上面的代码时,脚本尝试解析从 Githubs REST API 返回的一些 JSON 失败。我们可以看到记录的最后几行如下所示:

GDMan/zipball/v1.3.1", "body": "## [1.3.1](https://github.com/devklick/GDMan/compare/v1.3.0...v1.3.1) (2024-05-07)


### Bug Fixes

* fixes [#15](https://github.com/devklick/GDMan/issues/15), --help is not a known command ([ddd78f2](https://github.com/devklick/GDMan/commit/ddd78f2a92da239bab9a08658b732d1460b19dc3))



" }
parse error: Invalid string: control characters from U+0000 through U+001F must be escaped at line 150, column 1
Found download ''

我猜这里显示的换行符就是问题所在。不过使用wget下载保存文件然后执行就不存在这个问题了:

wget -q --no-cache https://gist.githubusercontent.com/devklick/be9cbe0b384958a7e7ce115f7df25e5a/raw/27153ef3109e7561e45f0fe43e9a10276da78252/install.sh
chmod +x ./install.sh
./install.sh linux

单独运行这些步骤,我们可以看到最后几行输出看起来有点不同:

GDMan/zipball/v1.3.1", "body": "## [1.3.1](https://github.com/devklick/GDMan/compare/v1.3.0...v1.3.1) (2024-05-07)\n\n\n### Bug Fixes\n\n* fixes [#15](https://github.com/devklick/GDMan/issues/15), --help is not a known command ([ddd78f2](https://github.com/devklick/GDMan/commit/ddd78f2a92da239bab9a08658b732d1460b19dc3))\n\n\n\n" }
Found download 'https://github.com/devklick/GDMan/releases/download/v1.3.1/GDMan_v1.3.1_linux-x64.zip'

所以问题是;为什么我的脚本在写入文件系统时与写入内存时表现不同,如何修复此问题以解决 JSON 换行问题,而无需在运行脚本之前先保存脚本?

我知道我可以通过单独运行这些步骤但用

&&
链接它们来解决这个问题,但我现在已经投入到这个问题中,并且真的很想知道问题/解决方案是什么。

有问题的 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'";
bash shell pipe wget
1个回答
0
投票

发生这种情况是因为您在一种情况下使用

sh
(可能是
dash
),而在另一种情况下使用
bash
,并且
echo
不可在 shell 之间移植。

您的文件在 JSON 字符串中包含

\n\n
,每个字符串给出不同的结果:

$ bash -c 'echo "\n\n"'
\n\n
$ dash -c 'echo "\n\n"'
(blank line)
(blank line)

这是POSIX

除非省略 -n(作为第一个参数)和转义序列,否则不可能在所有 POSIX 系统中可移植地使用 echo。

如果您希望脚本跨多个 shell 运行,可以将

echo
替换为
printf
,或者直接从
curl
jq
进行管道传输。

© www.soinside.com 2019 - 2024. All rights reserved.