I have this bash command I want to run from Python2.7:
time ( s=172.20.16 ; for i in $(seq 1 254) ; do ( ping -n -c 1 -w 1 $s.$i 1>/dev/null 2>&1 && printf "%-16s %s\n" $s.$i responded ) & done ; wait ; echo )
I tried running it like this:
cmd = 'time ( s=172.20.16 ; for i in $(seq 1 254) ; do ( ping -n -c 1 -w 1 $s.$i 1>/dev/null 2>&1 && printf "%-16s %s\n" $s.$i responded ) & done ; wait ; echo )'
#1. subprocess.call(cmd.split())
#2. subprocess.call(cmd, shell=True)
#3. os.system(cmd)
But all returned /bin/sh: 1: Syntax error: word unexpected (expecting ")") , while running it from bash
worked prefectly. I also tried adding a /bin/bash
to the head of the command, but that didn't work.
When using os.system('bash "{}"'.format(cmd))
it didn't crash with the previous error, but the loop unfolded incorecctly (it printed 1..254 instead of using them as the IP suffix)
I managed to make it work by saving the command in a bash script and then calling the script from python, but I would rather do that directly. What is the problem here?
shell=True
uses /bin/sh
. /bin/sh
is not bash
.
Leaving all the problems with the shell script in place, but invoking it with bash, would look like the following:
cmd = 'time ( s=172.20.16 ; for i in $(seq 1 254) ; do ( ping -n -c 1 -w 1 $s.$i 1>/dev/null 2>&1 && printf "%-16s %s\n" $s.$i responded ) & done ; wait ; echo )'
subprocess.call(['bash', '-c', cmd])
Rewriting it to actually be a better shell script might instead look like:
cmd = r'''
time {
s=172.20.16
for ((i=1; i<=254; i++)); do
{ ping -n -c 1 -w 1 "$s.$i" >/dev/null 2>&1 && \
printf "%-16s %s\n" "$s.$i" "responded"
} &
done
wait
echo
}
'''
subprocess.call(['bash', '-c', cmd])
Note that we're using { ...; }
{ ...; }
, not ( ... )
, for grouping (thus avoiding more subshell creations than necessary); and that we're always quoting substitutions.
you are splitting by space to construct the array of commands/parameters for the suprocess call method; but notice that there are parameters that include spaces, so it should count as a single parameter, not two (ie this one: "%-16s %s\\n"
)
Try using subprocess as per this link Running Bash commands in Python
import subprocess
subprocess.call("{}".format(cmd).split())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.