我正在尝试将以下内容从bash转换为PowerShell:
url="https://api.adoptium.net/v3/binary/latest/19/ga/linux/x64/jdk/hotspot/normal/eclipse"
fetch_url=$( curl -s -w %{redirect_url} "${url}" )
fname=$( curl -OLs -w %{filename_effective} "${fetch_url}" )
使用bash执行上面的命令会将$fetch_url
设置为https://github.com/adoptium/temurin19-binaries/releases/download/jdk-19.0.2+7/OpenJDK19U-jdk_x64_linux_hotspot_19.0.2_7.tar.gz
,或者如果没有可用的URL,则设置为{"errorMessage":"No releases match the request"}
,并且命令返回一个非“0”的返回代码。
执行下一行$fname
将是OpenJDK19U-jdk_x64_linux_hotspot_19.0.2_7.tar.gz
。文件将下载到此名称,因为curl
是用-OLs
调用的。(-O
:输出到url中找到的名称;-L
:遵循重定向;-s
:无声;-w %{filename_effective}
:选择要在stdout上报告的结果文件名)。$fname
然后保存此文件名以供以后使用。
你知道如何用Invoke-WebRequest
实现同样的效果吗?对于给定的URL,它只返回
> Invoke-WebRequest -uri "https://api.adoptium.net/v3/binary/latest/19/ga/linux/x64/jdk/hotspot/normal/eclipse"
StatusCode : 200
StatusDescription : OK
Content : {31, 139, 8, 0…}
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
ETag: "0x8DAFB9194B2EB0B"
Server: Windows-Azure-Blob/1.0
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: a6f360ad-e01e-004e-7f8b-470ced000000
x-ms-version: …
Headers : {[Connection, System.String[]], [ETag, System.String[]], [Server, System.String[]], [x-ms-request-id, System.String[]]…}
RawContentLength : 200079543
RelationLink : {}
似乎没有办法像curl那样找到真实的的下载URL和文件名。我试过($curl
设置为C:\cygwin\bin\curl.exe
):
$fetch_url = &$curl -s -w %{redirect_url} "$api_url"
而不是使用Invoke-WebRequest
。但是这会导致服务器请求身份验证--这不是预期的。有什么想法可以让其中一个按预期工作吗?
2条答案
按热度按时间juzqafwq1#
有点黑客的味道,想看看有没有更好的方法
mqxuamgl2#
值得注意的是,现代Windows版本现在提供了
curl.exe
,因此您可以简单地将Bash脚本转换为PowerShell:注:
curl.exe
,即包含文件扩展名,以便绕过指向Invoke-WebRequest
的内置curl
* 别名 *-此问题已在PowerShell (Core) 7+中修复。%{…}
参数包含在'…'
中,因为{
和}
在PowerShell中是 * 元字符 *(它们包含script-block文本{…}
)使用
Invoke-WebRequest
可以实现您的任务,但它更麻烦:Invoke-WebRequest
**调用需要额外的工作:302
HTTP状态代码表示重定向,现在默认情况下被视为(语句终止)error,必须使用-SkipHttpErrorCheck
抑制该代码才能返回头数据。-SkipHttpErrorCheck
,也会发出一个非终止错误,声明The maximum redirection count has been exceeded [...]
,可以使用-ErrorAction Ignore
将其静音。[string[]]
类型的。假定只有 * 一个 * 重定向URL存在,简单地访问元素[0]
就足够了。Invoke-WebRequest
调用替换为以下内容:后退一步
Content-Disposition
标头**,其中包含 * 建议的下载文件名*:-O
(--remote-name
选项与-J
(--remote-header-name
)组合使用,可以让curl
使用此文件名curl
man
页面包含关于-J
的 * 警告:请谨慎使用此选项,尤其是在Windows上。恶意服务器可能会向您发送Windows或某些第三方软件可以自动加载的DLL或其他文件的名称。
如果您想利用
curl
的-J
选项,您的代码可以简化为:注:
Invoke-WebRequest
* 不 * 支持遵循Content-Disposition
字段。curl
的-O
):文件名必须 * 显式地 * 传递给-OutFile
参数:-OutFile
的 * 目录 * 路径的能力,文件名由URL的最后一段暗示,尽管是 * 重定向到 * URL(不像curl
的-O
与-L
组合时所做的那样)