1

I'm trying to write a script which uses the os command(linux) and save them in the text file. But when I try to run this code the output of the os command is not saved in the text file.

#!/usr/bin/python
import sys
import os


target = raw_input('Enter the website : ')
ping_it = os.system('ping ' + target)
string_it = str(ping_it)

with open("Output.txt", "w+") as fo:
        fo.write(string_it)
        fo.close()

After running the script when I check txt file the only thing I get is no 2 in the Output.txt.

petezurich
  • 9,280
  • 9
  • 43
  • 57
Dhananjay
  • 15
  • 4

3 Answers3

2

Welcome to Stackoverflow.

The main issue here is that os.system is not designed to produce the output from the command - it simply runs it, and the process sends its output to whatever it inherits from its parent (your program).

To capture output it's easiest to use the subprocess module, which allows you to capture the process's outputs.

Here's a fairly simple program that will get you started:

import subprocess

target = 'google.com'
ping_it = subprocess.Popen('ping ' + target,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
out, err = ping_it.communicate()

with open("Output.txt", "w+") as fo:
        fo.write(str(out))
        fo.close()

If you want to read output as it is produced rather than waiting for the subprocess to terminate you can use a single subprocess.PIPE channel and read from that, which is conveniently expressed in forms like this:

with Popen(["ping", "google.com"], stdout=PIPE) as proc:
    print(proc.stdout.read())

In this example I chose to give the command as a list of arguments rather than as a simple string. This avoids having to join arguements into a string if they are already in list form.

Note that when interacting with subprocesses in this way it's possible for the subprocess to get in a blocked state because either stdout or stderr has filled up its output buffer space. If your program then tries to read from the other channel that will create a deadlock, where each process is waiting for the other to do something. To avoid this you can make stderr a temporary file, then verify after subprocess completion that the file contains nothing of significance (and, ideally, remove it).

holdenweb
  • 33,305
  • 7
  • 57
  • 77
0

Exactly what are you trying to save in the file? You did save the output of os.command, which is nothing more than the final status of the execution. This is exactly what the documentation tells you is the return value of that command.

If you want the output of the ping command, you need to use something that focuses on ping, not on os.command. The simple way is to add UNIX redirection:

os.system('ping ' + target + '&> Output.txt')

If you feel a need to pass the results through Python, use a separate process and receive the command results; see here.

You can also spawn a separate process and examine the results as they are produced, line by line. You don't seem to need that, but just in case, see my own question here.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

From docs you can use os.popen to assign output of any command to a variable.

import os
target = raw_input('Enter the website : ')

output = os.popen('ping ' + target).read()   # Saving the output

with open('output.txt', 'w+') as f:
    f.write(output)
Santosh Karki
  • 77
  • 1
  • 9
  • Note that the use of `os.popen` and its peers for such purposes has been deprecated for a long time - there are [notes in the documentation for Python 2](https://docs.python.org/2.7/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3) about how to replace such outdated usages. – holdenweb May 21 '19 at 09:09
  • Further, note that the end of the documentation to which this answer links says _"Availability: Unix, Windows. spawnlp(), spawnlpe(), spawnvp() and spawnvpe() are not available on Windows. spawnle() and spawnve() are not thread-safe on Windows; we advise you to use the subprocess module instead."_ – holdenweb Jun 04 '19 at 09:59