Как я могу изменить значок файла или папки с помощью терминала


54

Как я могу изменить или установить значок для файла или папки в терминале, мне нужно использовать язык сценариев?



Обратите внимание, что он плохо масштабируется. Пробовал применять иконки ко многим каталогам в одном каталоге - Finder работал очень медленно.
Колен

Ответы:


32

Вам понадобятся инструменты разработчика, и тогда может сработать следующее. Это берет изображение icon.pngи применяет его к file.ext.

# Take an image and make the image its own icon:
sips -i icon.png

# Extract the icon to its own resource file:
/Developer/Tools/DeRez -only icns icon.png > tmpicns.rsrc

# append this resource to the file you want to icon-ize.
/Developer/Tools/Rez -append tmpicns.rsrc -o file.ext

# Use the resource to set the icon.
/Developer/Tools/SetFile -a C file.ext

# clean up.
rm tmpicns.rsrc
# rm icon.png # probably want to keep this for re-use.

Круто, это как раз то, что я хотел.
ocodo

У меня проблемы с Rez -appendработой с .aviфайлами. ### Rez - Fatal error trying to open the resource file "Video.avi" for writing.какие-нибудь идеи?
ocodo

Интересно, что это также сделало файл неспособным принять новый значок с помощью метода Get Info copy / paste.
ocodo

есть ли ограничение на размер иконки? Если я использую большой JPG (1024x768), он будет изменен на что-то очень маленькое. Могу ли я как-нибудь сохранить его первоначальный размер?
Nuc

3
Обратите внимание, что в последних версиях OSX инструменты разработчика находятся в $PATH(заглушки, /usr/binкоторые знают, где найти реальные инструменты), а не в /Developer/Tools, так что вы должны вызывать их только по именам файлов; т. е. в данном случае, как раз Rezи DeRez.
mklement0

19

С пользой нескольких лет задним числом:

Ответ user588 в и ответ коию в них работают хорошо, но они полагаются на коммунальные услуги ( Rez, DeRezи SetFile) , что:

  • не устанавливаются по умолчанию (они поставляются с Xcode или утилитами командной строки разработчика)
  • теперь устарели ( Rezи DeRez, потому что они относятся к углероду)

osxiconutils выглядит интересно, но больше не будет компилироваться (начиная с OSX 10.10.4) .


Поэтому я создал CLIfileicon , который должен работать на чистой машине OSX (без предварительных условий) ; это скрипт Bash основывается главным образом на xattr, xxdи встроенный Python скрипт , который вызывает какао, любезно этот полезный ответ .

Это позволяет устанавливать / удалять / извлекать пользовательские значки для / из файлов или папок , в том числе на томах APFS в macOS 10.13 (High Sierra).

Вы можете установить его следующим образом:

  • Если у вас установлен Node.js, из реестра npm , с
    [sudo] npm install -g fileicon
  • В противном случае:
    • Загрузите CLI как fileicon(эта ссылка останется актуальной).
    • Сделайте его исполняемым с chmod +x fileicon.
    • Переместите или вставьте ссылку в папку в своей папке $PATH, например /usr/local/bin(требуется sudo).

Вот информация об использовании; для полной информации обратитесь к руководству :

$ fileicon -h

Set a custom icon for a file or folder:

    fileicon set      <fileOrFolder> <imageFile>

 Remove a custom icon from a file or folder:

    fileicon rm       <fileOrFolder>

 Get a file or folder's custom icon:

    fileicon get [-f] <fileOrFolder> [<iconOutputFile>]

 Test if a file or folder has a custom icon:

    fileicon test     <fileOrFolder>

 -q ...  silence status output

 Standard options: --help, --man, --version, --home

@Slomojo: [В ответ на удаленный комментарий] я понимаю, что не все имеют или хотят установить Node.js, поэтому здесь также есть прямая ссылка на скачивание (см. Пункт «Иначе:» в моем ответе) - это автономный Bash-скрипт (единственная вещь, от которой вы отказываетесь, устанавливая этот путь, это установка справочной страницы, но вы можете получить обычную текстовую визуализацию справочной страницы fileicon --man).
mklement0

