关于macOS:升级通过Homebrew Cask安装的所有酒桶

Upgrade all the casks installed via Homebrew Cask

我使用Homebrew Cask在OS X上安装应用程序。如何升级所有已安装的Cassk?


2017年12月更新

我以为这将永远不会发生,但是现在终于有了针对Homebrew Cask的官方升级机制(有关实现,请参见问题3396)!要使用它,只需运行以下命令:

brew cask upgrade

但是,这不会更新没有版本信息(version :latest)或具有内置升级机制(auto_updates true)的应用程序的存储桶。要重新安装这些木桶(如果有可用的升级,则要对其进行升级),请使用带有--greedy标志的upgrade命令,如下所示:

brew cask upgrade --greedy

2017年3月更新(注意双关语;)(@polo)

由于最初得到了答复,所以我发现了一些更新。
要解决此问题,您现在可以使用brew cask reinstall

1
2
brew cask reinstall <cask_name>
brew cask list | xargs brew cask reinstall

原始答案中提到的问题4678已关闭,现在在问题#29301中讨论了升级功能
还有buo / homebrew-cask-upgrade,这是一个外部软件包,可将升级命令添加到brew cask。我已经在一些软件包上成功测试了它。

原始答案

没有官方的方法来升级自制酒桶。目前正在对此进行处理,但距离完成还很遥远。有关更多详细信息,请参见问题#4678。该问题还提供了一些脚本示例,用户可以使用这些脚本来升级其所有容器。升级单个容器的最简单方法是运行brew cask install --force ,但要知道这有可能会导致您的应用出现问题,因为不会首先将其正确卸载。通常,这不是问题。

您可以使用以下shell命令升级所有已安装的容器:

1
brew cask list | xargs brew cask install --force

为了将来参考,可以在github上的重复问题中找到更多详细信息。


自制酒桶升级

我认为这是迄今为止升级木桶的最佳解决方案。
来源:https://github.com/buo/homebrew-cask-upgrade

安装与使用

1
2
3
brew tap buo/cask-upgrade
brew update
brew cu

(可选)强制升级过时的应用程序,包括标记为最新的应用程序:

1
brew cu --all


可以通过以下方式列出已安装的木桶:

1
brew cask list

并使用以下命令强制重新安装木桶:

1
brew cask install --force CASK_NAME

因此,将第一个命令的输出传递到第二个命令的输出中,我们更新所有桶:

1
brew cask list | xargs brew cask install --force


Bash脚本升级软件包

灵感来自Pascal答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env bash

(set -x; brew update;)

(set -x; brew cleanup;)
(set -x; brew cask cleanup;)

red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

casks=( $(brew cask list) )

for cask in ${casks[@]}
do
    version=$(brew cask info $cask | sed -n"s/$cask:\ \(.*\)/\1/p")
    installed=$(find"/usr/local/Caskroom/$cask" -type d -maxdepth 1 -maxdepth 1 -name"$version")

    if [[ -z $installed ]]; then
        echo"${red}${cask}${reset} requires ${red}update${reset}."
        (set -x; brew cask uninstall $cask --force;)
        (set -x; brew cask install $cask --force;)
    else
        echo"${red}${cask}${reset} is ${green}up-to-date${reset}."
    fi
done

它能做什么

  • 更新酿造/酒桶,清理
  • 阅读酒桶清单
  • 检查brew cask info以获取最新版本
  • 安装新版本(如果有)(并删除所有旧版本!)

来源:https://gist.github.com/atais/9c72e469b1cbec35c7c430ce03de2a6b

一线耐心:

1
curl -s https://gist.githubusercontent.com/atais/9c72e469b1cbec35c7c430ce03de2a6b/raw/36808a0544628398f26b48f7a3c7b309872ca2c6/cask_upgrade.sh | bash /dev/stdin

另存为/usr/local/bin/cask-upgrade,因此以后可以在本地以cask-upgrade运行


自2017年12月起使用:
酿造桶升级

[自2017年12月在Homebrew为酒桶引入升级命令以来不推荐使用]
我只是使用以下内容:

1
brew cask outdated | xargs brew cask reinstall


brew cask upgrade

upgrade命令最近已在Homebrew Cask中引入,应弃用其他答案中描述的所有其他手动方法。


