Python file path in Windows - python

I am using Windows 10.
I have this code,
script_dir = os.path.dirname(__file__)
temp = cs(os.path.join(script_dir+"first.txt"),
os.path.join(script_dir+"second.text"),
os.path.join(script_dir+"third.txt"))
It executes in git bash, but it throws an error in powershell and cmd.
How can I fix this code, so that I can execute this code in anywhere?
============================================================
Edit:
it says, it cannot find .first.txt and following files.
It also throws this error,
DLL load failed: The specified module could not be found.
============================================================
Edit2:
cs is a class I created.
class cs:
info = {}
result = {}
def __init__(self, first, second, third, output=None):
self.output = ""
self.first = first
self.second = second
self.third = third
def decrypt(self):
pass
I don't know why it works in git bash, but not in powershell and cmd

The correct code is
script_dir = os.path.dirname(__file__)
temp = cs(os.path.join(script_dir, "first.txt"),
os.path.join(script_dir, "second.text"),
os.path.join(script_dir, "third.txt"))
What you are doing wrong, is adding "first.txt" etc to script_dir, and passing that to os.path.join. os.path.join, however, takes multiple arguments (any number of arguments) and joins them together in the correct way. What your code did, is add those strings together, making: script_dirfirst.txt, which would explain why it couldn't find the file.

Related

Python subprocess.run can't find /bin/sh in chroot

(First off, apologies for the roughness of this question's writing-- would love any constructive feedback.)
Ok what I'm doing is a bit involved-- I'm trying to make a Python script that executes Bash scripts that each compile a component of a Linux From Scratch (LFS) system. I'm following the LFS 11.2 book pretty closely (but not 100%, although I've been very careful to check where my deviations break things. If you're familiar with LFS, this is a deviation that breaks things).
Basically, my script builds a bunch of tools (bash, tar, xz, make, gcc, binutils) with a cross compiler, and tells their build systems to install them into a directory lfs/temp-tools. Then the script calls os.chroot('lfs') to chroot into the lfs directory, and immediately resets all the environment variables (most importantly PATH) with:
os.environ = {"PATH" : "/usr/bin:/usr/sbin:/temp-tools/bin", ...other trivial stuff like HOME...}
But after the chroot, my calls of
subprocess.run([f"{build_script_path} >{log_file_path} 2>&1"], shell=True)
are failing with FileNotFoundError: [Errno 2] No such file or directory: '/bin/sh', even though
bin/sh in the chroot directory is a sym link to bash
there's a perfectly good copy of bash in /temp-tools/bin
calling print(os.environ) after the python chroot shows /temp-tools/bin is in PATH
I thought maybe subprocess.run is stuck using the old environment variables, before I reset them upon entering the chroot, but adding env=os.environ to subprocess.run does not help. :/ I'm stuck for now
For context if it helps, here is where the subprocess.run call gets made:
def vanilla_build(target_name, src_dir_name=None):
def f():
nonlocal src_dir_name
if src_dir_name == None:
src_dir_name = target_name
tarball_path = find_tarball(src_dir_name)
src_dir_path = tarball_path.split(".tar")[0]
if "tcl" in src_dir_path:
src_dir_path = src_dir_path.rsplit("-",1)[0]
snap1 = lfs_dir_snapshot()
os.chdir(os.environ["LFS"] + "srcs/")
subprocess.run(["tar", "-xf", tarball_path], check=True, env=os.environ)
os.chdir(src_dir_path)
build_script_path = f"{os.environ['LFS']}root/build-scripts/{target_name.replace('_','-')}.sh"
log_file_path = f"{os.environ['LFS']}logs/{target_name}"
####### The main call #######
proc = subprocess.run([f"{build_script_path} >{log_file_path} 2>&1"],
shell=True, env=os.environ)
subprocess.run(["rm", "-rf", src_dir_path], check=True)
if proc.returncode != 0:
red_print(build_script_path + " failed!")
return
tracked_file_record_path = f"{os.environ['LFS']}logs/tracked/{target_name}"
with open(tracked_file_record_path, 'w') as f:
new_files = lfs_dir_snapshot() - snap1
f.writelines('\n'.join(new_files))
f.__name__ = "build_" + target_name
return f
And how I enter the chroot:
def enter_chroot():
os.chdir(os.environ["LFS"])
os.chroot(os.environ["LFS"])
os.environ = {"HOME" : "/root",
"TERM" : os.environ["TERM"],
"PATH" : "/usr/bin:/usr/sbin:/temp-tools/bin",
"LFS" : '/'}
Thank you! In the meantime I'm going to chop away as much code as possible to isolate the problem to either understand whatever I'm not getting or rewrite this question to be less context specific

Reading TDMS files in python_ how to use tdmsinfo command?

I would like to know what is the content of a tdms file, which is produced by Labview.
Following this site, I write in Python:
import numpy as np
from nptdms import TdmsFile
from nptdms import tdms
#read a tdms file
filenameS = "RESULTS.tdms"
tdms_file = TdmsFile(filenameS)
tdmsinfo [--properties] tdms_file
I receive the following error:
tdmsinfo [--properties] tdms_file
^
SyntaxError: invalid syntax
I do not how to fix it.
Thank you for your help :)
What you are looking for is:
First create a TMDS objet from file:
tdms_file = TdmsFile("C:\\Users\\XXXX\\Desktop\\xx Python\\XXXX.tdms")
then get the group names with:
tdms_groups = tdms_file.groups()
after you can figure out which group names you have into the file, just write
tdms_groups
It will print the following:
['Variables_1', 'Variables_2', 'Variables_3', 'Variables_4', etc..]
With group names now u will be able to get channels with the following:
tdms_Variables_1 = tdms_file.group_channels("Variables_1")
Next print your channels contain into that group:
tdms_Variables_1
It will show:
[ TdmsObject with path /'Variables_1'/'Channel_1', TdmsObject with path /'Variables_1'/'Channel_2', etc..]
At the end get the vectors and its data:
MessageData_channel_1 = tdms_file.object('Variables_1', 'Channel_1')
MessageData_data_1 = MessageData_channel_1.data
Check your data
MessageData_data_1
do stuff with your data!
cheers!
To loop over all properties from the root object try this:
#read a tdms file
filenameS = "RESULTS.tdms"
tdms_file = TdmsFile(filenameS)
root_object = tdms_file.object()
# Iterate over all items in the properties dictionary and print them
for name, value in root_object.properties.items():
print("{0}: {1}".format(name, value))
That should give you all properties names.
Your problem seems to be that tdmsinfo will not work inside a Python script as it is not a python command: it's "a command line program".
The solution is to either use 'tdmsinfo' from a windows shell, or make a wrapper in python so that it runs the command in a subprocess for you. For instance in Python3 with the subprocess package
import subprocess
tdmsfile='my_file.tdms'
# startup info to hide the windows shell
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
#si.wShowWindow = subprocess.SW_HIDE # default
# run tdmsinfo in a subprocess and capture the output in a
a = subprocess.run(['tdmsinfo',tdmsfile],
stdout=subprocess.PIPE,
startupinfo=si).stdout
a = a.decode('utf-8')
print(a)
the code above should give you only the channels and groups, but you can also run with the -p flag to include all the TDMS object properties
a = subprocess.run(['tdmsinfo','-p',tdmsfile],
stdout=subprocess.PIPE,
startupinfo=si).stdout