@Slomojo: [В ответ на удаленный комментарий] Что касается того, почему предлагается установка через npm: я обнаружил, что экосистема npm - мой любимый менеджер пакетов в целом, и я опубликовал несколько кросс-платформенных скриптов на основе CLI, которые не связаны с Node.js. Я также создать одну команду, на уровне пользователя установки для НПМ (через п и Node.js) , что делает его простым в использовании НПМ даже для людей , которые в противном случае не имеют никакого интереса к Node.js: curl -L http://git.io/n-install | bash.
mklement0

3
Это хорошее готовое решение. +1
user3439894

1
@PatNiemeyer: Спасибо, я обновил ссылку osxiconutils, но учтите, что этот ответ касается утилитыfileicon , которая все еще работает (и фактически была создана, потому что osxiconutilsбольше не работает) - я обновил ответ, чтобы сделать это более понятным ,
mklement0

1
Я понимаю, что нахожусь на несколько лет позади всех остальных в этой теме, но просто хотел упомянуть, что я обнаружил это сегодня, и это здорово. Спасибо за это! T
TJ Луома

18

Я почти начал баунти на это, потому что мне не удалось изменить иконку в папку с помощью @ Манкоф «s ответ . Но я нашел решение.


Чтобы изменить значок папки, вы указываете не Rez -append tmp.rsrcпапку, а специальный Icon\rфайл внутри папки. Если вы ранее не устанавливали пользовательский значок для папки, файл, вероятно, не будет существовать, но Rezсоздает его «на лету». Удаление Icon\rфайла приведет к удалению пользовательского значка, поэтому для предотвращения несчастных случаев его хорошо скрывать.

Вот модификации ответа mankoff:

# Append a resource to the folder you want to icon-ize.
Rez -append tmpicns.rsrc -o $'myfolder/Icon\r'

# Use the resource to set the icon.
SetFile -a C myfolder/

# Hide the Icon\r file from Finder.
SetFile -a V $'myfolder/Icon\r'

А для файла? Обратите внимание на мой комментарий: avi файлы
ocodo

@slomojo извини, но я не могу воспроизвести ошибку, которую ты получаешь - просто проверил решение mankoff с помощью файла .avi. Перепроверить права доступа к файлам и введенные вами команды?
Яри ​​Кейнянен

Я сделаю еще один шаг, возможно, я сделал ошибку раньше.
ocodo

Я отчаянно пытаюсь сделать это для флэш-накопителя USB. Все команды «работают» в том смысле, что они не возвращают ошибок, но у меня все еще остается флэш-накопитель с неизменным значком. Любые мысли и я буду вечно благодарен!
Сингмотор

8

В дополнение к Ruby, вот версия Python:

#!/usr/bin/env python
import Cocoa
import sys

Cocoa.NSWorkspace.sharedWorkspace().setIcon_forFile_options_(Cocoa.NSImage.alloc().initWithContentsOfFile_(sys.argv[1].decode('utf-8')), sys.argv[2].decode('utf-8'), 0) or sys.exit("Unable to set file icon")

./set-image.py image.png myfile

Python, предустановленный в Mac OS, уже имеет PyObjC, поэтому вам не нужно устанавливать какие-либо пакеты.


Я добавил декодирование UTF-8 в Unicode, иначе скрипт не работал с именами не-ASCII. Также добавлена ​​проверка возвращаемого значения, невозможность установить значок приведет к коду возврата 1.
kolen

1
Можно ли в любом случае указать, что значок не имеет измененного соотношения сторон? Это прекрасно работает, но файлы изображений преобразуются в квадрат. Спасибо!
Густаво Безерра

1
Точно не нашел ответа, но возведение в квадрат изображений с прозрачным заполнением до того, как рука работала просто отлично: stackoverflow.com/questions/12179342/…
Густаво Безерра

7

