【问题标题】:Calling python script from TCL and creating a file atomically从 TCL 调用 python 脚本并原子地创建文件
【发布时间】:2018-01-16 09:01:06
【问题描述】:

我编写了一个 python 脚本,负责以原子方式创建文件,如other question 中所述。脚本创建的文件有点大(大约 1.5MB),如下所示:

$ ./my_script.py --output_file some_directory/my_file.txt
$ ls -l --block-size=K some_directory/my_file.txt
-rw------- 1 foouser foogroup 1477K Aug  7 17:39 some_directory/my_file.txt

不幸的是,由于一些遗留基础设施和设置方式,需要从 TCL 脚本中调用此脚本。这是我目前这样做的方式:

#!/usr/bin/env tclsh
set PY_SCRIPT my_script.py
puts [exec $PY_SCRIPT --output some_directory/my_file.txt]

我看到的问题是生成的文件似乎不再是原子创建的(原子性是我的应用程序的要求)。 TCL puts command documentation 表示以下内容:

Tcl 在内部缓冲输出,因此用 puts 写入的字符可能不会 立即出现在输出文件或设备上; Tcl 通常会 延迟输出,直到缓冲区满或通道关闭。

我相信这解释了为什么我的文件不再以原子方式创建。我不是 TCL 专家,所以我不确定如何在 TCL 脚本中完成原子文件创建。

有什么建议吗?

【问题讨论】:

  • 为什么需要puts?您仍在使用 my_script.py 来生成您需要的所有输出,对吧?你不应该在 tcl 中执行那个脚本吗?
  • 您知道这种大小的文件通常不是原子写入的吗?真正原子写入的通常大小约为 16 kB,尽管操作系统可能会提供模拟原子性的视图。由于防病毒软件的影响(通常会破坏写入的原子性),Windows 上的一切都更加明显。
  • @DonalFellows 根据他们的链接问题,OP 似乎在滥用原子写入的概念来简单地表示“要么全部或不写入文件”。

标签: python file tcl atomic


【解决方案1】:

我想你想要的只是flush stdout

【讨论】:

    【解决方案2】:

    您链接到的 Python 代码的直接翻译是这样的(未经测试的代码):

    package require Tclx
    
    set f [open $tmpFile w]
    puts -nonewline $f $text
    sync $f    ; # flush is performed implicitly
    close $f
    
    file rename -force $tmpFile $myFile
    

    需要 TclX 包来获取sync 命令。 (这可能不适用于 Windows。)

    【讨论】:

    • flush $f 在这里(没有 TclX 依赖)不足以清除缓冲区; rename 将满足 all-writes-or-none 的要求吗?
    • @mrcalvin:不再确定:我现在大部分时间都将 Tcl 抛在脑后,仅通过查看代码我无法弄清楚这一点。对不起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    相关资源
    最近更新 更多