如何在 Mac OSX/Finder 中复制目录后触发脚本

发布于 2024-08-17 08:44:22 字数 1912 浏览 9 评论 0原文

在 Snow Leopard 中,每当用户在 Finder 中复制目录时,我想触发脚本/代码。我怎样才能做到这一点?

我一直在寻找文档,但我对这种类型的工作有点陌生,无法识别正确的方法。

动机:如果一个目录受版本控制,例如使用 git 或 hg 或 svn,并且用户复制该目录,那么我想运行一个脚本来搜索原始目录,然后创建一个 '版本控制中的标记。如果用户重命名该目录(例如在 10 秒内),则重命名将成为该标签注释的一部分。我最终也想添加一些覆盖图标来指示目录的版本控制状态。

扩展动机:我面临的问题是版本控制软件,如 git 和 hg,在我看来太复杂了,因为它与文件系统太脱节,并且充当了某种影子文件系统。我是版本控制的忠实粉丝,并且已经使用它很多年了 - 但我也看到了由于其复杂性而导致的部署限制。现实情况是,如果更易于使用,将会有更多代码处于版本控制之下。

我正在研究创建一个更易于使用且不需要终端访问的 VCS 系统的可行性。想象一下,如果 Apple 将其作为 finder 和/或 iLife 的一部分,版本控制(代码)会是什么样子 - 简单,但足够好。实际上,我显然不会重新发明 vcs,但我希望为 hg 之类的东西构建一个模块/插件,并将其与重新设想 vcs 如何为以查找器为中心的 UI 工作相结合a - 一切都是为了为更休闲的程序员创建一个更简单但足够好的 VCS。

第一个技术障碍是检测目录副本和重命名 - 因此出现了这个问题。

文件数量:由于该项目的主要动机是源代码版本控制,因此我只需要匹配与您正在处理的项目数量相匹配的目录数量。因此,如果您正在开发两个不同的项目,那么我认为我只需要跟踪两个目录 - 每个项目的根目录。现在,我完全承认,此时我可能会错误地描述需求,所以也许我需要跟踪项目中的所有目录,甚至可能还需要跟踪这些项目中的所有文件,所以可以说,对于为了论证,一个典型的项目中有 1,000 个文件。所以,基本上,可能只有几个目录,或者几百个目录,或者几千个文件。重要的是,我认为 50,000 个文件属于较高范围。

用户从查找器中复制目录“trunk”

后备箱 -->主干副本

如果用户将“主干副本”重命名为“主干副本固定#255每种颜色” 主干目录(不是副本)将被标记为 评论“固定每种颜色 #255”

参考

  • 文件系统事件编程

    • 在启动时,如果注册目录中的某些内容发生更改 - 如果大目录中的任何一个文件发生更改,则会收到通知。我认为它不会告诉你发生了什么变化。
  • 内核队列

    • 您可以注册以获得有关个人文件级别的通知。您的选择(至少)如下: 注意_删除|注意_写 |注意_扩展 |注意_ATTRIB |注意_LINK |注意_重命名 |注意_REVOKE 这可能用于检测目录重命名(它适用于目录吗?),但显然不是目录副本。

稍微相关的问题

谢谢, 杰杰

In Snow Leopard, I want to trigger a script/code whenever a user duplicates a directory in Finder. How can I do that?

I've been hunting around the docs, but I'm a little too new this type of work to recognize the right approach.

Motivation: If a directory is under version control, say with git or hg or svn, and the user duplicates that dir, then I want to run a script that searches for the original dir and then makes a 'tag' in version control. If the user renames the dir, say within 10 seconds, then the rename would be part of that tag comment. I'd eventually like to throw on some overlay icons to indicate the version control state of the dir, too.

Expanded Motivation: The problem that I face is that that version control software, like git, and hg, in my opinion is too complicated namely because it is too disconnected from the file system and acts as sort of a shadow-filesystem. I'm a big fan of version control and have used it for many years - but I have also seen the limits of deployment because of its complexity. The reality is that a lot more code would be under version control if it were easier to use.

I'm investigating the feasibility of creating an easier to use VCS system that doesn't require terminal access. Imagine what version control (for code) would look like if Apple were to make it part of finder and/or iLife - simple, but good-enough. In reality, I'm obviously not going to re-invent a vcs, but I'm hoping that building a module/plugin for something like hg, and coupling that with a re-envisioning of how vcs works for a finder-centric UI a - all to create a simpler, but good enough, VCS for the more casual programmer.

The first technical hurdle detecting directory copies and renames - and hence this question.