Check setfileicon(исходный код) , утилита, созданная Damien Bobillot.

Загрузите двоичный файл здесь: http://maxao.free.fr/telechargements/setfileicon.gz

После распаковки файла сделайте его исполняемым:

chmod +x setfileicon

Тогда вы можете использовать его следующим образом:

./setfileicon "my-icon.icns" "my-file-or-directory"

Спасибо за это, действительно очень полезно. Кстати, я редактирую метод GUI, чтобы уменьшить шум.
ocodo

К сожалению, большая часть кода сейчас устарела.
Мюген

3

У меня есть проект github, в котором я создаю «капли» AppleScript из сценариев [shell / bash, python, perl, ruby ​​и т. Д.], Которые принимают пути к файлам в качестве аргументов. Я написал эту функцию bash для изменения значка папки (потому что пакеты AppleScript - это папки с расширением .app).

replace_icon(){
    droplet="$1"
    icon="$2"
    if [[ "$icon" =~ ^https?:// ]]; then
        curl -sLo /tmp/icon "$icon"
        icon=/tmp/icon
    fi
    rm -rf "$droplet"$'/Icon\r'
    sips -i "$icon" >/dev/null
    DeRez -only icns "$icon" > /tmp/icns.rsrc
    Rez -append /tmp/icns.rsrc -o "$droplet"$'/Icon\r'
    SetFile -a C "$droplet"
    SetFile -a V "$droplet"$'/Icon\r'
}

После определения вы вызываете функцию с 2 аргументами:

replace_icon /path/to/AppleScript.app /path/to/icon.png

или же

replace_icon /path/to/AppleScript.app http://i.imgur.com/LmUvWqB.png

Как видите, вторым аргументом может быть изображение в вашей системе или URL.

ПРИМЕЧАНИЕ. Эта сумасшедшая $'/Icon\r'вещь, которую я делаю, заключается в том, что имя файла Icon заканчивается буквальным возвратом каретки \r. Убедитесь сами с:

find my-applescript.app -maxdepth 1 | less -U

3

Предполагая, что у нас уже есть icns-файл. Создайте временный файл ресурсов, который указывает на icns-файл:

$ echo "read 'icns' (-16455) \"Icon.icns\";" >> Icon.rsrc

Добавьте файл ресурса в качестве значения расширенного атрибута «com.apple.ResourceFork» в файл:

$ Rez -a Icon.rsrc -o FileName.ext

Показать значок файла:

$ SetFile -a C FileName.ext

Добавьте файл ресурсов в качестве значения расширенного атрибута «com.apple.ResourceFork» к файлу магических значков в текущей папке:

$ Rez -a Icon.rsrc -o Icon$'\r'

Показать значок текущей папки:

$ SetFile -a C .

Скрыть файл магических значков внутри текущей папки (нажмите ⇧⌘., Чтобы показать / скрыть скрытые файлы в Finder):

$ SetFile -a V Icon$'\r'

Дополнительные детали

Данные значка хранятся в виде значения расширенного атрибута «com.apple.ResourceFork» (команда терминала «xattr -p com.apple.ResourceFork FileName.ext» печатает значение). Для папки есть волшебный (пустой и скрытый) файл Icon$'\r'внутри папки. Чтобы извлечь данные значка из расширенного атрибута «com.apple.ResourceFork» в файл текстового ресурса (из которого мы знаем правильный идентификатор типа icns «-16455»):

$ DeRez -only icns FileWithIcon.ext > Icon.rsrc
$ DeRez -only icns /Folder/With/Icon/Icon$'\r' > Icon.rsrc

В macOS 10.13 High Sierra команда $ sips -i ImageFile.icns/png/jpgвыдает ошибку «--addIcon больше не поддерживается». Переключатель «-i» означает «--addIcon» в качестве расширенного атрибута «com.apple.ResourceFork» для самого этого файла, используя содержимое этого файла изображения.


# <stdin>: 1: ### /Applications/Xcode.app/Contents/Developer/usr/bin/Rez - SysError 0 во время чтения.
кванты

2

Другой вариант - использовать MacRuby:

/usr/local/bin/macruby -e 'framework "Cocoa";NSWorkspace.sharedWorkspace.setIcon(NSImage.alloc.initWithContentsOfFile("/tmp/a.png"),forFile:"/tmp/file",options:0)'

Вы можете скачать установщик для MacRuby с http://macruby.org .


1
Ссылка - и MacRuby - очевидно, теперь мертвы; MacRuby, по-видимому, сменил коммерческий, основанный на подписке RubyMotion .
mklement0

2

Как ни странно, лучшим решением, похоже, является не использование собственных инструментов Apple, а код Python, потому что он имеет различные преимущества, не ограничиваясь:

  • разрешение выходного файла
    (работает до 1024x1024)
  • формат входного файла
    (пробовал с ICNS и PNG)
  • разрешения на установку
    (определите как функцию)

Обновить

Теперь (в macOS Sierra) ответ @ koiyu, кажется, работает, поэтому вы можете использовать этот двухслойный файл, чтобы скопировать значок из исходной папки в папку назначения:

#!/bin/sh

DeRez -only icns $1/Icon$'\r' > icon.rsrc; Rez -a icon.rsrc -o $2/Icon$'\r'
SetFile -a C $2; SetFile -a V $2/Icon$'\r'; rm icon.rsrc

Добро пожаловать, чтобы спросить другого! Кажется, это будет лучше в качестве комментария. Я знаю, что у вас еще нет необходимых очков, но я попросил кого-нибудь, кто может прийти, взглянуть. Кроме того, я написал Applescript, который делает все это для вас в аккуратном комплекте, см. Мой ответ на аналогичный вопрос на этом SE.
JMY1000

Да, я пытался, но не мог этого сделать. Кроме того, я думаю, что вторая часть вашего комментария будет лучше в качестве ответа, не будучи связанной с первой.
dardo82

2

В последней версии macOS (10.14) sips -i icon.pngпоявится сообщение --addIcon is no longer supportedоб ошибке.

Это также нуждается в Установленных Инструментах разработчика. Это использует изображение Icon.pngи применяет его file.ext, как и ответ пользователя user588 :

# Covert Icon.png to tmpicons.icns:
sips -s format icns Icon.png --out tmpicns.icns

# Create temporary resource file which points to tmpicons.icns:
echo "read 'icns' (-16455) \"tmpicns.icns\";" >> tmpicns.rsrc

# append this resource to the file you want to icon-ize.
Rez -a tmpicns.rsrc -o file.ext

# Use the resource to set the icon.
SetFile -a C file.ext

# Clean up
rm tmpicons.icns && rm tmpicns.rsrc

0

Как и решение Python, использующее PyObjC, оказывается, что это можно сделать только с помощью AppleScript (что не рекомендуется в 10.15 Catalina, в отличие от Python и других языков сценариев).

Я нашел пример того, как сделать это на GitHub здесь:

набор радиопеленгатор-значок

#!/usr/bin/env osascript

use framework "AppKit"

--------------------------------------------------------------------------------
# PROPERTY DECLARATIONS:
property this : a reference to current application
property NSWorkspace : a reference to NSWorkspace of this
property NSImage : a reference to NSImage of this

--------------------------------------------------------------------------------
# IMPLEMENTATION:
on run argv
  set icon to item 1 of argv
  set target to item 2 of argv

  setIcon to icon for target
end run
--------------------------------------------------------------------------------
# HANDLERS:
to setIcon to iconPath for filePath
  set sharedWorkspace to NSWorkspace's sharedWorkspace()
  set newImage to NSImage's alloc()
  set icon to newImage's initWithContentsOfFile:iconPath

  set success to sharedWorkspace's setIcon:icon forFile:filePath options:0
end setIcon

AppleScript нелегко читать, но, очевидно, можно получить доступ к коду Objective-C, чтобы сделать это через платформу AppKit.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.