Domanda

I have a Python script script.py which I am using to generate the command line argument to another script exactly like so:

./main $(./script.py)

The output of script.py may contain spaces (e.g. foo bar) which are being unintentionally interpreted by the shell. I want the argument to ./main to be the single string "foo bar". Of course I can solve this problem if I quote the argument to ./main, like this:

./main "$(./script.py)"

But I can't and don't want to do that. (The reason is because ./main is being called without quotes from another script which I don't have control to edit.)

Is there an alternative representation of the space character that my Python script can use, and that bash won't interpret?

È stato utile?

Soluzione

You can try to have ./script.py output a non-breaking space (U+00a0) instead of a regular space, which bash will not use for word-splitting. However, I would file a bug report to have the script that calls main add quotes to its argument. Whether this works depends on how main reacts to getting a string that consists of a two-byte UTF-8 sequence representing U+00a0 rather than a single space character.

A sample script.py:

#!/usr/bin/python
print u'foo\xa0bar'.encode('utf8')

A sample script a.bash:

#!/bin/bash
main () {
    echo $#
}
main $(script.py)

And finally, a demonstration that main gets 1 argument from the output of script.py:

$ bash a.bash
1

Altri suggerimenti

You can change your python script to escape the spaces in the output if you cannot quote the calling code.

See this code snippet:

arg1() { echo "$1"; }
arg1 abc def
abc

arg1 abc\ def
abc def

So as you can see if you output abc\ def instead of abc def from python code it will be considered single argument.

Assuming that:

  • you have control over ./main and that it is a shell script
  • the entire output from the Python script is to be interpreted as a single parameter

simply use $* rather than $1 inside ./main

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top