使用subprocess用nano写入并保存文件

0 投票
2 回答
3876 浏览
提问于 2025-04-18 16:43

我想知道怎么通过调用nano这个编辑器来写入或追加内容到一个文件里,并且让它自动保存。例如,我有一个文件,想打开它并在最后加点东西,所以我会写:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile(mode='a')
>>> example = file.name
>>> f.close()
>>> import subprocess
>>> subprocess.call(['nano', example])

当最后一行代码执行完后,文件就会打开,我可以随便写东西,然后通过按Ctrl+O和Ctrl+X来保存。

不过,我希望能通过一个输入管道(stdin PIPE)来发送内容,这样文件就能自动保存,也就是说有没有什么方法可以让它自己按下Ctrl+O和Ctrl+X呢?

谁能帮我解决这个问题呢?

2 个回答

0

如果你真的需要从Python程序控制nano或者其他一些互动程序,我在这里建议的和我之前对这个问题的建议是一样的:使用python subprocess.call()来启动一个ncurses进程...

... 不要用subprocess来控制curses或全屏互动程序,应该用pexpect。这就是它的用途。

(另一方面,我也同意这里很多评论提到的更好的解决权限问题的方法。可以写一个脚本(用Python、bashsed或者其他语言)在sudo下运行,这样就可以直接对你的数据文件进行修改或添加内容。

1

Ctrl-O 只是一个字符,和其他字符一样。你可以通过写 '\x0f'(在 Python 3 中是 b'\x0f')来发送它。

不过,这样做可能没什么用。大多数在终端中提供交互式图形界面的程序,比如 nano,是不能通过标准输入(stdin)来控制的。它们需要控制终端,为此,它们会检查标准输入是否是一个终端(用 isatty),然后用 tcsetattr 来设置,或者直接打开 /dev/tty

你可以通过创建一个伪终端来解决这个问题,方法是使用 os.openptyos.forkpty 或者 pty

不过,使用像 pexpect 这样的库来处理交互式程序,通常会更简单,无论是图形界面程序还是其他类型的。

其实,最简单的办法就是根本不去控制一个交互式程序。例如,和 nano 不同,ed 是设计成可以通过脚本在“批处理模式”下运行的,sed 更是如此。

而且,当你想做的事情可以直接用 Python 完成时,根本就不需要去控制一个程序。向文件追加内容最简单的方法是用 open'a' 模式打开它,然后用 write 写入。根本不需要外部程序。例如:

new_line = input('What do you want to add?')
with open(fname, 'a') as f:
    f.write(new_line)

如果你使用 nano 只是因为你需要用 sudo 来做某事……那其实没有必要。你可以用 sudo 其他任何程序,比如 sed 或者另一个 Python 脚本,操作起来同样简单。使用 nano 只是在无谓地给自己增加难度。


这里最大的疑问是:为什么你有一个文件是你的 Python 脚本无法写入的,但你又希望任意远程用户能够向它追加内容?这听起来像是一个很糟糕的系统设计。你让文件不可写是因为你想限制普通用户修改它;如果你希望你的 Python 脚本能够代表远程用户修改它,为什么这个文件不属于脚本运行的同一个用户呢?

撰写回答