防止AppleScript脚本在使用传递的参数时更改其自己的修改日期

防止AppleScript脚本在使用传递的参数时更改其自己的修改日期,applescript,osx-lion,Applescript,Osx Lion,我有一个AppleScript脚本,我用它在我的桌面上用GeekTool显示iTunes曲目信息。我在runargv上使用向脚本传递不同的参数,这样我就可以在不复制脚本的情况下显示曲目信息的不同部分(例如,我可以通过运行osascript itunes.scpt title来获取标题,通过运行osascript itunes.scpt album来获取艺术家/专辑) 但是,每次我运行带有参数的脚本时,实际的文件修改日期都会发生更改,这似乎是脚本在向自身写入内容或进行某种修改 这通常不是问题,除了

我有一个AppleScript脚本,我用它在我的桌面上用GeekTool显示iTunes曲目信息。我在runargv上使用
向脚本传递不同的参数,这样我就可以在不复制脚本的情况下显示曲目信息的不同部分(例如,我可以通过运行
osascript itunes.scpt title
来获取标题,通过运行
osascript itunes.scpt album
来获取艺术家/专辑)

但是,每次我运行带有参数的脚本时,实际的文件修改日期都会发生更改,这似乎是脚本在向自身写入内容或进行某种修改

这通常不是问题,除了在OSX10.7中,Lion为超过2周未修改的文件引入了文件锁定。一旦我的iTunes脚本被操作系统锁定,它在运行时就不能再进行这些不可见的自我更新,我的系统日志中就会出现如下错误:

osascript: couldn't save changes to script /path/to/script: error -54
我可以通过手动修改脚本(例如添加空行)暂时解决这个问题,但两周后,由于Lion将其锁定,所有问题再次出现

理论上,我可以在系统范围内禁用文件锁定来解决这个问题,但我不希望——我喜欢在其他方面使用它

那么,如何在运行argv时使用
向AppleScript文件传递参数,而不更改脚本的修改日期呢

这里有一个简单的工作示例。如果从命令行(
oscascript test.scpt blah
)运行此脚本,脚本的修改日期将更改

--test.scpt
on run argv
    tell application "iTunes"
        if player state is playing then
            set trck to current track
            set title_text to (get name of trck)
            return title_text & " " & item 1 of argv
        end if
    end tell
end run

您可以尝试通过stdin将脚本馈送到
osascript
,而不是直接读取脚本

osascript - args < /path/to/script 
你需要破折号(参见
osascript
的手册页)

但是,我无法复制修改时更新的行为(我在雪豹上),所以我不知道这是否会有任何不同。但是它可能会工作,因为
osascript
与文件没有直接联系(如果确实是
osascript
的错误)


在任何情况下都会出现奇怪的问题

除了在常规AppleScript(而不是Xcode变体)中定义的属性外,所有全局变量都是持久的,并与脚本一起保存(至少在重新编译之前)。这包括运行处理程序中定义的项目(显式或隐含),例如:

on run
    try
        display dialog someVariable -- will error the first time
    on error -- set global
        beep
        set someVariable to time string of (current date)
    end try
end run

您可以尝试将代码移动到处理程序中,以便不设置或更改全局变量。

Hrm。这两个选项都给了我这个错误:
0:13:语法错误:实数不能跟在这个标识符后面。(-2740)
。但如果我在
osascript
手册页中的超级简单示例
a.scpt
上尝试使用该语法,也会出现同样的错误。@Andrew Word。我在发布之前测试了这两个命令,它们在雪豹上运行得很好。。。但您的原始命令也是如此。@Andrew:A
.scpt
文件不仅仅是一个脚本,它包含文本形式的脚本代码,还包含预编译形式的脚本,所有内容都以二进制格式存储。如果告诉
osascript
读取脚本文件,它知道如何从
.scpt
文件中提取纯脚本,但通过
STDIN
馈送数据时,它需要纯脚本代码(ASCII),而不是脚本文件的内容。脚本编辑器中以纯文本形式存储的脚本没有扩展名
.scpt
,而是
.applescript
,只是人类可读的脚本源。@Andrew尝试一下这个
osacodecompile a.scpt | osascript-Andrew
@Mecki谢谢你,这对我很有用!我不知道在这种情况下,哪些变量是持久的和全局的?
运行
处理程序中的任何内容,或者iTunes过程中设置的内容?我会将所有iTunes内容移动到一个单独的处理程序中,然后从内部调用它吗?
run
?运行处理程序中定义的所有变量(如trck和title_text)都是全局变量。将整个过程移动到一个单独的处理程序中,并从运行处理程序中调用它应该可以做到这一点,因为这些变量将是本地的,并且不会与脚本一起保存。谢谢你演示这个。我能够在不将代码放入单独的处理程序的情况下修复该问题。只需在运行处理程序的顶部添加“localsomevariable”。执行此操作时,“显示对话框”不会显示,脚本的修改日期也不会更改。太棒了。把所有的东西都转移到一个新的处理器上,效果非常好。
run
是唯一一个使所有内容都像这样全局化的处理程序,还是有其他内置处理程序会导致此问题?我还没有测试所有其他预定义的处理程序(打开的处理程序按预期工作-变量是局部的,除非另有声明),但我猜运行处理程序是一个特例,因为它不必显式声明。
on run
    try
        display dialog someVariable -- will error the first time
    on error -- set global
        beep
        set someVariable to time string of (current date)
    end try
end run