如何通过OS X中的终端为特定文件类型的所有文件更改默认应用程序?


32

如何通过OS X中的终端更改特定文件类型的所有文件的默认应用程序?


即使我在那儿回答了它也不是一个骗子。对于那个很抱歉。
丹尼尔·贝克

Answers:


39

我有一个简单的方法。你会想自制,如果你不已经拥有了它:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装duti:

brew install duti

现在,您需要找到要使用的应用程序的ID,并将其分配给您要使用的扩展程序。在此示例中,我已经将Brackets用于,*.sh并且还希望将其用于*.md文件而不是xcode。

获取.sh文件的默认应用程序ID :

duti -x sh

output:
  Brackets.app
  /opt/homebrew-cask/Caskroom/brackets/1.6/Brackets.app
  io.brackets.appshell

最后一行是ID。

对所有.md文件使用此应用程序ID :

duti -s io.brackets.appshell .md all

3
如果可以的话,可以投票50次。很棒的信息。在El Capitan对我来说像是一种魅力。
瑞安·沃尔斯

1
在塞拉利昂也工作。额外提示:UTI很麻烦,但是您可以使用“ mdls -name kMDItemContentType <file>”查找给定文件(以及扩展名)的UTI。
阿德里安

2
如果您尚未通过这种方式将某个应用程序与某事物关联,但知道该应用程序的名称,则可以osascript -e 'id of app "$appName"'获取系统上已安装的任何应用程序的ID
GrayedFox

1
仅供参考:将@GrayedFox的技巧与duti结合使用:duti -s $(osascript -e 'id of app "Visual Studio Code"') .md all
Strajk,

18

编辑~/Library/Preferences/com.apple.LaunchServices.plist

在下方添加一个条目LSHandlers,其中包含UTI(LSHandlerContentType例如密钥public.plain-text)和应用程序捆绑标识符(LSHandlerRoleAll例如com.macromates.textmate)。

在“ 属性列表编辑器”中看起来像这样:

替代文字 替代文字

要从命令行执行此操作,请使用defaults/usr/libexec/PlistBuddy。两者都有大量的联机帮助页。

例如,.plist使用打开所有文件Xcode

defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = "com.apple.property-list"; LSHandlerRoleAll = "com.apple.dt.xcode"; }'

当然,您需要确保那里没有UTI的其他条目com.apple.property-list

这是一个更完整的脚本,它将删除UTI的现有条目并添加一个新条目。它只能处理LSHandlerContentType,并且始终会设置LSHandlerRoleAll,并且具有硬编码的包ID而不是参数。除此之外,它应该运行得很好。

#!/usr/bin/env bash

PLIST="$HOME/Library/Preferences/com.apple.LaunchServices.plist"
BUDDY=/usr/libexec/PlistBuddy

# the key to match with the desired value
KEY=LSHandlerContentType

# the value for which we'll replace the handler
VALUE=public.plain-text

# the new handler for all roles
HANDLER=com.macromates.TextMate

$BUDDY -c 'Print "LSHandlers"' $PLIST >/dev/null 2>&1
ret=$?
if [[ $ret -ne 0 ]] ; then
        echo "There is no LSHandlers entry in $PLIST" >&2
        exit 1
fi

function create_entry {
        $BUDDY -c "Add LSHandlers:$I dict" $PLIST
        $BUDDY -c "Add LSHandlers:$I:$KEY string $VALUE" $PLIST
        $BUDDY -c "Add LSHandlers:$I:LSHandlerRoleAll string $HANDLER" $PLIST
}

declare -i I=0
while [ true ] ; do
        $BUDDY -c "Print LSHandlers:$I" $PLIST >/dev/null 2>&1
        [[ $? -eq 0 ]] || { echo "Finished, no $VALUE found, setting it to $HANDLER" ; create_entry ; exit ; }

        OUT="$( $BUDDY -c "Print 'LSHandlers:$I:$KEY'" $PLIST 2>/dev/null )"
        if [[ $? -ne 0 ]] ; then 
                I=$I+1
                continue
        fi

        CONTENT=$( echo "$OUT" )
        if [[ $CONTENT = $VALUE ]] ; then
                echo "Replacing $CONTENT handler with $HANDLER"
                $BUDDY -c "Delete 'LSHandlers:$I'" $PLIST
                create_entry
                exit
        else
                I=$I+1 
        fi
done

3
最简单的方法可能是x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $x复制并粘贴这些LSHandlers条目。要获取包标识符,您可以执行osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'
Lri 2011年

@Lri在某种程度上,是的,但是这个问题是专门关于命令行的。我发现TextEdit(或“属性列表编辑器” / Xcode)不符合条件;我只是从其他答案中使用“属性列表编辑器”复制了该部分,以进行说明。有关捆绑标识符的有用注释。
丹尼尔·贝克


如果确实存在UTI的替代条目,您是否同意“从数组中从命令行删除单个词典可能会不必要地困难”?
格雷厄姆·佩林

1
@GrahamPerrin这是不必要的困难,因为defaults它似乎没有能力执行此操作,并且它需要打几个PlistBuddy电话。但是可以在可重用的shell脚本中完成此操作。
丹尼尔·贝克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.