如何让Fish Shell与gcloud命令行工具兼容?

30

有人成功地将 Fish shell 与谷歌的 gcloud 命令行工具配合使用过吗?我不是 Fish 脚本专家,但这是 gcloud 运行所需的两个文件(在 Fish 的 bash 模式下可以正常工作)。据我所知,Fish 不允许您从中获取 bash 文件,因此这些文件需要转换为 Fish 脚本。

path.bash

script_link="$( readlink "$BASH_SOURCE" )" || script_link="$BASH_SOURCE"
apparent_sdk_dir="${script_link%/*}"
if [ "$apparent_sdk_dir" == "$script_link" ]; then
  apparent_sdk_dir=.
fi
sdk_dir="$( command cd -P "$apparent_sdk_dir" && pwd -P )"
bin_path="$sdk_dir/bin"
export PATH=$bin_path:$PATH
_python_argcomplete() {
    local IFS=''
    COMPREPLY=( $(IFS="$IFS"                   COMP_LINE="$COMP_LINE"                   COMP_POINT="$COMP_POINT"                   _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS"                   _ARGCOMPLETE=1                   "$1" 8>&1 9>&2 1>/dev/null 2>/dev/null) )
    if [[ $? != 0 ]]; then
        unset COMPREPLY
    fi
}
complete -o default -F _python_argcomplete "gcloud"

_completer() {
    command=$1
    name=$2
    eval '[[ "$'"${name}"'_COMMANDS" ]] || '"${name}"'_COMMANDS="$('"${command}"')"'
    set -- $COMP_LINE
    shift
    while [[ $1 == -* ]]; do
          shift
    done
    [[ $2 ]] && return
    grep -q "${name}\s*$" <<< $COMP_LINE &&
        eval 'COMPREPLY=($'"${name}"'_COMMANDS)' &&
        return
    [[ "$COMP_LINE" == *" " ]] && return
    [[ $1 ]] &&
        eval 'COMPREPLY=($(echo "$'"${name}"'_COMMANDS" | grep ^'"$1"'))'
}

unset bq_COMMANDS
_bq_completer() {
    _completer "CLOUDSDK_COMPONENT_MANAGER_DISABLE_UPDATE_CHECK=1 bq help | grep '^[^ ][^ ]*  ' | sed 's/ .*//'" bq
}

unset gsutil_COMMANDS
_gsutil_completer() {
    _completer "CLOUDSDK_COMPONENT_MANAGER_DISABLE_UPDATE_CHECK=1 gsutil help | sed /Additional/q | grep '^  ' | sed -e 's/^  //' -e 's/ .*//'" gsutil
}

unset gcutil_COMMANDS
_gcutil_completer() {
    _completer "CLOUDSDK_COMPONENT_MANAGER_DISABLE_UPDATE_CHECK=1 gcutil help | grep -v '^information' | grep '^[a-z]' | sed -e 's/ .*//' -e '/^$/d'" gcutil
}

complete -o default -F _bq_completer bq
complete -o default -F _gsutil_completer gsutil
complete -o default -F _gcutil_completer gcutil
8个回答

49

对我有效的方法就是只使用 bass。看看这个链接:https://github.com/edc/bass

只需获取 gcloud 添加到你的 bash_profile 的行,并在你的 .config/fish/config.fish 文件中,在它们前面添加 bass,如下所示:

# The next line updates PATH for the Google Cloud SDK.
bass source '/Users/hunter/bin/google-cloud-sdk/path.bash.inc'

# The next line enables shell command completion for gcloud.
bass source '/Users/hunter/bin/google-cloud-sdk/completion.bash.inc'

3
谢谢你100遍...贝斯太棒了! - ivan
3
这似乎不再起作用了,或者说,当我按Tab键时,我会得到自动完成的文件和文件夹。 - Casey
4
https://github.com/Doctusoft/google-cloud-sdk-fish-completion 这个加上 source '...../google-cloud-sdk/path.fish.inc' 对我来说是有效的。 - Casey
我安装了那个仓库并以为它就是它了,但最终,我将 bass source ~/google-cloud-sdk/path.bash.inc 添加到 ~/.config/fish/config.fish 中,以使其适用于新终端。 - lumaks
“bass!”在我的语言中意味着“够了!”。这已经足够了。+1 :) - Pratik Deoghare

17

截至今日,我只能做到以下三件事:

  1. brew install --cask google-cloud-sdk
  2. source /usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.fish.inc 添加到我的 ~/.config/fish/config.fish 文件中
  3. 克隆 https://github.com/aliz-ai/google-cloud-sdk-fish-completion 然后运行 install.sh

7
这对我来说是有效的解决方案。使用 oh-my-fish 安装它:$ omf install git@github.com:aliz-ai/google-cloud-sdk-fish-completion.git - Dave Wongillies
2
对我来说,上述命令出现了权限错误。$ omf install https://github.com/lgathy/google-cloud-sdk-fish-completion.git。这个命令可以正常工作。 - ALLSYED
第三步对我来说已经足够了。谢谢! - Alexandre Paes
对于homebrew 3.4.11:source /opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.fish.inc - Mitch Ware

5
在 path.bash 中,它所做的只是将 Cloud SDK 的 bin 目录添加到您的 PATH 环境变量中。我们在其中放置了一些奇怪的东西,因为我们希望它在 Cloud SDK 目录内部工作,即使在符号链接后面也可以。对于您自己的系统,只需执行 "export PATH=$PATH:/path/to/google-cloud-sdk/bin" 的等效命令即可。
关于选项卡完成,我不知道 fsh 的选项卡完成如何工作,因此无法提供帮助。

“export PATH=$PATH:/path/to/google-cloud-sdk/bin”的fsh等效命令是什么? - iamchriswick
3
使用 fish_user_paths 这个全局变量是其中一种可能性:set -U fish_user_paths $fish_user_paths /path/to/google-cloud-sdk/bin。意思是将 /path/to/google-cloud-sdk/bin 添加到 $fish_user_paths 中。 - Pedro Romano
以什么方式,@GeorgeKatsanos?我刚刚尝试了一下(再次),它对我有效。 - Pedro Romano
在 Fish 中添加路径:set -gx $PATH /path/to/google-cloud-sdk/bin - rgalbo

3

开箱即用!谢谢! - Elijah Lynn
直接使用适用于参数/子命令,但不适用于选项,例如 --filter - Elijah Lynn
看起来 aliz-ai/google-cloud-sdk-fish-completion 现在重定向到 https://github.com/lgathy/google-cloud-sdk-fish-completion。正在更新答案。 - Elijah Lynn

2
现在,gcloud已经默认支持Fish,但是我遇到了一个非常烦人的问题。在google-cloud-sdk/path.fish.inc中包含的代码(以及@nafg的答案)会更改目录,导致每个新的shell会话都会在google-cloud-sdk目录中启动。
我所做的修改很简单,添加了两行额外的代码,用于获取当前工作目录并在操作后恢复它。这似乎已经解决了我的问题,因此希望能够帮助正在搜索“fish gcloud”问题的任何其他人。
set restore_dir (pwd -P)
set sdk_dir (builtin cd "$apparent_sdk_dir" > /dev/null; and pwd -P)
set bin_path "$sdk_dir/bin"
cd "$restore_dir"

1
你说的“开箱即用”是什么意思?我刚刚安装了它,但它不起作用。 - George Katsanos
1
看起来现在已经修复了。 - Rik
你是如何安装gcloud的?使用brew?apt?我认为这个文件并不在所有的软件包中存在。 - Roman M
在Mac上似乎没有预装Homebrew。 - Elijah Lynn
这个列表是为zsh而不是fish提供的补全。https://github.com/Homebrew/homebrew-cask/blob/ea70f7a70ccafb51dd060ab565e3ec8f9a62e60a/Casks/g/google-cloud-sdk.rb#L66-L76 - Elijah Lynn

1

这里有一个有趣的方法:http://michelpm.com/blog/2013/07/26/switching-from-zsh-to-fish/

基本上它会在bash中运行一个bash脚本,但它会对环境的变化进行差异化比较,并在fish中应用。

然而,它不适用于自动完成和path.bash,这太过繁琐了。更像是:

  • 将var=value更改为set var value
  • 将[...]更改为test...
  • 将$(...)更改为(...)
  • if不需要then,以end结束
  • ||更改为; or,将&&更改为; and
  • 将export更改为set -x

因此,在没有测试的情况下,这是我会尝试的:

set script_link ( readlink "$BASH_SOURCE" ); or set script_link $BASH_SOURCE
set apparent_sdk_dir ${script_link%/*}
if test "$apparent_sdk_dir" == "$script_link" ;
  set apparent_sdk_dir .
end
set sdk_dir ( command cd -P "$apparent_sdk_dir"; and pwd -P )
set bin_path $sdk_dir/bin
set -x PATH $bin_path:$PATH

1
对于 path.bash,我会按照正常方式编辑您的 PATH,直接将目录添加到路径中。我们添加了 path.bash,以便那些不熟悉点文件的人更容易使用,但是 fsh 用户很可能已经熟悉了。 - John Asmuth

0
使用Fisher模块:
fisher install lgathy/google-cloud-sdk-fish-completion

而且你已经准备就绪

请编辑您的答案,包括解释这是如何运作的以及为什么它是问题描述中的解决方案。请参见[答案]。 - Yunnosch

0
截至2023年8月,启用fish中的shell自动补全的最简单直接的方法是编辑~/.config/fish/config.fish文件,并添加以下行:
. "/path/to/where/you/installed/google-cloud-sdk/path.fish.inc"

例如,如果在/Users/foo/Applications目录下存在google-cloud-sdk文件夹,则添加以下内容:
. "/Users/foo/Applications/google-cloud-sdk/path.fish.inc"

然后重新启动fish。

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