call shell command from python - python

I have this shell command that I want to call from python
frontend='test'
instance_list = subprocess.call(['sudo gcloud compute instances list | grep -v TERMINA | grep +'frontend'+ | awk '{ print $1 }''])
I'm getting this error
instance_list = subprocess.call(['sudo gcloud compute instances list | grep -v TERMINA | grep +'frontend'+ | awk '{ print $1 }''])
^
SyntaxError: invalid syntax
What I'm doing wrong?

How about this:
frontend='test'
instance_list = subprocess.call(['sudo gcloud compute instances list | grep -v TERMINA | grep '+frontend+' | awk \'{ print $1 }\''])
You just did the string concatenation wrong: the plus needs to be outside of the quotes...
And the quotes for awk probably need to be escaped...

You should put the plus signs outside the quotation marks:
instance_list = subprocess.call(['sudo gcloud compute instances list | grep -v TERMINA | grep '+frontend+' | awk '{ print $1 }''])

I Think the problem is in the way you arranged your quotations and concatenation sign (+)
Concatenation works like: 'Hello' + variable + 'world'
Or when it is about escaping quotes inside (Which is probably not your case)
You can use triple quotes like xxx.call([''' You are free to use single quotes inside here ''']);
For your case, this can help:
instance_list = subprocess.call(['sudo gcloud compute instances list | grep -v TERMINA | grep ' + frontend + ' | awk '{ print $1 }''])

Related

Getting rid of extra printing in subprocess Python

I am trying to print my ip address using subprocess.run() in Linux. So , i wrote the following code:
ip=subprocess.run(["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"],shell=True,)
It gives me my Ip address "192.168.1.103" in terminal , but i wrote it "print(ip)" , it gives me : "CompletedProcess(args=["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"], returncode=0)"
I want the result ,i.e "192.168.1.103" when i wrote print(ip). So how can i do it ? Moreover when i wrote the followings in Pycharm , it gives me similar reply :
The code:
ip=subprocess.run(["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"],shell=True,)
print(ip)
The result:
192.168.1.103
CompletedProcess(args=["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"], returncode=0)
How can I obtain only Ip address without printing "CompletedProcess(args=["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"], returncode=0)" ?
You can save it to a temporary text file and load it back to the program like this:
import subprocess
ip=subprocess.run(["ifconfig | grep -w 'inet' | awk '{print $2}' | head -n 1"],shell=True, capture_output=True)
print((ip.stdout).decode('ascii').strip())
Output
"192.168.1.200"

How to run awk -F\' '{print $2}' inside subprocess.Popen in Python?

I need to run a shell command inside subprocess.Popen in Python.
The command is:
$ virsh dumpxml server1 | grep 'source file' | awk -F\' '{print $2}'
The output is:
/vms/onion.qcow2
I'm having two challenges with the above command:
1) The command is inside a loop, and where you see 'server1', it is a variable that will have a server name.
2) Python is complaining about KeyError: 'print $2'
Here is what I have so far:
proc = subprocess.Popen(["virsh dumpxml {0} | grep 'source file' | awk -F\' '{print $2}'".format(vm)], stdout=subprocess.PIPE, shell=True)
stdout = proc.communicate()[0]
Thanks in advance.
While it's possible use libvirt directly from python, your problem is that { is the format string, and surrounds print $2 in your awk script as well, so you have to escape those braces like
proc = subprocess.Popen(["virsh dumpxml {0} | grep 'source file' | awk -F\\' '{{print $2}}'".format(vm)], stdout=subprocess.PIPE, shell=True)
stdout = proc.communicate()[0]

Fabric, retrieving result of a bash command into a python variable

I would like to store the result of a command in a variable.
By instance running : a = sudo("ls -l my_filename | awk '{print $11}'")
How could I achieve this ?
a = sudo("ls -l my_filename | awk '{print $11}'", capture=True )

Handling newlines within sed; command called from Python

I am having an issue with newlines in my command which involves the use of sed.
The scenario is as follows. When I execute the following command from Bash, I get:
cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed -e s/ph/\\nPH/g | grep -v ^$
PHysical id : 0core id : 0
PHysical id : 0core id : 1
As you can see, the sed command replaced ph with \nPH, such that I get a new line for each 'physical id...'
Now, I am calling this bash command from Python. Here is a small snippet of my code containing all relevant library imports.
import subprocess
cmd = 'cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed -e s/ph/\\nPH/g | grep -v ^$ '
subprocess.call(cmd, shell=True, universal_newlines=True, stdin=subprocess.PIPE)
The problem is that I get:
nPHysical id : 0core id : 0nPHysical id : 0core id : 1
on one line. It appears that the '\n' is not processed as the letter n is printed before PH.
I need to get the output nicely printed so that I can later add | sort | uniq | wc -l to my command to count the lines.
I would appreciate some help from the Bash-and-Python gurus out there.
Thank you.
Try:
cmd = r'cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed -e s/ph/\\nPH/g | grep -v ^$ '
The r means is a raw string. You might not be escaping some characters correctly.
Simply enclose the substitution command for sed with commas ("") to ensure it is passed correctly into python subprocess:
import subprocess
cmd = 'cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed -e "s/ph/\\nPH/g" | grep -v ^$ '
subprocess.call(cmd, shell=True, universal_newlines=True, stdin=subprocess.PIPE)
Output:
PHysical id : 0core id : 0
PHysical id : 0core id : 0

Python escaping sed and bash command with subprocess

Question:
How do I use sed with python successfully? I have to run this command on a remote server to get a list of comma delimited hosts. When ran from bash I get what I want which is something like host1, host2, host3
Here is what I have:
process = subprocess.Popen(["ssh $USER#mychefserver knife search node "chef_environment:*" | grep -i "node name" | egrep -i "stuff|ruff" | uniq -u | sort -n | cut -d ":" -f 2 | sed -e 's/^[ \t]*//' | tr '\n' ', '
"], shell=False, stdout=PIPE)
I know I'll have to escape the \n, \t, etc, but I'm having trouble with the rest. Whenever I try to run it from my Python script I get an error for invalid syntax even though I've tried a cornucopia of escapes.
You string quoting is broken as you use " inside a double quoted string. You have to escape the " like \". Further note, that most of the double quotes in command line can be replaced by single quotes '. The following code should work:
process = subprocess.Popen(["ssh $USER#mychefserver knife search node \"chef_environment:*\" | grep -i 'node name' | egrep -i 'stuff|ruff' | uniq -u | sort -n | cut -d':' -f 2 | sed -e 's/^[ \t]*//' | tr '\n' ', '"], shell=False, stdout=subprocess.PIPE)

Categories

Resources