applescript将文本传递到python脚本stdout的位被截断

2024-04-23 19:15:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用applescript将字符串传递给python脚本(我的最终用途是处理来自icloud的注释)。然而,由于某种原因,当我尝试用print语句测试东西时,它会产生奇怪的结果。你知道吗

以下是applescript:

set s to "here is a

long string

with

line breaks"

do shell script "python t3.py " & quoted form of s

这是t3.py:

import sys 
print("about to print whole argument list") 
print(sys.argv)
print("printed whole argument list")

当我调用调用python脚本的applescript时,会打印出一些非常奇怪的东西:

printed whole argument listng string\n\nwith\n\nline breaks']

但是,如果我注释掉python脚本的最后一行,它会打印:['t3.py', 'here is a \n\nlong string\n\nwith\n\nline breaks'],这是最接近正确的(它只会删除第一个预期的打印)。你知道吗

我的第一个假设是,这是Python端的某种流缓冲,因此我在每个print调用中添加了flush=True。输出没有变化。你知道吗

这到底是怎么回事?我使用的是python3.6.4。你知道吗


Tags: topy脚本stringhereissysargument
1条回答
网友
1楼 · 发布于 2024-04-23 19:15:53

您遇到了文本中换行符编码不一致的问题。不同的操作系统以不同的方式表示文本中的行尾:unix(和类似macOS的unix衍生工具)使用换行符(有时写为\n);DOS(和衍生工具行窗口)使用换行符,后跟回车符(\n\r);老式macOS(在OSX之前)只使用回车符(\r)。你知道吗

AppleScript可以追溯到Mac OS的OSX之前,并且仍然使用回车。当与其他操作系统交谈时,它有时会转换成unix约定,但并不总是这样。这里发生的事情是,python脚本正在生成带有换行符的输出,AppleScript的do shell script命令正在捕获其输出并转换为回车约定,而它永远不会被转换回来。当它被发送到终端时,回车使它返回到第1列,而不是下一行,所以输出的每一行都被打印在最后一行的上面。你知道吗

如何修复(或者是否需要修复)取决于更大的上下文,即您实际要对输出做什么。在许多上下文中(包括仅在命令行上运行),您可以通过tr '\r' '\n\管道将输出中的回车转换回新行:

$ osascript t3.applescript 
printed whole argument listg string\n\nwith\n\nline breaks']
$ osascript t3.applescript | tr '\r' '\n'
about to print whole argument list
['t3.py', 'here is a\n\nlong string\n\nwith\n\nline breaks']
printed whole argument list

编辑:至于如何让AppleScript用unix风格的分隔符生成结果。。。我看不出简单的方法,但是可以使用文本替换函数from here将CR转换为LF:

on replaceText(find, replace, subject)
    set prevTIDs to text item delimiters of AppleScript
    set text item delimiters of AppleScript to find
    set subject to text items of subject

    set text item delimiters of AppleScript to replace
    set subject to subject as text
    set text item delimiters of AppleScript to prevTIDs

    return subject
end replaceText


set s to "here is a

long string

with

line breaks"

set CRstring to do shell script "python t3.py " & quoted form of s

set LFstring to replaceText("\r", "\n", CRstring)

您还可以创建一个专用函数:

on CR2LF(subject)
    set prevTIDs to text item delimiters of AppleScript
    set text item delimiters of AppleScript to "\r"
    set subject to text items of subject

    set text item delimiters of AppleScript to "\n"
    set subject to subject as text
    set text item delimiters of AppleScript to prevTIDs

    return subject
end CR2LF

相关问题 更多 >