I want to call this terminal command on macOS in python lsappinfo info -only name
. It returns the name of the current foreground application.lsappinfo front
Here is how I understand the command:
lsappinfo
return information about running appsinfo
allows to select specific data
select the foreground processlsappinfo front
name
select the name of the process only
And here is my current code:
import subprocess
sub = subprocess.Popen(['lsappinfo', 'info', '-only', 'name', '`lsappinfo front`'])
out, err = sub.communicate()
print(err)
print(out)
But I get:
>>> None
>>> None
The expected output of the command is
"LSDisplayName"="AppName"
I succeed using os.system()
but I want to achieve it with subprocess
since it's the recommended way and I want to store the output. Does someone know how to do it?
CodePudding user response:
did you check if is needed any special permission?
what is the output if you write your command in a .sh file, and then execute the command as ["./{myscript}.sh"]
or so (remember to add x perms)?
CodePudding user response:
this works:
cmd1 = ['lsappinfo', 'front']
name = subprocess.run(cmd1, shell=False, capture_output=True).stdout.decode('utf-8').strip("\n")
cmd2 = ['lsappinfo', 'info', '-only', "name", name]
out2 = subprocess.run(cmd2, shell=False, capture_output=True)
print(out2.stdout.decode('utf-8').strip("\n"))
subprocess
has issues with bash evals (the backticks). Same with grep
.
You need to do it in 2 steps in your python code. Bit of a workaround but it works.
Output:
$ python test.py
"LSDisplayName"="Code"
(Edit: added the strip for the \n
at the end.)
Use this in a function and you're good to go.
Note: It returns "Code" for me since I ran it in VSCode, which was in the foreground at that moment.
CodePudding user response:
The command you actually want to run is:
lsappinfo info -only name $(lsappinfo front)
which calls lsappinfo front
to get the ASN of the front process and then passes the result to a second call to lsappinfo
to get the name of that process.
The key issue here is that the shell calls the two processes for you, so you would have to use the shell in your Python subprocess
call to do the same... or you would have to do a second subprocess
call per @Remzinho.
The single step method is:
import subprocess as sp
res = sp.run('lsappinfo info -only name $(lsappinfo front)', shell=True)
Note that backticks are deprecated and $(...)
should be preferred. The latter, newer method is also nestable.
lsappinfo info -only name `lsappinfo front` # worse
lsappinfo info -only name $(lsappinfo front) # better
CodePudding user response:
do it with zsh directly better !