Igor
Igor

Reputation: 1464

How to escape double quotes while reading from a file and passing the content to another executer with shellscript?

I got a problem with shellscript here.

I need to read a json file and pass this as a string using another command. Basically what I'm doing is reading a json file that has a schema validator and passing this schema validator do Mongo while creating a new collection.

If I pass the command like this from my .sh file:

mongo $DATABASE -u $MY_USER -p $PASS --eval "db.createCollection('$MY_COLLECTION', { validator: { \$jsonSchema: { \"bsonType\":\"object\", \"additionalProperties\":false, \"required\":[ \"mongo-modified\", \"mongo-revision\" ], \"properties\":{ \"_id\":{}, \"Description\":{\"bsonType\":\"string\"},\"mongo-modified\":{\"bsonType\":\"date\"},\"mongo-revision\":{\"bsonType\":\"string\"},\"Summary\":{\"bsonType\":\"string\"}}} } });"

Then it works fine. As you can see I had to escape all the double quotes to make it work. The problem is that instead of having it hardcoded there I'll be reading from a json file like this:

VALIDATOR=`cat /tmp/schema-validator.json`

And then I'll call mongo like this:

mongo $DATABASE -u $MY_USER -p $PASS --eval "db.createCollection('$MY_COLLECTION', { validator: { $VALIDATOR } });"

It's not working this way and I believe the reason is the quotes I have inside my $VALIDATOR.

The Json file looks like this:

{
    "bsonType": "object",
    "additionalProperties": false,
    "required": [
        "mongo-modified",
        "mongo-revision"
    ],
    "properties": {
        "_id": {

        },
    "Description": {
        "bsonType": "string"
    },
    "mongo-modified": {
        "bsonType": "date"
    },
    "mongo-revision": {
        "bsonType": "string"
    },
    "Summary": {
        "bsonType": "string"
    }
}

Another possible reason would be having multiple lines. Either way I'm kind of stuck with that.

If someone could give me a direction on that it would be great.

Thanks!

Upvotes: 0

Views: 393

Answers (2)

David Maze
David Maze

Reputation: 159865

If you have that much data you're trying to escape, and especially since it looks like you're trying to write an entire script, you'll be far better off writing it to a file and passing the filename as a parameter to mongo.

The one trick is that you need to get the $MY_COLLECTION variable injected somehow. It looks like you can both --eval a fragment and load a script, which in your case might look like

mongo ... --eval "my_collection = '$MY_COLLECTION'" createCollection.js

Another trick that looks like it will work is to put your script in a shell heredoc and pass it to mongo on stdin, rather than trying to stuff it into --eval.

Within your script it's also probably better to load the validator definition as a JSON object, rather than trying to use shell interpolation to inject it.

Upvotes: 1

George Whiteside
George Whiteside

Reputation: 1

To escape all of the double quotes and trim the whitespace from the json file, you could do something like this.

VALIDATOR=$(
     # replace " with \"
     sed 's/\"/\\\"/g' /tmp/schema-validator.json |
         # delete newlines
         tr -d '\n' |
         # squeeze spaces (delete all but one space)
         tr -s ' ')

See the man pages for sed and tr for more info about how they work.

Upvotes: 0

Related Questions