这是我为处理此问题而编写的函数。请注意,我个人不希望它只是盲目地重新安装所有内容,因为我使用的某些酒桶需要一段时间才能安装或需要其他提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
brew-cask-upgrade() {
  if ["$1" != '--continue' ]; then
    echo"Removing brew cache"
    rm -rf"$(brew --cache)"
    echo"Running brew update"
    brew update
  fi
  for c in $(brew cask list); do
    echo -e"

Installed versions of $c:"
    ls /opt/homebrew-cask/Caskroom/$c
    echo"Cask info for $c"
    brew cask info $c
    select ynx in"Yes""No""Exit"; do  
      case $ynx in
       "Yes") echo"Uninstalling $c"; brew cask uninstall --force"$c"; echo"Re-installing $c"; brew cask install"$c"; break;;
       "No") echo"Skipping $c"; break;;
       "Exit") echo"Exiting brew-cask-upgrade"; return;;
      esac
    done
  done
}


我认为使用

1
brew cask reinstall `brew cask outdated`

会成功的这也将有助于删除该应用程序的先前版本,并将安装较新的版本。


基于@Atais的回答,我将他的逻辑提高了一些。我想要一种在实际强制升级之前先检查要升级的软件包的方法。

  • $ brew-cask.sh仅列出类似于Homebrew brew update的输出。
  • 上面的列表显示了所有已安装的软件包,绿色的?表示所有待处理的更新。
  • $ brew-cask.sh upgrade将强制升级那些软件包。

码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# Usage:
#
#  $ brew update
#    You should execute this first to update everything locally.
#
#  $ brew-cask.sh [update]
#    This will list all of your cask packages and rather there is an upgrade
#    pending with a ? checkmark, just like Homebrew does with"brew update".
#    The update command is optional, as it doesn't actually do any tracking, there's
#    not really anything to"update" with cask.  But it keeps with the pattern of
#    of Homebrew's"brew update" pattern for those with memory muscle fingers (like me).
#
#  $ brew-cask.sh upgrade
#    This performs a"brew cask install <cask> --force" of all cask packages that have
#    an update pending.
#
# This code was inspired by http://stackoverflow.com/a/36000907/56693

# get the list of installed casks
casks=( $(brew cask list) )

if [["$1" =="upgrade" ]]; then
  for cask in ${casks[@]}; do
    current="$(brew cask info $cask | sed -n '1p' | sed -n 's/^.*: \(.*\)$/\1/p')"
    installed=( $(ls /opt/homebrew-cask/Caskroom/$cask))
    if (! [[" ${installed[@]}" == *" $current"* ]]); then
      echo"Upgrading $cask to v$current."
      (set -x; brew cask install $cask --force;)
    else
      echo"$cask v$current is up-to-date, skipping."
    fi
  done
