0

how can I write/append to a file by calling nano using subprocess and get it saved automatically .For example I have a file and I want to open it and append something at the end of it so I write

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

Now once the last line gets executed the file gets open and I can write anything and then save it by hitting Ctrl+O and Ctrl+X

Instead I want that I send the input through a stdin PIPE and and the file gets saved by itself ie there could be any mechanism that hits Ctrl+O and Ctrl+X automayically by itself ?

Can help me in solving this issue ?

saurabh
  • 293
  • 2
  • 7
  • 19
  • What is it you are trying to achieve here would it not be better to read the file in to the program and then write to it then write it out to a file again. – bobthemac Aug 10 '14 at 10:18
  • 1
    First, why do you want to use `nano` for this? – abarnert Aug 10 '14 at 10:18
  • I want to append files by taking user input remotely so if there is anything else apart from naon plz suggest. – saurabh Aug 10 '14 at 10:24
  • @saurabh: How are you planning to get the user input? You want them to type directly into `nano`? If so, how do you know when they're done, so you can send ^O^X? On the other hand, if you're taking their input directly in your script and appending it to a file, just append it to the file directly in your script; what's `nano` adding? – abarnert Aug 10 '14 at 10:26
  • I need to append some text values by taking inputs from users remotely and append those to files that needs root prmissions so I'll be using subprocess module therefore, calling open() directly doesn't works.So How can this be achieved? – saurabh Aug 10 '14 at 10:34
  • 1
    @saurabh: How does running `nano` help you with permissions? Because you `sudo` it? If so, why can't you just `sudo` another Python script? Or `sed` or some other simpler tool than `nano`? – abarnert Aug 10 '14 at 10:36
  • If you cannot call `open()` directly, then running `nano` directly will also not work. (For example, if you are allowed to read but not to write to the file, then opening for writing will fail, and *saving* with `nano` will also fail, even if can open for *reading* in `nano`.) – Dan Getz Aug 10 '14 at 10:53
  • Thats why I was using subprocess I mean I was going to call subprocess.Popen(['sudo') before nano. Is there any other method more sophisticated than this possible? – saurabh Aug 10 '14 at 11:03
  • 1
    @saurabh: Running `['sudo']` first, and then running `['nano']`, won't help anything. You'd have to run `['sudo', 'nano']`. And if you can do that for `nano`, you can do exactly the same thing for `sed`, or for `python`. – abarnert Aug 10 '14 at 11:36
  • You may want to read [What is the XY problem?](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Describe what you're actually trying to do, and then why you think driving `nano` might be the solution, rather than describing your problems driving `nano`. – abarnert Aug 10 '14 at 11:40

2 Answers2

1

A ctrl-O is just a character, same as any other. You can send it by writing '\x0f' (or, in Python 3, b'\x0f').

However, that probably isn't going to do you any good. Most programs that provide an interactive GUI in the terminal, like nano, cannot be driven by stdin. They need to take control of the terminal, and to do that, they will either check that stdin isatty and then tcsetattr it, or just open /dev/tty,

You can deal with this by creating a pseudo-terminal with os.openpty, os.forkpty, or pty.

But it's often easier to use a library like pexpect to deal with interactive programs, GUI or otherwise.

And it's even easier to not try to drive an interactive program in the first place. For example, unlike nano, ed is designed to be driven in "batch mode" by a script, and sed even more so.

And it's even easier to not try to drive a program at all when you're trying to do something that can be just as easily done directly in Python. The easiest way to append something to a file is to open it in 'a' mode and write to it. No need for an external program at all. For example:

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

If the only reason you were using nano is because you needed something to sudo… there's really no reason for that. You can sudo anything else—like sed, or another Python script—just as easily. Using nano is just making things harder for yourself for absolutely no reason.


The big question here is: why do you have a file that's not writable by your Python script, but which you want arbitrary remote users to be able to append to? That sounds like a very bad system design. You make files non-writable because you want to restrict normal users from modifying them; if you want your Python script to be able to modify it on behalf of your remote users, why isn't it owned by the same user that the script runs as?

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • I need to append some text values by taking inputs from users remotely and append those to files that needs root prmissions so I'll be using subprocess module therefore, calling open() directly doesn't works.So How can this be achieved? – saurabh Aug 10 '14 at 10:31
  • you run your main process using sudo - and then open will work - spawning another process which runs an editor just to write a few lines to a file is overkill. – Tony Suffolk 66 Aug 10 '14 at 11:11
0

In the (unlikely) event that you still find that you need to control nano or some other interactive program from a Python process, I'm going to suggest the same thing here that I suggested for this question: Using python subprocess.call() to launch an ncurses process ...

... don't use subprocess for controlling curses/full-screen interactive processes. use pexpect. That's what it's for.

(On the other hand I also agree with the many comments here regarding better ways to work around the permissions issue. Write some sort of script (in Python, bash, sed or whatever) which can be run under sudo and which can make the in-place edits or appendices to your data file directly.

Community
  • 1
  • 1
Jim Dennis
  • 17,054
  • 13
  • 68
  • 116