In python, I'm trying to do something to compile c source codes easily, including a line like that ;
import os
os.system("gcc %s -o %s -ansi" %(filename, filename[:-3])
But it gives me the error ;
sh: 2: -o: not found
To check what is wrong I'm trying to do this ;
print("gcc %s -o %s -ansi" %(filename, filename[:-3]))
and it gives me that ;
gcc foo.c
-o foo -ansi
My question is why it occurs and what should I do to prevent it ?
os.system is depreciated and it's recommended to use subprocess instead.
Splitting the filename on "." will ensure it works correctly even if the file extension differ.
And if you're using Python 3 I suggest you use format.
import subprocess
filename = filename.strip()
subprocess.call('gcc {} -o {} -ansi'.format(filename,filename.split(".")[0])
You probably want to strip away the newline from filename:
import os
import subprocess
filename = filename.strip()
subprocess.call(['gcc', filename, '-o', os.path.splitext(filename)[0], '-ansi'])
filename[:-3] will return the whole string apart from the last 3 characters. Evidently, your last 3 characters are .c\n, which is why you have a newline in your formatted string, because filename equates to foo.c\n.
To remedy this I suppose you have two choices:
1) remove the \n from the string with filename.strip() (recommended, especially if you use filename often for these purposes)
2) use filename[:-1] instead of filename
Related
my file name is
file_name = '19-00165_my-test - Copy (7)_Basic_sample_data'
my function is like
call("rm -rf /tmp/" + file_name + '.csv', shell=True)
but getting this error
/bin/sh: -c: line 0: syntax error near unexpected token `('
My response always is: Don't use space in files.
But if you really want this, than you should place the files in quotes as such:
call("rm -f '/tmp/{0}.csv'".format(file_name), shell=True)
Why are you using shell=True? That means the command will be passed to a shell for parsing, which is what's causing all the trouble. With shell=False, you pass a list consisting of the commands followed by its arguments, each as a separate list element (rather than all mashed together as a single string). Since the filename never goes through shell parsing, it can't get mis-parsed.
call(["rm", "-rf", "/tmp/" + file_name + '.csv'], shell=False)
In order to avoid having problems with unescaped characters, one way is to use the shlex module:
You can use the quote() function to escape the string, it returns a shell-escaped version of the string:
import shlex
file_name = "19-00165_my-test - Copy (7)_Basic_sample_'data"
call(f"rm -f /tmp/{shlex.quote(file_name)}.csv", shell=True)
# rm -rf /tmp/'19-00165_my-test - Copy (7)_Basic_sample_'"'"'data'.csv
You can also use join():
import shlex
file_name = "19-00165_my-test - Copy (7)_Basic_sample_'data"
call(shlex.join(["rm", "-f", f"/tmp/{file_name}.csv"]), shell=True)
# rm -f '/tmp/19-00165_my-test - Copy (7)_Basic_sample_'"'"'data.csv'
Note: This answer is only valid if shell=True is required to make the command work. Otherwise the answer of #Gordon Davisson is way easier.
I want to run a bash script from a python program. The script has a command like this:
find . -type d -exec bash -c 'cd "$0" && gunzip -c *.gz | cut -f 3 >> ../mydoc.txt' {} \;
Normally I would run a subprocess call like:
subprocess.call('ls | wc -l', shell=True)
But that's not possible here because of the quoting signs. Any suggestions?
Thanks!
While the question is answered already, I'll still jump in because I assume that you want to execute that bash script because you do not have the functionally equivalent Python code (which is lees than 40 lines basically, see below).
Why do this instead the bash script?
Your script now is able to run on any OS that has a Python interpreter
The functionality is a lot easier to read and understand
If you need anything special, it is always easier to adapt your own code
More Pythonic :-)
Please bear in mind that is (as your bash script) without any kind of error checking and the output file is a global variable, but that can be changed easily.
import gzip
import os
# create out output file
outfile = open('/tmp/output.txt', mode='w', encoding='utf-8')
def process_line(line):
"""
get the third column (delimiter is tab char) and write to output file
"""
columns = line.split('\t')
if len(columns) > 3:
outfile.write(columns[3] + '\n')
def process_zipfile(filename):
"""
read zip file content (we assume text) and split into lines for processing
"""
print('Reading {0} ...'.format(filename))
with gzip.open(filename, mode='rb') as f:
lines = f.read().decode('utf-8').split('\n')
for line in lines:
process_line(line.strip())
def process_directory(dirtuple):
"""
loop thru the list of files in that directory and process any .gz file
"""
print('Processing {0} ...'.format(dirtuple[0]))
for filename in dirtuple[2]:
if filename.endswith('.gz'):
process_zipfile(os.path.join(dirtuple[0], filename))
# walk the directory tree from current directory downward
for dirtuple in os.walk('.'):
process_directory(dirtuple)
outfile.close()
Escape the ' marks with a \.
i.e. For every: ', replace with: \'
Triple quotes or triple double quotes ('''some string''' or """some other string""") are handy as well. See here (yeah, its python3 documentation, but it all works 100% in python2)
mystring = """how many 'cakes' can you "deliver"?"""
print(mystring)
how many 'cakes' can you "deliver"?
I'm trying to get xcopy working with python to copy files to a remote system. I am using a very simple test example:
import os
src = "C:\<Username>\Desktop\test2.txt"
dst = "C:\Users\<Username>"
print os.system("xcopy %s %s" % (src, dst))
But for some reason when I run this I get:
Invalid number of parameters
4
Running the xcopy directly from the command line works fine. Any ideas?
Thanks
\t is a tab character. I'd suggest using raw strings for windows paths:
src = r"C:\<Username>\Desktop\test2.txt"
dst = r"C:\Users\<Username>"
This will stop python from surprising you by interpreting some of your backslashes as escape sequences.
In addition to using raw string literals, use the subprocess module instead of os.system - it will take care of quoting your arguments properly if they contain spaces. Thus:
import subprocess
src = r'C:\<Username>\Desktop\test2.txt'
dst = r'C:\Users\<Username>'
subprocess.call(['xcopy', src, dst])
Try prefixing your strings with r. So r"C:\<Username>\Desktop\test2.txt". The problem is that a backslash is treated as a special character within strings.
I am trying to develop a script to read pcap file and extract some field from it but using tshark as a subprocess. However i am getting syntax error regarding cmd. Can anyone help me out on this?
def srcDestDport (filename):
cmd = r"tshark -o column.format:"Source","%s", "Destination","%d", "dstport"," %uD"' -r %s"%(filename)
subcmd = cmd.split(' ')
lines = subprocess.Popen(subcmd,stdout=subprocess.PIPE)
return lines
As far as Python is concerned, you appear to be missing some commas in your cmd definition:
cmd = r"tshark -o column.format:"Source","%s", "Destination","%d", "dstport"," %uD"' -r %s"%(filename)
# -- no comma here -^ ----^ ----^ --^
because the first string ends when the first " is encountered at "Source"; a raw string does not preclude you from escaping embedded quotes.
If you wanted to produce a list of arguments, just make it a list directly, saves you interpolating the filename too:
cmd = ["tshark", "-o",
'column.format:"Source","%s","Destination","%d","dstport"," %uD"',
"-r", filename]
Note the single quotes around the 3rd argument to preserve the quotes in the command line argument.
This eliminates the need to split as well and preserves whitespace in the filename.
I'll start by saying that I am very, very new to Python.
I used to have a Windows/Dos batch file in order to launch Mencoder with the right set of parameters, without having to type them each time.
Things got messy when I tried to improve my script, and I decided that it would be a good opportunity to try coding something in python.
I've come up with that :
#!/usr/bin/python
import sys, os
#Path to mencoder
mencoder = "C:\Program Files\MPlayer-1.0rc2\mencoder.exe"
infile = "holidays.avi"
outfile = "holidays (part1).avi"
startTime = "00:48:00"
length = "00:00:15"
commande = "%s %s -ovc copy -oac copy -ss %s -endpos %s -o %s"
os.system(commande % (mencoder, infile, startTime, length, outfile))
#Pause
raw_input()
But that doesn't work, windows complains that "C:\Program" is not recognized command.
I've trying putting some "\"" here and there, but that didn't help.
Python have two types of quotes, " and ' and they are completely equal. So easiest way to get quotes in a string is to say '"C:\Program Files\MPlayer-1.0rc2\mencoder.exe"'.
Using the raw prefix (ie r'"C:\Program Files\MPlayer-1.0rc2\mencoder.exe"') is a good idea, but that is not the error here, as none of the backslashes are followed by a letter that is an escape code. So your original string would not change at all by having an r in front of it.
use two quotes instead of one if you are doing on windows.
"\\"
I'm new to Python but I know when ever I see that problem, to fix it, the file (executable or argument) must be in quotes. Just add \" before and after any file that contains a space in it to differentiate between the command-line arguments. So, that applies to your outfile variable as well. The code should look like this...
#!/usr/bin/python
import sys, os
#Path to mencoder
mencoder = "\"C:\Program Files\MPlayer-1.0rc2\mencoder.exe\""
infile = "holidays.avi"
outfile = "\"holidays (part1).avi\""
startTime = "00:48:00"
length = "00:00:15"
commande = "%s %s -ovc copy -oac copy -ss %s -endpos %s -o %s"
os.system(commande % (mencoder, infile, startTime, length, outfile))
#Pause
raw_input()
You can even put the mencoder.exe into a directory which doesn't have a space char inside it's name (opposed to Program Files).