Number of Files: Since the primary motivation of this project is for source code version control, I only need to match the number of directories matching the number of projects you are working on. So, if you are working on two distinct projects, then, I think, that I only need to track two directories - the root of each project. Now, I fully admit that I may, at this point be mis-characterizing the need, so maybe I need to track all of the directories in the projects, or maybe even all of files in those projects, too, so lets say, for the sake of argument, that a typically project has 1,000 files in it. So, basically, maybe only a few directories, or a few hundred directories, or maybe a few thousand files. Importantly, I think 50,000 files would be at the higher end of the spectrum.

User duplicates the dir 'trunk' from within finder

trunk --> trunk copy

If the user renames 'trunk copy' to 'trunk copy fixed #255 per colors'
the trunk dir (not the copy) would be tagged with
the comment 'fixed #255 per colors'

References:

  • File System Event Programming

    • Get notified, upon start-up, if something in a registered dir changed - if any one file in a large dir changes. It won't tell you, I don't think, what got changed.
  • Kernel Queues

    • You can register to be notified of things at the individual file level. You're options are (at least) the following:
      NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE This could maybe be used to detect a directory rename (will it work for dirs?), but apparently not a dir copy.

Slightly related question:

Thanks,
JJ

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七七 2024-08-24 08:44:22

最初的帖子提出了一个非常大的项目,有很多未指定的功能。您的“扩展动机”以“...检测目录副本并重命名...”结尾很有帮助。

首先,您几乎通过引用文件系统事件和内核队列来回答您自己的帖子。您关闭文件夹操作的做法是正确的,但原因错误。您似乎关心为大量文件夹激活 FA。这不是问题,因为它可以自动化。 FA 不起作用的原因是它们无法检测文件重命名。此外,由于操作是 AppleScript,因此在开销和并发性方面存在巨大问题。

