Проблемы с путями - POSIX HFS не может получить папку

Я пытаюсь заставить этот короткий сценарий работать. Все, что он должен сделать, это взять содержимое папки в Application Support/App локального пользователя и переместить его на usb.

set localLocation to POSIX path of (path to library folder from user domain) & "Application\\ Support/myApp" as text
set usbLocation to "/Volumes/myUsb/myApp"                                   
tell application "Finder" to move entire contents of folder localLocation to folder usbLocation

В обоих каталогах есть папка (USB и компьютер), которая соответствует описанию пользовательского пути, описанному здесь как "myApp". Код содержит ошибку в первом разделе отчета, где он не может найти папку в поддержке приложений. Я не уверен, почему это так, и я также пытаюсь понять разницу между HFS и POSIX, какой из них предназначен для использования? У меня есть ощущение, что возможна ошибка конкатенации с типами. Я новичок, пожалуйста, помогите.

Спасибо!

2 ответа

Решение

Понимание того, как AppleScript обращается со ссылками на файлы и папки, является головной болью, и хорошо известно, что он запутан и суетлив относительно спецификаторов файлов и строк путей.

Простые определения:

Posix path: Путь, состоящий из прямой косой черты, разделяющей папки в дереве каталогов, например /Users/CK/Downloads/Some_File.txt, Корневой каталог (верхнего уровня) представлен одиночной косой чертой, /, Каждый путь posix происходит от этого корневого каталога, поэтому, как правило, пути posix должны начинаться с косой черты. В идеале пути к папкам заканчиваются косой чертой; пути к файлам нет; но это не строгое

HFS path: Путь, состоящий из двоеточий, которые разделяют папки в дереве каталогов, например Macintosh HD:Users:CK:Downloads:Some_File.txt, Корневой каталог представлен Macintosh HD:, который всегда начинается с пути HFS (если только системный жесткий диск не называется другим). В идеале пути к папкам заканчиваются двоеточием; пути к файлам нет; это полужесткий

Это буквально все, что вам нужно знать о путях posix и HFS, чтобы сделать некоторые сценарии AppleScripting. Сложнее всего разобраться с типами классов файлов AppleScript. Есть три:

alias: Это ваши друзья, и они наиболее универсальны, когда используются с Finder или системными событиями, а также при обращении к файлам или папкам. Это объект AppleScript, который содержит ссылку на файл, которая указывает на существующий файл. Пытаясь назначить alias Тип класса для ссылки на файл, который не существует, выдаст ошибку.

file: Это объект ссылки на файл, который может указывать на файл, который не существует (пока). Он определяет строку пути HFS, определяя ее как не просто фрагмент текста, а путь к файлу. Ключевая разница между file а также alias в том, что file является статической ссылкой, то есть если она указывает на файл с заданным именем и имя этого файла изменяется, file объект теперь будет ссылаться на файл, который не существует. alias с другой стороны, динамически сдвигает свою ссылку даже после переименования или перемещения файла.

POSIX file: Если вам нравится использовать пути posix (и вы должны), POSIX file объект твой лучший друг. Он принимает строку пути posix и определяет его как путь к файлу почти таким же образом file делает для строк пути HFS. Аналогично, это статическая ссылка и может указывать на файлы или папки, которые не существуют.

Моя рекомендация

Мне кажется, что пути HFS являются ненужным осложнением того, что могло бы быть простым объединением пользователей командной строки и AppleScripting. Они вводят людей в заблуждение, и поскольку нотация так широко соблюдается в результатах, возвращаемых AppleScript, они кажутся обязательными при их использовании.

Они не. Лично я никогда не использую пути HFS. (Почти никогда).

Одно по сути не лучше другого, и это на самом деле просто личное предпочтение. Поэтому я советую выбрать один стиль, который вам наиболее удобен, и научиться управлять этим типом пути в настройках AppleScript.

Поскольку я использую пути posix, я занимаюсь POSIX file объекты и alias объекты. Это то, на чем я сосредоточусь сейчас до конца этого ответа.

Ваш сценарий

Ваш скрипт выдал свою первую ошибку, потому что вы пытались избежать пробелов в строке пути к файлу, возможно, из-за привычки печатать в терминале. Вам не нужно экранировать символы в строке файла, кроме обратной косой черты \, поскольку строки пути к файлу всегда будут заключены в двойные кавычки.

По-прежнему обращаясь к первой строке вашего скрипта, вы совершенно правильно получили path to library folder (который возвращает alias); превратил его в строку пути posix; затем добавил "Application Support/myApp" текст пути. Тем не менее, может быть полезно знать, что вы можете получить path to application support папка, поэтому ваша первая строка может стать:

set localLocation to POSIX path of (path to application support from user domain) & "myApp"

Результатом является строка пути posix, но не файловый объект (но сейчас это нормально).

Ваша следующая строка затем явно объявляет строку пути posix:

set usbLocation to "/Volumes/myUsb/myApp"

что абсолютно нормально.

Немного сложнее: работать с Finder:

tell application "Finder" to move entire contents of ¬
    folder localLocation to folder usbLocation

Тем не менее, у вас было почти идеально. Поскольку вы используете пути posix, вам нужно либо превратить их в alias объекты, или объяснить искателю, что он имеет дело с путём posix, который является то, что POSIX file объект делает.

Чтобы создать POSIX file объект, вы можете либо предварять POSIX file спецификатор строки пути posix, подобный этому:

set usbLocation to POSIX file "/Volumes/myUsb/myApp"

или сделайте более обычное приведение в класс типов, например так:

set usbLocation to "/Volumes/myUsb/myApp" as POSIX file