Python failing to create symlinks

I'm trying to use python to make symbolic links. When I try to use os.symlink I get a WinError 5 "Access is denied" error, but if I try to create the same symlink using mklink, it works fine. (I'm running this as an administrator, and have the 'Create symbolic links' privilege.)
I then to use subprocess.call to call mklink directly with the proper arguments and such, and it runs without any errors, yet when it's finished the symlinks have not been created.
When I try to use Popen to run the command I get a 'system cannot find the file specified' error even though the directory is there.
This is on Windows Server 2008.
def createStudentFolders(studentList):
grad_year = input("Please enter the year of graduation for the class of students being created (i.e. 2016): ")
for student in studentList:
student = student.replace(" ","") # Gets rid of the white space in the name
studentPath = 'cpwd/{}'.format(student)
try:
os.mkdir(studentPath)
except:
pass
print(studentPath)
proc = Popen("icacls {} /inheritance:e /grant STUDENT\{}:(OI)(CI)F /T".format(studentPath, student))
classFolder = "students/ClassOf{}".format(grad_year)
try:
os.mkdir(classFolder)
except:
pass
os.symlink('{}/{}'.format(classFolder, student), studentPath, target_is_directory=True)
print("Done")
def main():
newStudentsLoc = "newStudents.txt"
studentList = readStudentsToList(newStudentsLoc)
createStudentFolders(studentList)
main()
input("Pausing")
File resides in Z:\
inside that are
cpwd\<student folders>
students\ClassOf<Year>\<symlinks to student folders go here>
I've tried using absolute paths as well with no luck.

How to create symlinks in windows using Python?

