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

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

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

Safely echo python commands into file without executing them

So I have a python file with a ton of lines in it that I want to read into python then echo into another file over a socket.
Assuming I have file foo.py
import os
os.popen('some command blah')
print("some other commands, doesn't matter")
Then I try and open the file, read all the lines, and echo each line into a new file.
Something along the lines of
scriptCode = open(os.path.realpath(__file__)).readlines()
for line in scriptCode:
connection.send("echo " + line + " >> newfile.py")
print("file transfered!")
However, when I do this, the command is executed in the remote shell.
So my question:
How do I safely echo text into a file without executing any keywords in it?
What have I tried?
Adding single quotes around line
Adding single quotes around line and then a backslash to single quotes in line
Things I've considered but haven't tried yet:
Base64 encoding the line until on the remote machine then decoding it (I don't want to do this because there's no guarentee it'll have this command)
I know this is odd. Why am I doing this?
I'm building a pentesting reverse shell handler.
shlex.quote will:
Return a shell-escaped version of the string s. The returned value is a string that can safely be used as one token in a shell command line, for cases where you cannot use a list.
Much safer than trying to quote a string by yourself.

Ghostcript destination name with blank space returns error [duplicate]

I have a main file which uses(from the main I do a source) a properties file with variables pointing to paths.
The properties file looks like this:
TMP_PATH=/$COMPANY/someProject/tmp
OUTPUT_PATH=/$COMPANY/someProject/output
SOME_PATH=/$COMPANY/someProject/some path
The problem is SOME_PATH, I must use a path with spaces (I can't change it).
I tried escaping the whitespace, with quotes, but no solution so far.
I edited the paths, the problem with single quotes is I'm using another variable $COMPANY in the path
Use one of these threee variants:
SOME_PATH="/mnt/someProject/some path"
SOME_PATH='/mnt/someProject/some path'
SOME_PATH=/mnt/someProject/some\ path
I see Federico you've found solution by yourself.
The problem was in two places. Assignations need proper quoting, in your case
SOME_PATH="/$COMPANY/someProject/some path"
is one of possible solutions.
But in shell those quotes are not stored in a memory,
so when you want to use this variable, you need to quote it again, for example:
NEW_VAR="$SOME_PATH"
because if not, space will be expanded to command level, like this:
NEW_VAR=/YourCompany/someProject/some path
which is not what you want.
For more info you can check out my article about it http://www.cofoh.com/white-shell
You can escape the "space" char by putting a \ right before it.
SOME_PATH=/mnt/someProject/some\ path
should work
If the file contains only parameter assignments, you can use the following loop in place of sourcing it:
# Instead of source file.txt
while IFS="=" read name value; do
declare "$name=$value"
done < file.txt
This saves you having to quote anything in the file, and is also more secure, as you don't risk executing arbitrary code from file.txt.
If the path in Ubuntu is "/home/ec2-user/Name of Directory", then do this:
1) Java's build.properties file:
build_path='/home/ec2-user/Name\\ of\\ Directory'
Where ~/ is equal to /home/ec2-user
2) Jenkinsfile:
build_path=buildprops['build_path']
echo "Build path= ${build_path}"
sh "cd ${build_path}"

use Python to open a file in read mode

I am trying to open a file in read mode using Python. The error I am receiving suggest I am using the won filename or read mode. When I type the file path into my computer, it works. I tried to assign the input filename to a variable and then opening the variable in read mode. I also tried typing in the full path and opening the path in read mode. Both game me an error.
Code:
workingDirec = raw_input("What is the working directory?")
original_file = raw_input("The input filename is?")
def calculateZscore():
"Z score calc"
full_original = os.path.join(workingDirec,original_file)
print full_original
f = open ('C:\Users\tpmorris\ProgramingAndScripting\Trial 2 Data\Trial 2 Data\NCSIDS_ObsExp.txt','r')
print f
My results:
Using full path output:
What is the working directory?C:\Users\tpmorris\ProgramingAndScripting\Trial 2 Data\Trial 2 Data
The input filename is?NCSIDS_ObsExp.txt
C:\Users\tpmorris\ProgramingAndScripting\Trial 2 Data\Trial 2 Data\NCSIDS_ObsExp.txt
IOError: [Errno 22] invalid mode ('r') or filename: 'C:\Users\tpmorris\ProgramingAndScripting\Trial 2 Data\Trial 2 Data\NCSIDS_ObsExp.txt'
Using variable output:
IOError: [Errno 2] No such file or directory: 'full_original'
On Windows your paths must be escaped because Windows uses backslashes \ to denote path separators.
Backslashes however are typically used as escape sequences and are used in Python as such as well! So you have to "escape" them like this:
f = open ('C:\\Users\\tpmorris\\ProgramingAndScripting\\Trial 2 Data\\Trial 2 Data\\NCSIDS_ObsExp.txt','r')
See:
Windows path in Python
Using Python on Windows
Firstly , on Windows, you must escape backslashes (double backslash) if you are going to use Windows path syntax, for the reasons pointed out by #James Mills answer.
Another option is to use forward slashes; Python will interpret these correctly in os.path.
You could use as your command line path input:
C:/Users/tpmorris/ProgramingAndScripting/Trial 2 Data/Trial 2 Data
Or add
/NCSIDS_ObsExp.txt
to the above if you were going to use a hardcoded path.
Also you should make some small changes to your code if you want to print the contents of your text file:
First, your file open should be done using a with statement. This will ensure the file object's built in __enter__ and __exit__ methods get called, in particular, if you forget to close the file when you are done after you've opened it.
See Understanding Python's with statement for more.
Second, if you want to print each line in your text file, don't try to print the file object. Rather loop through the lines and print them.
So your code for accepting command line input should be:
import os
workingDirec = raw_input("What is the working directory?")
original_file = raw_input("The input filename is?")
full_original = os.path.join(workingDirec,original_file)
print full_original
with open(full_original,'r') as f:
for line in f:
print line
f.close()
I removed the def of a function to do something else in the midst of your file read code. That def should go elsewhere.