В любом случае AppleScript превращает это в file объект и преобразует его в путь HFS. Если вы запустите эту строку чуть выше, AppleScript вернет это:

file "Macintosh HD:Volumes:myUsb:myApp"

Итак, мы уже видим, что есть эквивалентность между file объекты и пути HFS по сравнению с POSIX file объекты и пути посикс.

Вы можете редактировать строки 1 и 2 вашего скрипта, чтобы построить эти POSIX file объекты сразу; или вы можете сделать это в точке, где вы взаимодействуете с Finder:

tell application "Finder" to move entire contents of ¬
    folder (localLocation as POSIX file) to folder (usbLocation as POSIX file)

Если вы делаете это здесь, вы должны принудительно использовать as возможно потому, что добавление его в качестве спецификатора объекта мешает folder в роли спецификатора объекта.

Это должно успешно переместить все файлы на новое место. Другой способ сделать это - переместить папку вместо ее содержимого, что, вероятно, быстрее, если имеется много файлов и подкаталогов. Просто измените путь назначения соответственно:

set localLocation to POSIX path of (path to application support folder from user domain) & "myApp" as POSIX file
set usbLocation to POSIX file "/Volumes/myUsb/"

tell application "Finder" to move folder localLocation to folder usbLocation with replacing

(with replacing потому что папка myApp в месте назначения будет заменена папка myApp исходя из вашего жесткого диска.)

Наконец, для полноты картины я кратко расскажу о alias объекты:

Псевдоним объектов

строительство alias Объекты из путей posix довольно просты и требуют двух шагов. Во-первых, вы строите POSIX file объект, как я показал вам выше. Затем вы приводите этот объект в alias, Это можно сделать в одну строку:

set usbLocation to POSIX file "/Volumes/myUsb/myApp" as alias

или же

set usbLocation to "/Volumes/myUsb/myApp" as POSIX file as alias

Помните, однако, что alias объекты указывают на файлы и папки, которые уже существуют. Поэтому в некоторых случаях вы можете объявить POSIX file Объект сразу же из строки пути posix, которая указывает на несуществующий файл, который, например, вы будете создавать. Но вы можете только заставить его в alias после того, как файл был создан.

Одна из причин, вы можете использовать alias объекты, потому что они являются динамическими, как я упоминал ранее (или они должны быть). Так что если вы установите localLocation как alias объекта в начале, затем переместил папку к месту назначения, как в моем последнем примере Finder, alias object теперь должен автоматически указывать на /Volumes/myUsb/myApp/ (хотя это не всегда работает успешно, как одна из многих ошибок AppleScript).

Другая, более важная причина использования alias объекты - это то, что они транслируются непосредственно между различными приложениями, с которыми взаимодействует AppleScript: не все используют POSIX file объекты, а некоторые могут не использовать пути HFS; но они практически все знают, что такое alias Объект есть.

Это ключ при переключении между Finder и System Events для обработки файлов. Вообще говоря, обработку файлов и папок лучше всего выполнять с помощью системных событий, а не с помощью Finder. Но есть несколько вещей, которые вы можете сделать только в Finder: установить тег файла (label index); получить выбранные файлы (selection); и знать, какая целевая папка имеет фокус в настоящее время (insertion location).

Получение selection в Finder возвращает специфичные для Finder классы, а именно document files, Нельзя использовать эти объекты с системными событиями. Тем не менее selection as alias list это то, что может управляться системными событиями:

tell application "Finder" to set S to selection as alias list

tell application "System Events" to get properties of item 1 of S

Наконец, третья причина использовать alias объекты, потому что, по некоторым причинам, получение файлов как alias Объекты заметно быстрее, чем их извлечение, как и любой другой объект класса. Проверка этого на содержимом моей папки загрузок (которая достаточно мала, чтобы не заставлять меня ждать, но достаточно велика, чтобы заставить работать Finder), привела к следующим результатам:

tell application "Finder" to get entire contents of ¬
    (path to downloads folder) as alias list
-- 1.45s

tell application "Finder" to get entire contents of ¬
    (path to downloads folder)
-- 2.29s

Это идентичные утверждения, за исключением принуждения к alias list (список alias файловые объекты) в первую очередь. Преимущество в скорости будет более заметным в больших папках.

использующий alias объекты с Finder немного легче / проще, чем с file или же POSIX file объекты, потому что alias объекты не различают файлы и папки так, как другие. В вашем скрипте необходимо с Finder использовать folder спецификатор с POSIX file объекты; с alias объект, вам не нужно:

set localLocation to POSIX path of (path to application support folder from user domain) & "myApp" as POSIX file as alias
set usbLocation to POSIX file "/Volumes/myUsb/" as alias

tell application "Finder" to move localLocation to usbLocation with replacing

Я не согласен отговаривать от использования путей HFS.

Если вам нужно использовать Finder, это наиболее удобный способ, так как Finder не принимает пути POSIX.

Для обращения к папке на верхнем уровне внешнего тома в терминологии Finder есть еще один короткий путь: folder "foo" of disk "bar",

set localLocation to (path to application support folder from user domain as text) & "myApp"                                  
tell application "Finder" to move entire contents of folder localLocation to folder "myApp" of disk "myUsb"

тем не мение entire contents в Finder может быть очень медленным. Оболочка намного быстрее.

set localLocation to POSIX path of (path to application support folder from user domain) & "myApp/" 
set usbLocation to "/Volumes/myUsb/myApp"                                    
do shell script "/bin/cp " & quoted form of localLocation & "*" & space & quoted form of usbLocation
Другие вопросы по тегам