I am trying to create symlinks using Python on Windows 8. I found This Post and this is part of my script.
import os
link_dst = unicode(os.path.join(style_path, album_path))
link_src = unicode(album_path)
kdll = ctypes.windll.LoadLibrary("kernel32.dll")
kdll.CreateSymbolicLinkW(link_dst, link_src, 1)
Firstly, It can create symlinks only when it is executed through administrator cmd. Why is that happening?
Secondly, When I am trying to open those symlinks from windows explorer I get This Error:
...Directory is not accessible. The Name Of The File Cannot Be Resolved By The System.
Is there a better way of creating symlinks using Python? If not, How can I solve this?
EDIT
This is the for loop in album_linker:
def album_Linker(album_path, album_Genre, album_Style):
genre_basedir = "E:\Music\#02.Genre"
artist_basedir = "E:\Music\#03.Artist"
release_data_basedir = "E:\Music\#04.ReleaseDate"
for genre in os.listdir(genre_basedir):
genre_path = os.path.join(genre_basedir, "_" + album_Genre)
if not os.path.isdir(genre_path):
os.mkdir(genre_path)
album_Style_list = album_Style.split(', ')
print album_Style_list
for style in album_Style_list:
style_path = os.path.join(genre_path, "_" + style)
if not os.path.isdir(style_path):
os.mkdir(style_path)
album_path_list = album_path.split("_")
print album_path_list
#link_dst = unicode(os.path.join(style_path, album_path_list[2] + "_" + album_path_list[1] + "_" + album_path_list[0]))
link_dst = unicode(os.path.join(style_path, album_path))
link_src = unicode(album_path)
kdll = ctypes.windll.LoadLibrary("kernel32.dll")
kdll.CreateSymbolicLinkW(link_dst, link_src, 1)
It takes album_Genre and album_Style And then It creates directories under E:\Music\#02.Genre . It also takes album_path from the main body of the script. This album_path is the path of directory which i want to create the symlink under E:\Music\#02.Genre\Genre\Style . So album_path is a variable taken from another for loop in the main body of the script
for label in os.listdir(basedir):
label_path = os.path.join(basedir, label)
for album in os.listdir(label_path):
album_path = os.path.join(label_path, album)
if not os.path.isdir(album_path):
# Not A Directory
continue
else:
# Is A Directory
os.mkdir(os.path.join(album_path + ".copy"))
# Let Us Count
j = 1
z = 0
# Change Directory
os.chdir(album_path)
Firstly, It can create symlinks only when it is executed through administrator cmd.
Users need "Create symbolic links" rights to create a symlink. By default, normal users don't have it but administrator does. One way to change that is with the security policy editor. Open a command prompt as administrator, run secpol.msc and then go to Security Settings\Local Policies\User Rights Assignment\Create symbolic links to make the change.
Secondly, When I am trying to open those symlinks from windows explorer I get This Error:
You aren't escaping the backslashes in the file name. Just by adding an "r" to the front for a raw string, the file name changes. You are setting a non-existant file name and so explorer can't find it.
>>> link_dst1 = "E:\Music\#02.Genre_Electronic_Bass Music\1-800Dinosaur-1-800-001_[JamesBlake-Voyeur(Dub)AndHolyGhost]_2013-05-00"
>>> link_dst2 = r"E:\Music\#02.Genre_Electronic_Bass Music\1-800Dinosaur-1-800-001_[JamesBlake-Voyeur(Dub)AndHolyGhost]_2013-05-00"
>>> link_dst1 == link_dst2
False
>>> print link_dst1
E:\Music\#02.Genre_Electronic_Bass Music☺-800Dinosaur-1-800-001_[JamesBlake-Voyeur(Dub)AndHolyGhost]_2013-05-00
os.symlink works out of the box since python 3.8 on windows, as long as Developer Mode is turned on.
If you're just trying to create a link to a directory, you could also create a "Junction", no admin privileges required:
import os
import _winapi
src_dir = "C:/Users/joe/Desktop/my_existing_folder"
dst_dir = "C:/Users/joe/Desktop/generated_link"
src_dir = os.path.normpath(os.path.realpath(src_dir))
dst_dir = os.path.normpath(os.path.realpath(dst_dir))
if not os.path.exists(dst_dir):
os.makedirs(os.path.dirname(dst_dir), exist_ok=True)
_winapi.CreateJunction(src_dir, dst_dir)

Python - create object of class from one package in different package

I started using Python few days back and I think I have a very basic question where I am stuck. Maybe I am not doing it correctly in Python so wanted some advice from the experts:
I have a config.cfg & a class test in one package lib as follows:
myProj/lib/pkg1/config.cfg
[api_config]
url = https://someapi.com/v1/
username=sumitk
myProj/lib/pkg1/test.py
class test(object):
def __init__(self, **kwargs):
config = ConfigParser.ConfigParser()
config.read('config.cfg')
print config.get('api_config', 'username')
#just printing here but will be using this as a class variable
def some other foos()..
Now I want to create an object of test in some other module in a different package
myProj/example/useTest.py
from lib.pkg1.test import test
def temp(a, b, c):
var = test()
def main():
temp("","","")
if __name__ == '__main__':
main()
Running useTest.py is giving me error:
...
print config.get('api_config', 'username')
File "C:\Python27\lib\ConfigParser.py", line 607, in get
raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'api_config'
Now if I place thie useTest.py in the same package it runs perfectly fine:
myProj/lib/pkg1/useTest.py
myProj/lib/pkg1/test.py
myProj/lib/pkg1/config.cfg
I guess there is some very basic package access concept in Python that I am not aware of or is there something I am doing wrong here?
The issue here is that you have a different working directory depending on which module is your main script. You can check the working directory by adding the following lines to the top of each script:
import os
print os.getcwd()
Because you just provide 'config.cfg' as your file name, it will attempt to find that file inside of the working directory.
To fix this, give an absolute path to your config file.
You should be able to figure out the absolute path with the following method since you know that config.cfg and test.py are in the same directory:
# inside of test.py
import os
config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'config.cfg')

Categories