'invalid argument' error opening file (and not reading file)

I am trying to write code that takes 2 numbers in a text file and then divides them, showing the answer as a top heavy fraction. I have gotten the fractions part to work when I am inputting my own values in the program, but i cannot get the program to recognise the text file. I have tried putting them in the same directory and putting the full system path of the file, but nothing so far has worked. right now I am just trying to get the contents of the file to print.
with open('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Python 3.4\topheavy.txt','w') as f:
for line in f:
for word in line.split():
print(word)
I will then assign the 2 values to x and y, but I get this error:
Traceback (most recent call last):
File "C:\Python34\divider.py", line 2, in <module>
open('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Python 3.4\topheavy.txt','w')
OSError: [Errno 22] Invalid argument:'C:\\ProgramData\\Microsoft\\Windows\\Startmenu\\Programs\\Python 3.4\topheavy.txt'
open('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Python 3.4\topheavy.txt','w')
OSError: [Errno 22] Invalid argument:'C:\\ProgramData\\Microsoft\\Windows\\Startmenu\\Programs\\Python 3.4\topheavy.txt'
Two things:
When working with paths that contain backslashes, you either need to use two backslashes, or use the r'' form to prevent interpreting of escape sequences. For example, 'C:\\Program Files\\...' or r'C:\Program Files\...'.
Your error shows this: \\Startmenu\\. It appears that a space is missing between "Start" and "menu", despite the fact that the open line seems to have the right path.
Note: that the \topheavy.txt in your path is probably getting converted to <tab>opheavy.txt too. That's why there aren't two backslashes in front of it in the traceback.
You are using a "\" separator which is probably getting escaped somewhere (like that \t near the end. That's the Windows path separator, but also used as a string escape.
You can double up the "\" as "\". Easiest however is to prepend an r at the beginning to ignore .
r"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Python 3.4\topheavy.txt"
Skip the recommendation to use / instead, you are not on Unix and there is no reason Python can't accommodate Windows, as long as you remember to take care about "\" also being an escape. Using r' at start also allows you to copy/paste from the string into another program or vice-versa.
also, it wouldn't hurt to test in c:\temp or similar to avoid issues where you may have mistyped your path.
Last, but not least, you need to open in "r" read mode, as previously mentioned.
You should add one more "/" in the last "/" of path for example:
open('C:\Python34\book.csv') to open('C:\Python34\\\book.csv')
Reference
I had this same error appear when trying to read a large file in Python 3.5.4. To solve it, instead of reading the whole file into memory with .read(), I read each line one by one:
with open('big.txt') as f:
for i in f:
print(i)
Just as is written on the Python Documentation, the IOError Exception occurs:
Raised when an I/O operation (such as a print statement, the built-in
open() function or a method of a file object) fails for an I/O-related
reason, e.g., “file not found” or “disk full”.
Open with "r" (read) instead of "w" (write)
And startmenu in these two lines are different?? Try using a forward instead of a back slash. Python will convert the forward slash to the appropriate delimiter for the OS it is running on
open('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Python 3.4\topheavy.txt','w')
OSError: [Errno 22] Invalid argument:'C:\ProgramData\Microsoft\Windows\Startmenu\Programs\Python 3.4\topheavy.txt'
Replace every \ with \\ in file path
My issue, rather arbitrary, was I was writing a file using open(filename, "w").write(...), where filename is an invalid pathname or includes unexpected slashes.
For example, converting a datetime.datetime.today() into a datestring with slashes or colons (Windows) and writing to non-existing directories will result in this error.
Change:
open("../backup/2021/08/03 15:02:61.json", "w").write(data)
To:
open("../backup/2021-08-03 15-02-61.json", "w").write(backup)
As an example.

Passing Python variable to Powershell parameter using Python's Popen

I am calling a Powershell script within a Python script using Python's subprocess Popen. The Powershell script requires two input parameters: -FilePath and -S3Key. It uploads a file to AWS S3 server. If I pass in hard coded strings, the script works.
os.Popen([r'C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe','-ExecutionPolicy','RemoteSigned','./Upload.ps1 -FilePath \"C:\TEMP\test.txt\" -S3Key \"mytrialtest/test.txt\"'])
However, if I try to pass in Python string variable, the Powershell script errors out saying it can not find the file specified by the filename variable.
filename = 'C:\TEMP\test.txt'
uploadkey = 'mytrialtest/test.txt'
os.Popen([r'C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe','-ExecutionPolicy','RemoteSigned','./Upload.ps1 -FilePath \"filename\" -S3Key \"uploadkey\"'])
Any help would be greatly appreciated. Thanks.
I know, it's an old question, so this is for those who find this question via google:
The solution mentioned in comment has some risks (string injection) and might not work if there are special characters involved. Better:
import subprocess
filename = r'C:\TEMP\test.txt'
uploadkey = 'mytrialtest/test.txt'
subprocess.Popen(['powershell',"-ExecutionPolicy","RemoteSig‌​ned","-File", './Upload.ps1', '-FilePath:', filename , '-S3Key:', uploadkey])
Notice the : appended to the parameter names - in most cases it will also work without the :, but if the value starts with a dash, it will fail without the :.

Categories

Resources