There are a few concepts to unpack:
Working directory
When a Python script is run, it usually starts with cwd
(current working directory) as the pwd
(present working directory) of the invoking shell.
So assuming we have a script /tmp/sub/print_cwd.py
:
#!/usr/bin/env python3
from os import getcwd
print(getcwd())
Then we get the following outputs (with the part before the $
being the shell's current directory):
/tmp/sub$ python3 print_cwd.py
/tmp/sub
/tmp$ python3 sub/print_cwd.py
/tmp
<other location>$ python3 /tmp/sub/print_cwd.py
<other location>
File paths
They can be relative (from cwd) or absolute (from root a.k.a. /
or C:\
)
- Relative paths can:
- go deeper e.g. to
sub/print_cwd.py
from /tmp
,
- higher, using
../
, or
- any combination of the two e.g. to
../../tmp/sub/print_cwd.py
from /home/user
(up 2 levels to /
, then back down, into tmp
)
PATH
To address the problem of I don't know where everyone keeps their binaries/exe's
, there is something called PATH (echo $PATH
to see what yours is).
The tl;dr is that if a binary is in a folder on PATH, you can call it with only the binary name, e.g. hashcat.exe
Putting it together
So what your script (or any shell, for that matter) does, when you specif a filename (binary for execution, but also for file-reads) is check:
- is there a file with this name in my
pwd
?
- is there a file with this name [in a folder] on
PATH
?
- Error: file not found
When you specify an absolute path, it knows exactly where to go, so it only looks there.
...What to do in your case?
Options:
- leave it to the user to ensure
hashcat.exe
is in a folder that is on their PATH, or
- Accept a location for
hashcat.exe
as a cli-argument to your script, then
- call
hashcat.exe
with an absolute path, or
- change your pwd to
hashcat.exe
's location with os.chdir()
NOTE: Option #1 was @chepner's suggestion, in an OP-comment.