如何在bash中获取文件(例如gist)?

3
我想在我的bash shell中引用一个gist,如何在一行命令中完成?换句话说,我不想创建一个中间文件。
我尝试过以下命令,但无法成功引用远程文件:
source <(curl -s -L https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash)

运行在Mac OSX 10.9上。

提前致谢。


3
你列出的命令对我有效。你是否尝试过仅运行curl命令以确保你可以适当地下载文件? - Brian Campbell
1
是的,curl 可以工作,那个命令也可以正常运行。但是,在你运行它之后,你真的有 git 自动补全吗?如果在执行该命令后运行 type __git_complete,你会看到什么?假设你还没有加载 git 自动补全。 - Mike D
是的,当我尝试时,我一直在使用Linux和OS X上的Bash 4。我已经添加了一个答案,为您提供了几个选项。 - Brian Campbell
3个回答

2

苹果公司发货的Bash版本是古老的Bash 3.2,而Bash 4已经发布了5年。以下是一些可能的解决方法:

  1. Install MacPorts, Homebrew, or pkgsrc and install Bash via one of them; or just build and install it yourself from source. Remember to add your newly installed bash to /etc/shells so you can set it as your shell, then go to "System Preferences > Users and Groups", click the lock to supply your password so you can make changes, then right click (two-finger click/control click) on your user to choose "Advanced Options..." and change your shell there.
  2. If you must be compatible with the 7 year old Bash shipped on OS X, you could just save the file and source it from there. Here's an example Bash function to make that easier:

    function curlsource() {
        f=$(mktemp -t curlsource)
        curl -o "$f" -s -L "$1"
        source "$f"
        rm -f "$f"
    }
    curlsource https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
    
  3. If you absolutely must avoid even creating a temporary file, and must run on ancient versions of Bash, the best you can do is read into a string and eval the result. I tried to emulate the effect of source <(cmd) by creating a FIFO (named pipe), piping the output of cmd into it, and reading it with source, but got nothing. It turns out, taking a look at the source for Bash 3.2, source simply reads the whole file into a string, and it checks the file size before doing so. A FIFO returns a size of 0 when you stat it, so source happily allocates a string of length 1 (for the trailing null), reads 0 bytes into it, and returns success. So, since source is just reading the whole file into a string and then evaluating that, you can just do the same:

    eval "$(curl -s -L https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash)"
    

我对我的一些服务器使用旧的东西,但 eval 的效果很好。谢谢 Brian。 - Mike D
@MikeD 是的,我想你可能不能更新,所以决定给出几个不同的选项。我很久以前就在我的 Mac 上完成了第二步,以至于我已经忘记我做过了,这就是为什么我发布了最初的“对我有效”的评论。很高兴能帮助! - Brian Campbell

1

目前 OS X 默认仍然使用 bash 3.2;在这个版本中,source 命令似乎不能正确地处理进程替换,可以通过简单的测试来证明:

$ source <(echo FOO=5)
$ echo $FOO

$

然而,相同的source命令在bash 4.1或更高版本中可以正常工作(我没有4.0版本进行测试,发布说明似乎对此问题保持沉默)。


你可以通过source <(echo'echo $BASH_SOURCE')查看脚本的来源。我不确定它是否在所有情况下都使用临时文件,在FreeBSD9上的bash 4.3.24打印的是 /tmp//sh-np-425112718(即使挂载了/dev/fd)。 - eckes
这是很好的信息。我刚在运行bash4.1的CentOS6.5上测试了你的代码和我的代码,它们都可以工作。不过还需要一些适用于bash3.2的东西,但还是谢谢你。 - Mike D

-2

此方法适用于任何版本的Bash,且无需创建任何文件。

source <<< "$(curl -s -L https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash)"

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