我正在尝试使用applescript将字符串传递给python脚本(我的最终用途是处理来自icloud的注释)。但是由于某种原因,当我尝试使用打印语句测试事物时,它会产生奇怪的结果。
这是小标题:
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方面讲这是某种流缓冲,所以我在每个打印调用中都添加了flush=True
。输出无变化。
这到底是怎么回事?我正在使用python 3.6.4。
答案 0 :(得分:2)
您会遇到文本换行符编码不一致的麻烦。不同的操作系统以不同的方式在文本中指示行尾:unix(以及macOS等unix派生词)使用换行符(有时写为\n
); DOS(以及Windows的派生行)使用换行符,后跟回车符(\n\r
);和老式Mac OS(在OS X之前)仅使用回车符(\r
)。
AppleScript可以追溯到Mac OS的OS X以前的日期,并且仍使用回车符。与操作系统的其余部分通信时,有时会有时转换为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