您对 FS 事件的看法是正确的:(来自 达尔文文档

重要的一点是
通知的粒度
位于目录级别。它告诉你
只有目录中的东西
已经改变,但不告诉你
发生了什么变化。

所以看起来你只剩下内核队列了。他们做一切事情。请注意,您必须聪明地使用内核队列 - 您必须知道苍蝇的名称才能监视它。因此,当创建新文件/文件夹时,您必须解释事件并打开(O_EVTONLY)新文件。但是,有一个问题:(更多达尔文文档

如果您正在监控大型
内容的层次结构,你应该使用
然而,文件系统事件
因为内核队列有点
比内核事件更复杂,并且
可能会更加资源密集,因为
额外的用户内核
涉及沟通。

另一个回复提到 TimeMachine 使用 FS Events。我对此表示怀疑,因为注意到了“粗粒度”。我怀疑内核“关闭文件”代码中有一个特殊的钩子。至少,如果您想监视许多文件,这似乎是您所需要的。您考虑几个?

The original post suggested a really large project, with a lot of unspecified features. Your 'expanded motivation' ending with '... detecting directory copies and renames ...' was helpful.

First, you pretty much answered your own post with the references to File System Events and Kernel Queues. You were correct to dismiss Folder Actions, but for the wrong reason. You seemed concerned with activating FAs for a large number of folders. That is not a problem, because it could be automated. The reason FAs won't work is that they can't detect a file rename. Also, there is a huge problem with overhead and concurrency because the actions are AppleScript.

And you were correct about FS Events: (from Darwin Docs)

The important point to take away is
that the granularity of notifications
is at a directory level. It tells you
only that something in the directory
has changed, but does not tell you
what changed.

So it seems you are left with Kernel Queues. They do everything. Note that you will have to be clever to use Kernel Queues- you have to know the name of a flie to monitor it. So as new files/folders are created, you will have to interpret the events, and open (O_EVTONLY) the new files. However, there is a problem: (more Darwin Docs)

If you are monitoring a large
hierarchy of content, you should use
file system events instead, however,
because kernel queues are somewhat
more complex than kernel events, and
can be more resource intensive because
of the additional user-kernel
communication involved.

Another reply had mentioned that TimeMachine used FS Events. I doubt that because of the noted 'coarse granularity'. I suspect that there is a special hook in the kernel 'close file' code. At least, that is what it seems you need if you want to monitor many files. How many are you considering?

新一帅帅 2024-08-24 08:44:22

听起来文件系统事件就是您想要的。也许您因为它看起来很复杂而回避它,但我认为您想要做的事情总体来说很复杂。

Spotlight 和 Time Machine 使用文件系统事件来确定文件系统中发生的更改,从而确定哪些文件需要索引或备份。您的要求类似,只是您想要检查更新的目录是否存在于源代码管理中,而不是备份,如果不存在,则确定是否应将某些内容(新目录或标签或其他内容)添加到源代码管理中。

可能有一种方法可以在 Finder 中执行此操作,但您可能还想知道用户是否从命令行或其他程序复制目录。

您能更详细地介绍一下您使用此功能的动机吗?听起来您正在尝试使用户能够“使用”源代码管理,而无需实际学习它。 “只需复制目录,集成代码就会处理一切。”但我认为您在尝试将非常一般的文件系统更改解释为隐式源代码控制命令时会遇到问题。

It sounds like file system events is what you want. Maybe you're shying away from it because it seems complicated, but I think that what you're trying to do is complicated in general.

Spotlight and Time Machine use file system events in order to determine what's changed in the file system and therefore what files need to be indexed or backed up. Your requirement is similar, only instead of backing up, you want to check if the updated directories exist in source control, and if not, determine if something (either the new directories or a tag or whatever) should be added to source control.

There's probably a way to do this just within the Finder, but you probably also want to know if a user copies a directory from the command line or from some other program.

Could you go into some more detail about your motivation for this feature? It sounds like you're trying to enable users to "use" source control without actually having to learn it. "Just copy the directory and the integration code will take care of everything." But I think that you'll run into problems trying to do interpret very general filesystem changes as implicit source control commands.

仅此而已 2024-08-24 08:44:22

如果您只想在某些文件夹上触发此脚本,那么您应该使用 Apple 所谓的“文件夹操作”,您可以将其附加到您喜欢 Apple 脚本的任何文件夹。

我不知道 Finder 到底会触发什么,但如果我有我的 Mac,我知道我会打开自动化程序并在“文件和文件夹”下查看,我 100% 你会在那里找到一个复制或复制的事件。

If all you want is to trigger this script on some folders, then you should use what Apple calls "Folder Action" you can attach to whichever folder you like an apple script.

I don't know what the exact even the Finder will trigger but if I had my mac with me know I would open automater and look under "Files and Folders" I am 100% you will find an event for duplication or copying there.

后来的我们 2024-08-24 08:44:22

在自动化脚本中,查找器/系统中没有“重复”和“重命名”事件,因此您所要求的正是需要使用文件系统事件(我不会涉及),但以下快速 applescript

  • 捕获添加到文件夹中的所有项目(包括通过重复添加的项目)
  • 要求用户提供标签名称
  • ,使用此信息运行 bash 脚本,

这将使您能够构建一个好的解决方案

  1. ,将 additem.scpt 放置在/Library/Scripts/Folder Action Scripts
  2. fixup.sh 位于包含 trunk 的文件夹中(或调整并放在您喜欢的位置)
  3. ,右键单击并选择“文件夹操作设置...”
  4. 使用新脚本
  5. 编辑 连接该文件夹fixup.sh 以满足您的需求

additem.scpt

on adding folder items to this_folder after receiving added_items
        try
                tell application "Finder"
                        set the folder_name to the name of this_folder
                end tell

                set the item_count to the number of items in the added_items

                repeat with an_added_item in added_items
                        tell application "Finder"
                                set item_name to name of an_added_item
                        end tell

                        set new_name to text returned of (display dialog "Please enter tag name " default answer item_name buttons {"Continue…"} default button 1)

                        set the scriptcode to "\"" & POSIX path of this_folder & "fixup.sh\" \"" & POSIX path of an_added_item & "\" \"" & new_name & "\""
                        display dialog scriptcode
                        do shell script scriptcode
                end repeat
        end try
end adding folder items to

fixup.sh

#!/bin/bash

if [ -d "$1" ]
then
  echo asked to fixup \"$1\" >> /tmp/fixup.log
fi

there are no "on duplicate" and "on rename" events from the finder/system in automator scripts, so exactly what you are asking for requires using filesystem events (which I'm not going to get in to) but the following quick applescript

  • catches all items added to the folder (including those added by duplication)
  • asks the user to provide a tag name
  • runs a bash script with this info

which should enable you to build a good solution

  1. place additem.scpt in /Library/Scripts/Folder Action Scripts
  2. fixup.sh in the folder containing trunk (or adjust and put where you like)
  3. on the containing folder, right click and select "Folder Action Setup..."
  4. connect the folder with the new script
  5. edit fixup.sh to suit your needs

additem.scpt

on adding folder items to this_folder after receiving added_items
        try
                tell application "Finder"
                        set the folder_name to the name of this_folder
                end tell

                set the item_count to the number of items in the added_items

                repeat with an_added_item in added_items
                        tell application "Finder"
                                set item_name to name of an_added_item
                        end tell

                        set new_name to text returned of (display dialog "Please enter tag name " default answer item_name buttons {"Continue…"} default button 1)

                        set the scriptcode to "\"" & POSIX path of this_folder & "fixup.sh\" \"" & POSIX path of an_added_item & "\" \"" & new_name & "\""
                        display dialog scriptcode
                        do shell script scriptcode
                end repeat
        end try
end adding folder items to

fixup.sh

#!/bin/bash

if [ -d "$1" ]
then
  echo asked to fixup \"$1\" >> /tmp/fixup.log
fi
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文