else
  echo"Inspecting ${#casks[@]} casks. Use 'brew-cask.sh upgrade' to perform any updates."
  for (( i = i ; i < ${#casks[@]} ; i++ )); do
    current="$(brew cask info ${casks[$i]} | sed -n '1p' | sed -n 's/^.*: \(.*\)$/\1/p')"
    installed=( $(ls /opt/homebrew-cask/Caskroom/${casks[$i]}))
    if (! [[" ${installed[@]}" == *" $current"* ]]); then
      casks[$i]="${casks[$i]}$(tput sgr0)$(tput setaf 2) ?$(tput sgr0)"
    fi
  done
  echo" ${casks[@]/%/$'
'}" | column
fi

只需安装它(又名"我现在需要它!")

它已签入我的.dotfiles存储库;因此,您可以使用以下命令将其快速安装到~/bin中:

1
2
$ curl -L https://raw.githubusercontent.com/eduncan911/dotfiles/master/bin/brew-cask.sh --create-dirs -o ~/bin/brew-cask.sh
$ chmod 755 ~/bin/brew-cask.sh

然后像这样使用它:

1
2
$ brew-cask.sh
$ brew-cask.sh upgrade

如果您的路径中没有~/bin,请在上述语句前添加~/bin/前缀。


1
brew cask outdated | xargs brew cask reinstall --force

取得陈旧的木桶:

brew cask outdated

升级酒桶:

brew cask reinstall outdated-cask

演示脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ cat ~/bin/brew_cask_upgrade.sh
#!/bin/bash
red=$(tput setaf 1)
# green=$(tput setaf 2)
reset=$(tput sgr0)

(set -x; brew update;)

for cask in $(brew cask outdated | awk '{print $1}')
do
    echo"${red}update ${cask} ...${reset}."
    (set -x; brew cask install --force"$cask";)
done

echo"${red}brew clean up ...${reset}"
(set -x; brew cask cleanup;)
echo"${red}brew clean up done.${reset}"


我自己编写了这样的脚本。请查看github https://github.com/pesh1983/brew_cask_upgrade。它有很好的描述,但是如果您有任何其他问题,请随时问我。它确实可以公平升级:卸载并安装,因此任何必要的清理都将由" brew"本身执行。


改进了deinspanjer提供的代码,我试图模仿noop命令,就像Chocolatey中的命令一样(choco update --noop / choco已过时)。

https://git.io/vgjiL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/sh

fetch(){
    echo"Removing brew cache"
    rm -rf"$(brew --cache)"
    echo"Running brew update"
    brew update
}

lookup() {
  for c in $(brew cask list); do
    brew cask info $c
  done
}

update(){
  var=$( lookup  | grep -B 3 'Not installed' | sed -e '/^http/d;/^Not/d;/:/!d'  | cut -d":" -f1)
  if [ -n"$var" ]; then
  echo"The following installed casks have updates avilable:"
  echo"$var"
  echo"Install updates now?"
  select yn in"Yes""No"; do
    case $yn in
     "Yes") echo"updating outdated casks"; break;;
     "No") echo"brew cask upgrade cancelled" ;return;;
      *) echo"Please choose 1 or 2";;
    esac
    done
  for i in $var; do
    echo"Uninstalling $c"; brew cask uninstall --force"$i"; echo"Re-installing $i"; brew cask install"$i"
  done
else
  echo"all casks are up to date"
fi
}

fetch
update

可以看到,由于我的用例有些不同,因此我正在使用模块化方法。我不想坐在电脑前,对我安装的每个应用程序都键入"是/否"。虽然没有升级木桶的真正方法(只需重新安装最新版本),但我首先进行brew更新以获取实际上有可用更新的信息。

接下来,我循环浏览所有酒桶以显示其信息。因为我之前做过brew更新,所以现在提供的信息是未安装某些cask的最新版本。

在我的更新方法中,我实际上解析了该特定行的info命令:

1
lookup  | grep -B 3 'Not installed' | sed -e '/^http/d;/^Not/d;/:/!d'  | cut -d":" -f1

意思是:"只要您阅读"未安装"行,就在信息的上方提供三行。然后删除其中包含链接的任何行,同时删除其中包含":"的行。"

给定brew cask info命令的结构,我们最后得到一行(无版本信息,无应用程序URL),该行反映了该桶也已安装的实际名称。

酿造桶信息输出

在我的版本中,此信息现在已打印出来,因此您可以轻松查看哪些酒桶已过期并且可以更新。

在这一点上,我做了一个切换案例,因为现在可能没有足够的时间来更新内容。这取决于您的用例。对我来说,有时我只是想看看有什么新功能(正在等待一个新版本,一个错误修正),但实际上没有时间更新内容,因为现在我不想关闭浏览器等。

因此,如果选择"是",则将已清理的木桶名称列表提供给更新功能,其中对于每个确定为过时的木桶,将发出重新安装。

再次感谢deinspanjer,在尝试自己解决此问题时,我总是忘记事先发布brew更新,因此那里没有要实际解析的" not install"行(我整个方法的基础)。

我希望这可以帮到你。


基于我所阅读的内容,我创建了一个脚本,该脚本将创建一个文件,该文件列出要更新的文件,包括定义为最新的应用程序。然后,您可以使用我的olinst脚本修改文件以满足您的要求并安装更新。

有关更多信息,请访问我的github。

https://github.com/pacav69/caskroom-offline-install


我用

1
brew cask install --force `brew cask list`

这真的让我很生气,因此我创建了此脚本来更新所有Brew应用程序,并允许用户选择要更新的Cask应用程序。您也可以将应用排除在外。

https://github.com/derrekyoung/ScriptsAndUtils/blob/master/brew-cask-upgrade.sh


检查陈旧的酒桶:

brew cask outdated

升级所有过时的酒桶:

brew cask upgrade

如果要升级特定的酒桶,只需在升级后添加酒桶名称(例如:4k-video-downloader):

brew cask upgrade 4k-video-downloader