2

I prepared some code to execute such command line:

c:\cygwin\bin\convert "c:\root\dropbox\www\tiff\photos\architecture\calendar-bwl-projekt\bwl01.tif" -thumbnail 352x352^ -format jpg -filter Catrom -unsharp 0x1 "c:\root\dropbox\www\tiff\thumbnails\architecture\calendar-bwl-projekt\thumbnail\bwl01.jpg"

This works fine from command line (same command as above) but 352x352^ is 352x352^ not 352x352:

c:\cygwin\bin\convert "c:\root\dropbox\www\tiff\photos\architecture\calendar-bwl-projekt\bwl01.tif" -thumbnail 352x352^ -format jpg -filter Catrom -unsharp 0x1 "c:\root\dropbox\www\tiff\thumbnails\architecture\calendar-bwl-projekt\thumbnail\bwl01.jpg"

If run this code from Python, the ^ character is ignored and the resized image has size as if '%sx%s' was passed instead of %sx%s^

Why does Python cut out the ^ character and how can I avoid it?

def resize_image_to_jpg(input_file, output_file, size):
  resize_command = 'c:\\cygwin\\bin\\convert "%s" -thumbnail %sx%s^ -format jpg -filter Catrom -unsharp 0x1 "%s"' \
                   % (input_file, size, size, output_file)
  print resize_command
  resize = subprocess.Popen(resize_command)
  resize.wait()
tripleee
  • 175,061
  • 34
  • 275
  • 318
Chameleon
  • 9,722
  • 16
  • 65
  • 127

1 Answers1

4

Why Python cuts '^' character and how to avoid it?

Python does not cut ^ character. Popen() passes the string (resize_command) to CreateProcess() Windows API call as is.

It is easy to test:

#!/usr/bin/env python
import sys
import subprocess

subprocess.check_call([sys.executable, '-c', 'import sys; print(sys.argv)'] +
                      ['^', '<-- see, it is still here'])

The latter command uses subprocess.list2cmdline() that follows Parsing C Command-Line Arguments rules to convert the list into the command string -- it has not effect on ^.

^ is not special for CreateProcess(). ^ is special if you use shell=True (when cmd.exe is run).

if and only if the command line produced will be interpreted by cmd, prefix each shell metacharacter (or each character) with a ^ character. It includes ^ itself.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • If I'm following this correctly, the problem is actually the opposite of what's specified in the question - the `^` is dropped when the command is typed at the command line, but preserved when using `Popen`. – Mark Ransom Jan 09 '15 at 19:00
  • 1
    @MarkRansom: Yes. `^` escapes the next character on the command line but it has no special meaning if `Popen()` is used without `shell=True`. My guess either OP hasn't provided the actual code (i.e., `shell=True` is used) or the `convert` command corrupts the arguments itself. – jfs Jan 09 '15 at 19:10
  • I was added shell=True tp remove problem - now I understand the root cause better - very good explanation. – Chameleon Jan 10 '15 at 01:06
  • @eryksun: To be clear: the answer does not recommend `shell=True`. It just says that without `shell=True` (no interpretation by `cmd.exe`), `^` is not special i.e., `^` is passed as is to the command. – jfs Jan 11 '15 at 06:48