This is relatively simple matter but for some reason I cannot find a way to get the full path of the windows temp directory via python or to find similar request already posted in stack overflow community.
I'm using tempfile.gettempdir() command but it seems there is no way to capture the full path and it returns the short version:
'C:\Users\SVETLO~1\AppData\Local\Temp'
This overall works but there is an important part of the script later on which doesn't and it requires the full temp dir path, which is:
C:\Users\SvetlozarDraganov\AppData\Local\Temp\
Does anyone knows how to get the full absolute path to windows-temp folder with python?
Thanks in advance.
Svet
Edit-1:
I'm testing the %fA suggestion from CMD but for some reason, it doesn't work. If I'm using %sA attribute it actually returns the short path version:
CMD: for %A in ("C:\Users\SvetlozarDraganov\AppData\Local\Temp") do #echo %~sA
OUTPUT: C:\Users\SVETLO~1\AppData\Local\Temp
The %fA attribute however doesn't return the full path:
CMD: for %A in ("C:\Users\SVETLO~1\AppData\Local\Temp") do #echo %~fA
OUTPUT: C:\Users\SVETLO~1\AppData\Local\Temp
Speaking of full absolute path, you already have it.
The "short version" is the 8.3 filename that exists before VFAT and the "full path" as you meant it is the "long filename" or LFN. They are interchangable so long as accessing the file in concern.
In Windows command prompt, you can use parameter expansions to convert from short to long and back. See the solution here for an example (replace %~sA in the answer with %~fA in your case). So you can make use of that and call the command with subprocess.run() to read the output.
I can't recall Python has a built-in function for doing this conversion. But Windows API does: You may want to see how this solution for converting LFN to short filename, which in your case, the function should be GetLongPathName() instead.
I found a out-of-the-box solution to my question in python os module:
https://docs.python.org/2/library/os.path.html#os.path.realpath
It returns the long-version path!
Thanks to everybody!
Related
I am working together with a colleague and he has Ubuntu while I have windows. We have a dataset of json files which have in them a "path" written. His paths look like this:
'C:/Users/krock/Desktop/FIIT/BP/Ubuntu/luadb/etc/luarocks_test/modules/30log/share/lua/5.3/30log.lua'
But this doesn't work on Windows, I was trying to do
some_string.replace('/', '\\')
But this results in strings written in json that look like this:
'C:\\Users\\krock\\Desktop\\FIIT\\BP\\Ubuntu\\luadb\\etc\\luarocks_test\\data_all'
On my windows machine, I can't read (the program) these paths as it give an error:
No such file or directory
Is there a solution to this?
EDIT: I tried using Path from pathlib, but I got another error saying:
TypeError: Object of type WindowsPath is not JSON serializable
I found the solution to this is to do str(Path(path_string)), but the result is again the path in double quotes.
Yes, the solution is to use Python's built in pathlib. Also, using string literals might help the clarity of your program.
https://docs.python.org/3/library/pathlib.html
This question is missing code samples, so can't be more specific, but generally speaking, doing this manually is error-prone. Consider using a library, such as pathlib. E.G:
>>> from pathlib import Path
>>> Path('luarocks_test/modules/30log/share/lua/5.3/30log.lua')
PosixPath('luarocks_test/modules/30log/share/lua/5.3/30log.lua')
On Windows, instantiating a Path would give you a WindowsPath. You'll also want to use relative, rather than absolute references, as the paths will be different on your workstations.
I'm trying to automate our personal folder creation using a IDM system that runs on Python. All user shares will be created on \\\server\personal\%userID%. The \\\server\personal and %userID% are being passed as default_settings.home_directory and profileid. The code I'm trying as this :
share = self.config.getID('default_settings.home_directory') + profileid
self.log.info('Share = [{0}]'.format(share))
os.makedirs(share)
In the log I have
Share = [\\server\personal\xr2829]
but it errors out with
WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: '\\\\'
Try this alternative:
os.makedirs(os.path.join(self.config.getID('default_settings.home_directory'), profileid))
Should take care of slash/backslash confusion
I'm going to guess that there's a null character after the // in your configuration string. Python won't care, but the C function backing os.makedirs will stop on a null. Try logging repr(share) which will give a more detailed representation of the string.
Edit: Looking at the os.makedirs function more closely suggests another possibility. The path is being broken down into components so that each one can be checked or created as needed. The error message implies that the first two slashes (\\\\ when displayed using repr) have been broken out as the first directory element. The documentation says that UNC paths are supported as of version 2.3, but perhaps you're using a very old Python version or there's still a bug.
I have been trying to delete some symbolic links in my working directory, but I am facing some issues.
os.remove also removes the actual contents of the original folder of the link
os.shutil throws up an error in case of symbolic links.
Is there a way to remove a symbolic link using python commands without destroying the original content?
Thanks
os.unlink() works for me. It removes the symlink without removing the directory that it links to.
The accepted answer does not work on Windows with links created via mklink /D. If that is your problem the answer has been posted in this question: Delete Symlink to directory on Windows
The following code should work on both systems:
if(os.path.isdir(targetLink)):
os.rmdir(targetLink)
else:
os.unlink(targetLink)
Sorry,my Bad, I had made a stupid programming mistake : I was stupidly deleting the source instead of the links.
The correct answer is by #samfrances.
os.unlink does the trick.
In addition to this, here some other tips if you want to clear a directory using python:
Definitely not threadsafe, but you get the idea...
def rm(obj):
if os.path.exists(obj):
if os.path.isdir(obj):
if os.path.islink(obj):
os.unlink(obj)
else:
shutil.rmtree(obj)
else:
if os.path.islink(obj):
os.unlink(obj)
else:
os.remove(obj)
in Python 3.4 and above,
If link is a file, use unlink().
>>> from pathlib import Path
>>> p = Path('/some/file/')
>>> p.unlink()
If the path points to a directory, use Path.rmdir() instead.
>>> from pathlib import Path
>>> p = Path('/some/dir/')
>>> p.rmdir()
If the directory name contains a trailing slash, the linux rm command will follow the link and try to delete the directory. See Remove a symlink to a directory. The os.remove documentation says that it will give you an OSError if you try to remove a directory but maybe that doesn't always happen in the case of symlinks.
From the documentation:
os.path.realpath(path)
Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path (if they are supported by the
operating system).
When I invoke this with an extant file's name, I get the path to it: /home/myhome/myproject.
When I invoke this with a 'nonsense.xxx' string argument, I still get a path to /home/myhome/myproject/nonsense.xxx. This is a little inconsistent because it looks like nonsense.xxx is taken to be a directory not a file (though it is neither: it does not exist).
When I invoke this with a null string file name, I still get a path to /home/myhome/myproject.
How can I account for this behaviour when the documentation says so little about realpath()? (I am using Python 2.5.)
Edit: Somebody suggested a way to test if files exist. My concern is not to test if files exist. My concern is to account for behaviour.
os.path isn't interested in whether or not the files exist. It is merely concerned with constructing paths.
realpath eliminates known symlinks from the equation, but directories that do not exist are assumed to be valid elements of a path regardless.
Rather than guess, just read the code! It's there in your python installation. Or browse here, it's only 14 lines minus comments.
Place test such as "os.path.isfile(x)", "x is not None" and "os.path.isdir(x)" before the call?
when i give
ls -l /etc/fonts/conf.d/70-yes-bitmaps.conf
lrwxrwxrwx <snip> /etc/fonts/conf.d/70-yes-bitmaps.conf -> ../conf.avail/70-yes-bitmaps.conf
so for a symbolic link or soft link, how to find the target file's full(absolute path) in python,
If i use
os.readlink('/etc/fonts/conf.d/70-yes-bitmaps.conf')
it outputs
../conf.avail/70-yes-bitmaps.conf
but i need the absolute path not the relative path, so my desired output must be,
/etc/fonts/conf.avail/70-yes-bitmaps.conf
how to replace the .. with the actual full path of the parent directory of the symbolic link or soft link file.
os.path.realpath(path)
os.path.realpath returns the canonical path of the specified filename, eliminating any symbolic links encountered in the path.
As unutbu says, os.path.realpath(path) should be the right answer, returning the canonical path of the specified filename, resolving any symbolic links to their targets. But it's broken under Windows.
I've created a patch for Python 3.2 to fix this bug, and uploaded it to:
http://bugs.python.org/issue9949
It fixes the realpath() function in Python32\Lib\ntpath.py
I've also put it on my server, here:
http://www.burtonsys.com/ntpath_fix_issue9949.zip
Unfortunately, the bug is present in Python 2.x, too, and I know of no fix for it there.
http://docs.python.org/library/os.path.html#os.path.abspath
also joinpath() and normpath(), depending on whether you're in the current working directory, or you're working with things elsewhere. normpath() might be more direct for you.
Specifically:
os.path.normpath(
os.path.join(
os.path.dirname( '/etc/fonts/conf.d/70-yes-bitmaps.conf' ),
os.readlink('/etc/fonts/conf.d/70-yes-bitmaps.conf')
)
)
I recommend using pathlib library for filesystem operations.
import pathlib
x = pathlib.Path('lol/lol/path')
x.resolve()
Documentation for Path.resolve(strict=False): make the path absolute, resolving any symlinks. A new path object is returned.
On windows 10, python 3.5, os.readlink("C:\\Users\PP") where "C:\Users\PP" is a symbolic link (not a junction link) works.
It returns the absolute path to the directory.
This works on Ubuntu 16.04, python 3.5 as well.
The documentation says to use os.path.join():
The result may be either an absolute or relative pathname; if it is relative, it may be converted to an absolute pathname using os.path.join(os.path.dirname(path), result).