如何使用命令行从私有GitHub仓库下载单个原始文件?

124

在CI服务器上,我想获取我们在Github上维护的配置文件,以便它可以在许多作业之间共享。 我正在尝试通过curl获取此文件,但以下两种方法都失败了(我收到了404错误):

# As advised by the oAuth docs
curl -H 'Authorization: token the_token' -L -o setup.sh https://raw.github.com/org/repo/file

# The url of the raw file after clicking to view it
curl -L https://raw.github.com/org/repo/file?login=username&token=the_token 
20个回答

169

之前的答案不起作用(或者已经失效了)。

你可以使用V3 API获取原始文件,像这样(你需要一个OAuth令牌):

curl -H 'Authorization: token INSERTACCESSTOKENHERE' \
  -H 'Accept: application/vnd.github.v3.raw' \
  -O \
  -L https://api.github.com/repos/owner/repo/contents/path

所有内容都必须在一行上。 -O 选项将文件保存在当前目录中。您可以使用 -o filename 来指定不同的文件名。

要获取OAuth令牌,请按照此处的说明操作:

我也将这个过程写成了一个Gist:

编辑:解决方案的API参考如下:


4
请注意,如果文件是公开的,则无需授权令牌:curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/owner/repo/contents/path将返回原始文件。 - Alf Eaton
2
@NickChammas:没有那个头文件,我会得到一个JSON响应,其中包含元数据和实际文件内容的base64编码,而不是纯文本文件。 - c24w
如果上述命令出现错误,如curl:(56)代理连接中止,那是什么意思? - Max
4
请注意,此 URL 与您在浏览器中使用的 URL 不同。 我在这里突出显示了差异:https://``api.``github.com/``repos/``<owner>/<repo>/``contents/``<path/to/file>(抱歉有些凌乱) - PJSCopeland
5
这也适用于个人访问令牌。所需的最小权限集合为 repoadmin:org / read:org(在私有存储库上)。 - rlat
显示剩余7条评论

50

