Home > Enterprise >  How to use environment variables within a command in jq script files?
How to use environment variables within a command in jq script files?

Time:03-31

I am working with a large quantity of OpenAPI 3.0.0 files from which I need to create html pages. Each OpenAPI file represents an entity in a large object model. The Swagger Viewer, redoc-cli, and other tools do not produce the type of documentation I need. Here is an example file:

{
    "openapi": "3.0.0",
    "paths": {},
    "info": {
        "title": "My File",
        "version": "1.0.0"
    },
    "components": {
        "schemas": {
            "my_entity_name": {
                "type": "object",
                "description": "....",
                "properties": {
                    "propertyOne": {
                        "type": "string",
                        "description": "..."
                    },
                    "propertyTwo": {
                        "type": "string",
                        "format": "date",
                        "description": "..."
                    }
                }
            }
        }
    }
}

Within my solution I am using jq to parse the files (macOS, ksh). Since there are so many, I would like to pass an environment variable to jq. This is straightforward in the shell:

 % entity_name=my_entity_name
 % jq -r 'select(.components.schemas.'$entity_name'.properties != null)' file.json

In a script file the approach is similar, and I get the results I expect. However, given the nature of what I am trying to do, I'd like to use the jq -f option to put the jq commands in a file.

I've attempted putting the following in a file called jqscript.jq:

 select(.components.schemas.'$entity_name'.properties != null)

And I call make the call thus:

  % jq -rf jqscript.jq --arg entity_name "$entity_name" file.json

This results in an error:

jq: error: syntax error, unexpected INVALID_CHARACTER, expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
select(.components.schemas.'$entity_name'.properties != null)                           
jq: 1 compile error

I've tried to decipher how to use an environment variable in such a situation by modifying the '$entity_name' to $entity_name (removing the single quotes),$[entity_name], ${entity_name}, et cetera but I had similar results.

I was able to verify that variables can be passed to jq script files with the following example script:

value: $entity_name
} |
.value

When I run with this file with % jq -rf jqscript.jq --arg entity_name "$entity_name" file.json, I get the expected value for entity_name returned.

How can I go about using an environment variable that is both within a jq command and that command is in a jq script file?

CodePudding user response:

You are dynamically constructing a filter using the value of a variable. This is fragile, as the resulting expression is parsed, rather than using the value of the variable literally (similar to SQL injection attacks).

You can access the environment directly using $ENV.

 % export entity_name=my_entity_name
 % jq -r 'select(.components.schemas[$ENV.entity_name].properties != null)' file.json

or simply pass the key as an explicit argument

% jq -r --arg entity_name my_entity_name 'select(.components.schemas[$entity_name].properties != null)' file.json
  • Related