0

I want to run a program on Python on macOS Sierra that checks Terminal for its outputs after I automatically enter a command on it. For example, I would write in Terminal:

$ pwd

and then Terminal would output something like:

/Users/username

How would I have Python scan what Terminal outputs and set it to a variable as a string?

>>>output = (whatever Terminal outputs)
>>>print (output)
"/Users/username"

By the way, the other forums do not explain in much detail how one would do this in macOS. Therefore, this is not a duplicate of any forum.

  • You can manipulate `stdout` using `sys.stdout`. – cs95 Jul 31 '17 at 01:36
  • 4
    Possible duplicate of [Calling an external command in Python](https://stackoverflow.com/questions/89228/calling-an-external-command-in-python) – Silvio Mayolo Jul 31 '17 at 01:37
  • 1
    Are you trying to run `pwd` from within a Python script? (In that specific case, `os.getcwd()` is what you want.) Or do you want to hook your shell? Or Terminal.app specifically? It would help if you described what exactly you're trying to do... I suspect that this is an X-Y problem. – Daniel Pryden Jul 31 '17 at 01:39

2 Answers2

1

You could pipe the output to a file and read the file.

$ pwd > output.txt

Then read the file and take further actions based on its contents.

TomServo
  • 7,248
  • 5
  • 30
  • 47
  • Wow, that way actually helps a lot thanks! By the way, could you upvote my question? Because I guess people dislike questions when they can't answer them as sufficiently as you did. – Joseph Odeh Jul 31 '17 at 02:45
1

Use the subprocess module, it has some shortcut methods to make things easier and less complicated than using Popen.

>>> import subprocess
>>> output = subprocess.check_output("pwd")
>>> print(output)
b'L:\\\r\n'

You can decode this using output.decode("UTF-8") if you like or you can use the universal_newlines keyword argument to have it done automatically as well as sorting out newlines.

>>> subprocess.check_output("pwd", universal_newlines=True)
'L:\\\n'

Edit: With @Silvio's sensible suggestion, passing all arguments you can do the following:

subprocess.check_output(["ls", "-l"])

Or if you have a string sourced from elsewhere you can call .split() which will generate a list of substrings separated by a space.

subprocess.check_output("ls -l /".split())

Note: I'm using Python3 on Windows and Gnu on Windows so I have \r\n line endings and pwd.

import random
  • 3,054
  • 1
  • 17
  • 22
  • It works for "pwd" but it doesn't work for things like "ls /Applications" or "sudo pwd". Anything I could do to fix that? – Joseph Odeh Jul 31 '17 at 02:55
  • you can try adding `shell=True` to the function call. However there are [implications](https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess), so you should make sure you sanitise your inputs. – import random Jul 31 '17 at 03:03
  • 1
    As an alternative to `shell=True`, consider passing your arguments as a list. `subprocess.check_output(["sudo", "pwd"])`. That's a cleaner, safer way to invoke the shell. – Silvio Mayolo Jul 31 '17 at 03:05