或者,您可以使用GitHub的“个人访问令牌” (https://github.com/settings/tokens):

TOKEN=...
curl -s https://$TOKEN@raw.githubusercontent.com/<user or organization>/<repo name>/<branch>/<path to file>/<file_name>

示例:

$ curl -s https://1bacnotmyrealtoken123beefbea@raw.githubusercontent.com/concourse/concourse/master/README.md
....

1
@EM0 -- 我刚试了一下,可以用。有几个值得再确认的地方:1. 主机部分是 raw.githubusercontent.com,2. 路径是 <用户名>/<仓库名称>/<分支>/<文件名>,3. 令牌需要具有 repo 访问范围。 - theartofrain
1
是的,那就是路径。我从文件的“下载”链接中获取了路径,但删掉了结尾处的“?token=…”并添加了令牌。它确实具有仓库访问范围,但这只涉及公共存储库。这是一个组织私人存储库。此外,我们启用了双重身份验证,但我认为如果出现问题,它应该显示错误401而不是404。 - EM0
是的,这听起来都是正确的。路径听起来不错(这就是我在单击“原始”时获取的路径,去掉了?token=...参数,就像你说的那样)。我的用户也有双重身份验证,我假设我们正在谈论相同的令牌范围(https://github.com/settings/tokens/new上的“repo”复选框)。值得一提的是,如果令牌无效或没有“repo”范围,您将收到404(而不是401)。不确定为什么在您的设置中无法正常工作... - theartofrain
7
奇怪的事情:对我来说,使用上面的curl命令是有效的,但如果我在浏览器中打开同样的链接或尝试通过java.net.URL.openStream请求它,我会得到一个404错误。 - Nightscape
2
这是我在CMD中为内部GitHub实例使其工作的唯一方法。使用curl -H 'Authorization: token $TOKEN' $file_url总是404错误。我不确定为什么其中一个有效而另一个无效,但我从未深入研究过CURL的文档。 - kayleeFrye_onDeck
显示剩余3条评论

22

我知道这是一个老问题,但上面提出的解决方案都对我没有用。也许API从那时起已经改变了。

这个命令可以正常工作:

curl -H 'Authorization: token [在此处插入您的令牌]' -o output.txt https://raw.githubusercontent.com/[组织]/[存储库]/[分支]/[文件路径]


这是唯一能为我工作的方法,但你的回答中有一个小错误。应该是[organization]/[repo]/[branch]... - fIwJlxSzApHEZIl
谢谢,这是我在Github企业版中唯一有效的方法。请注意,所需的令牌是个人访问令牌。 - Oliver Pearmain
@OliverPearmain,你有没有尝试过curl -s https://PAT_VALUE@raw.github.company.com/OrgOrUser/RepoName/BranchOrCommitID/file_name.file_extension?这是我能够让它工作的唯一方法,但公司里其他人使用了这个解决方案,所以我想可能有一些CURL配置可以使其更容易使用curl -s...而不是这组CLI参数。 - kayleeFrye_onDeck

14
使用官方GitHub CLI gh是一个更简单的解决方案。
  1. 首先,您必须登录:
gh auth login

对我来说,这个命令是不必要的,因为我已经登录了。
然后我们需要API URL来定位要下载的文件。并调用gh来下载它:
API_URL=https://api.github.com/repos/owner/repo/contents/path/file.ext
gh api $API_URL -H "Accept: application/vnd.github.raw" > file.ext

一个真实的例子可能更好。在这里可以下载install_linux.md,使用gh命令行工具:
API_URL=https://api.github.com/repos/cli/cli/contents/docs/install_linux.md
gh api $API_URL -H "Accept: application/vnd.github.raw" > install_linux.md

API_URL中:
  • 用户ownercli
  • 仓库名称repo也是cli
  • 文件路径(path/file.ext)是docs/install_linux.md

3
为了避免安装 jq,你可以选择传递选项:curl $(gh api $API_URL --jq .download_url) -o file.ext。该命令用于下载文件,并将API返回的 "download_url" 字段中的URL作为参数传递给 curl 命令。 - Bertrand P
@BertrandPestre 感谢你的技巧。这是一个非常新的选项:8天前! - Jean-Pierre Matsumoto
可以通过在 gh 命令中添加 -H "Accept: application/vnd.github.raw" 参数来简化为单个 gh 调用。这将告诉 API 返回文件内容而不是元数据。 - wheeler
@wheeler 很棒!我已经更新了我的回答。 - Jean-Pierre Matsumoto

8
或者,如果您没有令牌:
curl --user [your_user] 'https://raw.github.com/path/to/file.config' > file.config

它会要求您输入密码。

更新: 对于那些遇到404错误的人,您可能需要为您的计算机创建一个SSH密钥。请参考您设置中的SSH和GPG密钥。

如果您点击相应文件上方右上角的按钮(在您想要下载的文件上点击后可用),这将起作用。复制该原始资源的URL。如果您尝试下载的资源不是通过raw.github.com(可能已更改为raw.githubusercontent.com)托管的,它将无法工作。

我成功地使用此方法在2023年7月14日使用macOS从个人仓库和非个人仓库下载了资源。


3
我被要求输入密码,但是响应总是404。 - Jean Jordaan
1
同样的问题:始终404。 - André Luís
似乎不再起作用了 - A. Khaled
我在想,将一个SSH/GPG密钥与您的计算机关联是否能解决这个问题。它会要求您输入密码。我在macOS上成功地使用这种方法从个人仓库和非个人仓库下载了文件。 - PeqNP

8

我曾经也为此苦恼了几分钟,直到我意识到只需要用引号将URL包起来以转义"&"符号。

curl "https://raw.github.com/org/repo/file?login=username&token=the_token"

这在我的私有仓库中起作用。


1
不行,它会返回“错误404:未找到”。 - David Espinosa

6

我已经获得了一个应用程序安装的令牌。

以前,您可以使用查询?access_token=MY_TOKEN,但这在2021年9月之后被弃用并最终删除

在他们的文档中:使用GitHub应用程序进行身份验证,他们说您可以使用访问令牌和用户名x-access-token来克隆存储库URL。

这似乎也适用于下载原始文件(ghs_...是令牌):

$> curl "https://x-access-token:ghs_4qgGKx4skAcaF3bAb3scrTkN4@raw.githubusercontent.com/Octocat/codertocat/main/README.md"

1
试过了,能用。 (感谢这个最近的答案!) - Anton Antonov
谢谢您的回复。确实,可以使用提到的方法直接访问文件。 - Jordan Borisov
这个已经不起作用了,我得到了一个404错误页面,有其他人可以确认吗? - Kay
@Kay,它有效。确保使用curl和域名为raw.githubusercontent.com,路径不包含/ blob。 - undefined
1
这个已经不再起作用了。响应中出现错误:已弃用的身份验证方法。创建个人访问令牌以访问:https://github.com/settings/tokens - undefined

3

我成功地让它在Github企业版上工作了,感谢以上的建议。必须采取你提供的所有建议并最终尝试,我才能让它工作。这是我采取的步骤:

  1. 创建个人token,按照以下步骤执行:

https://docs.github.com/cn/github/authenticating-to-github/creating-a-personal-access-token

  1. 确保您对令牌具有最少的以下权限:

    • repo (在repo下选择全部)
    • admin:org -> read:org (在“admin:org”下选择“read:org”) enter image description here
  2. 使用以下curl命令获取内容:

curl -H "Authorization: token [yourPersonalToken]" -H "Accept: application/vnd.github.v3.raw" -o [filePath]-content.json -L https://github.[company].com/api/v3/repos/[ORG]/[REPO_NAME]/contents/[PATH_TO_FILE]/content.json?ref=[BRANCH_NAME]

目标->

 [yourPersonalToken] is the token you created.
 [filePath] is a path where you want to save the downloaded copy.
 [company] is the name of company which hosted the github enterprise.
 [ORG] is the github organization is which repo is created.
 [REPO_NAME] is the name of the repository.
 [PATH_TO_FILE] is the path where file is located.
 [BRANCH_NAME] is the name of the branch you want to use, e.g. master, develop etc.

例子:

curl -H "Authorization: token 5a86ecda9ff927baaa66fad2af5bee8" -H "Accept: application/vnd.github.v3.raw" -o C:\Downloads\manifest.json -L https://github.example.com/api/v3/repos/cms/cms_one/contents/app/data/manifest.json?ref=master

今天起,此API可下载小于1 MB的文件。如果需要下载大文件,请使用此方法:https://caludio.medium.com/how-to-download-large-files-from-github-4863a2dbba3b - Happy

3
  1. 在浏览器中打开你的Github仓库: 点击文件
  2. 在浏览器中打开开发者工具: 选择网络选项卡
  3. 在浏览器中的Github页面: 点击下载按钮
  4. 关闭弹出窗口
  5. 在浏览器的开发者工具中: 右键单击列表上的 file_name?token=ABAHQCAT6KG...
  6. 选择复制 -> 复制链接地址

    链接的格式为:

    https://raw.githubusercontent.com/<USERNAME>/<PATH>/<FILENAME>?token=ABAHQCAT6KGHYHMG2SLCDT243PH4I

  7. 在终端中:

    wget -O myFilename https://raw.githubusercontent.com/<USERNAME>/<PATH>/<FILENAME>?token=ABAHQCAT6KGHYHMG2SLCDT243PH4I

链接仅在有限时间内有效,或者你可以创建自己的Token: GitHub文章


2
curl -H 'Authorization: token YOUR_TOKEN' \
  -H 'Accept: application/vnd.github.v4.raw' \
  -O \
  -L https://api.github.com/repos/INSERT_OWNER_HERE/INSERT_REPO_HERE/contents/PATH/TO/FILE

所以,如果原始文件的URL(登录后)为:
https://raw.githubusercontent.com/mr_coder/my_repo_name/master/my_script


Then 
  -L https://api.github.com/repos/INSERT_OWNER_HERE/INSERT_REPO_HERE/contents/PATH/TO/FILE
becomes
  -L https://api.github.com/repos/mr_coder/my_repo_name/contents/my_script

注意:我们有API v4。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接