"Command Not Found" Using Line in Argument to Os.System Using Python

command not found using line in argument to os.system using python

The * has nothing to do with the problem; the string you're substituting with %s ends with a newline, and that newline is what breaks your code.

When you use os.popen('...').read(), you get the entire output of ... -- including the trailing newline, which shell command substitutions implicitly trim.

The best answer would be to rewrite your logic in Python, but the easy answer here is to use such a command substitution, which also avoids trying to pass values into a script via string substitution (which is a fast route to shell-injection security bugs):

shell_script = r'''
cur_date=$(date -d '-1 day' '+%Y%m%d')

zgrep "919535144580" /var/tmp/comp?/emse_revres_rdc.log."$cur_date"* \
| grep -v "RI" \
| cut -d "|" -f 9,10,23,24,26 \
| sort \
| uniq -c \
| sort -nr \
>> /var/tmp/Andy/test.txt
'''

os.system(shell_script)

That said, if you're just going for the shortest change possible, put the following before your original code's os.system() call:

cur_date = cur_date.rstrip('\n')

os.system command not found after string formatting

Apart from os.system being by way inferior to subprocess, the likely problem is the substitution process done by .format().

Instead of your code, you should try

BOOT_VOLUME_ATTACHMENT_ID = "123"
print(repr('oci compute boot-volume-attachment detach --force --wait-for-state DETACHED --boot-volume-attachment-id {0} --region region1'.format(BOOT_VOLUME_ATTACHMENT_ID)))

and look what it outputs.

This will tell you if there is something strange (e. g. a line break) before the --region.

After your question update, it becomes clear that your BOOT_VOLUME_ATTACHMENT_ID isn't what you claimed it to be. Instead, it contains the output of a different program, which in most cases adds a line break at the end.

If you take that content and plug it into a string the way you did, this line break gets transferred into the destination string, telling the shell to execute two commands.

The solution is to use .strip() immediately after the os.popen() call.


About subprocess:

Your program will become cleaner (e. g. less injection-prone) if you do

import subprocess
BOOT_VOLUME_ATTACHMENT_ID = "123"
subprocess.call(['oci', 'compute', 'boot-volume-attachment', 'detach', '--force', '--wait-for-state', 'DETACHED', '--boot-volume-attachment-id', BOOT_VOLUME_ATTACHMENT_ID, '--region', 'region1'])

The reason is that this avoids having the shell between your program and oci, thus eliminating one potential source of errors.

Trouble passing arguments into os.system()

You should call it with just one string as follows:

os.system('python main.py input laska.png output laska_save{}.png'.format(i))

The os.system documentation says it just take an string as argument, so you must create that full string with the command before passing it to the function.

Passing arguments into os.system

Don't use os.system(); subprocess is definitely the way to go.

Your problem though is that you expect Python to understand that you want to interpolate args.fileread into a string. As great as Python is, it is not able to read your mind like that!

Use string formatting instead:

os.system("rtl2gds -rtl={args.fileread} -rtl_top={args.module_name} -syn".format(args=args)

If you want to pass a filename to another command, you should not use the FileType type option! You want a filename, not an open file object:

parser.add_argument('fileread', help='Enter the file path')

But do use subprocess.call() instead of os.system():

import subprocess

subprocess.call(['rtl2gds', '-rtl=' + args.fileread, '-rtl_top=' + args.module_name, '-syn'])

If rtl2gds implements command line parsing properly, the = is optional and you can use the following call instead, avoiding string concatenation altogether:

subprocess.call(['rtl2gds', '-rtl', args.fileread, '-rtl_top', args.module_name, '-syn'])

How do I execute a program or call a system command?

Use the subprocess module in the standard library:

import subprocess
subprocess.run(["ls", "-l"])

The advantage of subprocess.run over os.system is that it is more flexible (you can get the stdout, stderr, the "real" status code, better error handling, etc...).

Even the documentation for os.system recommends using subprocess instead:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

On Python 3.4 and earlier, use subprocess.call instead of .run:

subprocess.call(["ls", "-l"])

Python: Failing to open a file using os.system()

You can avoid (potential) problems with quoting, escaping, and so on, with subprocess:

import subprocess

subprocess.call(['pdftk', '1.pdf', '2.pdf', 'cat', 'output', 'result.pdf'])

It's just as easy to use as os.system, and even easier if you are building the argument list dynamically.



Related Topics



Leave a reply



Submit