I have been looking all over the internet for a way to find a way to get UUID for a computer and set it as a variable in python.
Some of the ways I tried doing didn't work.
Original idea:
import os
x = os.system("wmic diskdrive get serialnumber")
print(x)
However this does not work, and only returns 0.
I am wondering if their is a way i can find a unique Harddrive ID or any other type of identifier in python.
The os.system function returns the exit code of the executed command, not the standard output of it.
According to Python official documentation:
On Unix, the return value is the exit status of the process encoded in the format specified for wait().
On Windows, the return value is that returned by the system shell
after running command.
To get the output as you want, the recommended approach is to use some of the functions defined in the subprocess module. Your scenario is pretty simple, so subprocess.check_output works just fine for it.
You just need to replace the code you posted code with this instead:
import subprocess
x = subprocess.check_output('wmic csproduct get UUID')
print(x)
If the aim is to get the serial number of the HDD, then one can do:
In Linux (replace /dev/sda with the block disk identifier for which you want the info):
>>> import os
>>> os.popen("hdparm -I /dev/sda | grep 'Serial Number'").read().split()[-1]
In Windows:
>>> import os
>>> os.popen("wmic diskdrive get serialnumber").read().split()[-1]
for windows i do work with this one and it works perfectly:
import subprocess
UUID = str(subprocess.check_output('wmic csproduct get UUID'),'utf-8').split('\n')[1].strip()
print(UUID)
For windows:
import wmi
import os
def get_serial_number_of_system_physical_disk():
c = wmi.WMI()
logical_disk = c.Win32_LogicalDisk(Caption=os.getenv("SystemDrive"))[0]
partition = logical_disk.associators()[1]
physical_disc = partition.associators()[0]
return physical_disc.SerialNumber
For Linux try this:
def get_uuid():
dmidecode = subprocess.Popen(['dmidecode'],
stdout=subprocess.PIPE,
bufsize=1,
universal_newlines=True
)
while True:
line = dmidecode.stdout.readline()
if "UUID:" in str(line):
uuid = str(line).split("UUID:", 1)[1].split()[0]
return uuid
if not line:
break
my_uuid = get_uuid()
print("My ID:", my_uuid)
Related
I have the following program that wraps top in a pseudo terminal and prints it back to the real terminal.
import os
import pty
import subprocess
import sys
import time
import select
stdout_master_fd, stdout_slave_fd = pty.openpty()
stderr_master_fd, stderr_slave_fd = pty.openpty()
p = subprocess.Popen(
"top",
shell=True,
stdout=stdout_slave_fd,
stderr=stderr_slave_fd,
close_fds=True
)
stdout_parts = []
while p.poll() is None:
rlist, _, _ = select.select([stdout_master_fd, stderr_master_fd], [], [])
for f in rlist:
output = os.read(f, 1000) # This is used because it doesn't block
sys.stdout.write(output.decode("utf-8"))
sys.stdout.flush()
time.sleep(0.01)
This works well control sequences are handled as expected. However, the subprocess is not using the full dimensions of the real terminal.
For comparison, running the above program:
And running top directly:
I didn't find any api of the pty library to suggest dimensions could be provided.
The dimensions I get in practice for the pseudo terminal are height of 24 lines and width of 80 columns, I'm assuming it might be hardcoded somewhere.
Reading on Emulate a number of columns for a program in the terminal I found the following working solution, at least on my environment (OSX and xterm)
echo LINES=$LINES COLUMNS=$COLUMNS TERM=$TERM
which comes to LINES=40 COLUMNS=203 TERM=xterm-256color in my shell. Then setting the following in the script gives the expected output:
p = subprocess.Popen(
"top",
shell=True,
stdout=stdout_slave_fd,
stderr=stderr_slave_fd,
close_fds=True,
env={
"LINES": "40",
"COLUMNS": "203",
"TERM": "xterm-256color"
}
)
#Mugen's answer pointed me in the right direction but did not quite work, here is what worked for me personally :
import os
import subprocess
my_env = os.environ.copy()
my_env["LINES"] = "40"
my_env["COLUMNS"] = "203"
result = subprocess.Popen(
cmd,
stdout= subprocess.PIPE,
env=my_env
).communicate()[0]
So I had to first get my entire environment variable with os library and then add the elements I needed to it.
The solutions provided by #leas and #Mugen did not work for me, but I eventually stumbled upon ptyprocess Python module, which allows you to provide terminal dimensions when spawning a process.
For context, I am trying to use a Python script to run a PowerShell 7 script and capture the PowerShell script's output. The host OS is Ubuntu Linux 22.04.
My code looks something like this:
from ptyprocess import PtyProcessUnicode
# Run the PowerShell script
script_run_cmd = 'pwsh -file script.ps1 param1 param2'
p = PtyProcessUnicode.spawn(script_run_cmd.split(), dimensions=(24,130))
# Get all script output
script_output = []
while True:
try:
script_output.append(p.readline().rstrip())
except EOFError:
break
# Not sure if this is necessary
p.close()
I feel like there should be a class method to get all the output, but I couldn't find one and the above code works well for me.
I want to use netstat -nb in python but every code that i write i get the same msg: "The requested operation requires elevation."
The last code that i try is
import os
output_command = os.popen("netstat -nb").readlines()
and i try also
import subprocess
program_list = subprocess.run(["netstat", "-nb"], stdout=subprocess.PIPE).stdout.decode("utf-8")
program_list = program_list.split("\r\n")
import os
a=os.popen('netstat -nb').read()
print("\n Connections ",a )
try this, it's working!
The docs of shutil tells me:
Even the higher-level file copying functions (shutil.copy(), shutil.copy2()) can’t copy all file metadata. On POSIX platforms, this means that file owner and group are lost as well as ACLs
How can I keep the file owner and group if I need to copy a file in python?
The process runs on linux as root.
Update: We don't use ACLs. We only need to keep the stuff which is preserved with tools like tar and rsync.
You perhaps could use os.stat to get the guid and uid like in this answer and then reset the uid and guid after coping using os.chown.
I did it this way:
import os
import stat
import shutil
def copyComplete(source, target):
# copy content, stat-info (mode too), timestamps...
shutil.copy2(source, target)
# copy owner and group
st = os.stat(source)
os.chown(target, st.st_uid, st.st_gid)
You can use the subprocess module:
from subprocess import Popen
p = Popen(['cp','-p','--preserve',src,dest])
p.wait()
See Keeping fileowner and permissions after copying file in C on how cp itself does this, then just replicate its logic. Python has all the system calls mentioned in its os module.
I suggest you use the OS and subprocess modules. This will only work in Unix, but it should work well. Use the os.fchown to change file ownership, and subprocess.Popen() to pipe ls -l into a variable to read ownership. For one file, the permissions reader would look like this:
import os
import subprocess
def readfile(filepath):
process = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE)
output = process.communicate()[0]
output = output.split()
return (output[0],output[1]) #insert into this tuple the indexing for the words you want from ls -l
and for the uid setter (just a wrapper for os function):
def setuid(filepath,uid,gid):
os.chown(filepath,uid,gid)
as #Thom Wiggers 's answer
os.stat get uid,gid
os.chmod set uid,gid
demo code:
import os
st = os.stat(src_path)
os.chown(dst_path, st.st_uid, st.st_gid)
check except:
import os
def copy_owner_group(src, dst):
try:
st = os.stat(src)
except Exception as e:
print 'stat except:', e
else:
try:
os.chown(dst, st.st_uid, st.st_gid)
except Exception as e:
print 'chmod except:', e
I am using os.system to submit a command to the system.
I.e.,
import os
os.system(my_cmd)
But I was wondering how could I obtain the output, i.e., let us say i am in the bash and I type in my cmd, I'd get an output of this form:
Job <57960787> is submitted to queue <queueq>.
How can I, in python, using the os.system(cmd), also obtain the text output, and parse it to obtain the job id, 57960787.
Thanks!
It is better to use the subprocess module documentation here, example below:
import subprocess,re
p = subprocess.Popen('commands',stdout=subprocess.PIPE,stderr=subprocess.PIPE)
results, errors = p.communicate()
print results
re.search('<(\d+)>', results).group(1) #Cheers, Jon Clements
Or you can even use os.popen documentation here,
p_os = os.popen("commands","r")
line = p_os.readline()
print line
re.search('<(\d+)>', line).group(1) #Cheers, Jon Clements
Or as John Clements kindly suggested, you can use subprocess.check_output, Documentation here
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
A simple example:
>>> import os, sys
>>> cmd = "uname"
>>> b = os.popen(cmd, 'r', 1)
>>> b.read()
'Linux\n'
I am running Linux uname command.
os.popen() executes command and return a file type object using that you can read command's output.
os.system does not return output. So instead you can use the commands module.
Example:
import commands
my_cmd = 'ls -l'
status, output = commands.getstatusoutput(my_cmd)
print output
There is an external program A.
I want to write a script that does some action if the called external program A does not bring up any output(stout).
How is this possible in bash or python?
You can use the subprocess module which allows you to execute system calls and store its output in variables which can be used later on.
#!/usr/bin/python
import subprocess as sub
ur_call = '<your system call here>'
p = sub.Popen(ur_call, stdout=sub.PIPE,stderr=sub.PIPE)
output, errors = p.communicate()
if len(output) == 0 and len(errors) == 0:
pass # Do something
In a Bash-script, you could redirect the output to a file, and if the length of the file is zero then there was no output.
If the script that sometimes gives output is no.sh then you can do this in Python:
import os
x = os.popen("./no.sh")
y = x.read()
if y:
print "Got output"