Issue using open() in python with a linux global variable

Viewed 72

I trying to open and read a file with open() in python, with the global variable $USER in Linux, but the program stops in the 2 line. I want to believe that the problem is in the open() function because I use $USER in the 1 line and all is ok:

os.system("/usr/bin/nmap {target} -oN /home/$USER/.nmap_diff/scan{today}.txt")
scantxt = open("/home/$USER/.nmap_diff/scan{today}.txt","rb")

The output is:

File "diffscanner.py", line 92, in scanner
  scantxt = open("/home/$USER/.nmap_diff/scan{}.txt".format(today),"rb")
FileNotFoundError: [Errno 2] No such file or directory: '/home/$USER/.nmap_diff/scan2021-07-10.txt'

The output said the scan2021-07-10.txt has not found, but it really exist: scan2021-07-10.txt

2 Answers

os.system executes the command(passed as string) in a subshell. That means, the command will have access to the Linux's environment variables, USER in your case.

On the other hand, open expects a path-like object such as a path string. The string is read as it is and not evaluated to replace USER(or any other environment variable) with actual values. If you want to use env var, use os.environ

import os

USER = os.environ['USER']

scantxt = open(f"/home/{USER}/.nmap_diff/scan{today}.txt","rb")

The problem is that $USER is being interpreted as a literal string by open, not as an environment variable. To expand environment variables in the string, use os.path.expandvars.

os.system(f"/usr/bin/nmap {target} -oN /home/$USER/.nmap_diff/scan{today}.txt")
result_path = os.path.expandvars(f"/home/$USER/.nmap_diff/scan{today}.txt")
with open(result_path, "r", encoding="utf-8") as f:
    scantxt = f.read()

By the way, it also looks like the strings in your question were meant to be f-strings, but were missing the f prefixes. I have added them in my answer.

Also, I am assuming that you want the scan results as a string, so I have added the code for that as well. (It seems that nmap doesn't usually include any non-ascii characters in its output for the -oN option, but I am specifying the encoding as UTF-8 in case support for UTF-8 characters is added in a future version.)

Related