I have an envs.json file with content:
{
"dev-cc1": { "url": "https://my-url.com" },
"dev-cc2": { "url": "https://my-url.com" }
}
I would like to fetch urls based on an environment variable $ENV, but every other related article I came across didn't seem to work, or I just read it wrong. I think I'm missing something super trivial...
Things I tried:
export ENV="dev-cc1"
jq --arg ENV "$ENV" -n '."env.ENV"' envs.json
Because my env variable has a dash in it, I quoted around it, and then tried to reference it inside. However jq returns back null.
The hardcoded query works (jq --arg ENV "$ENV" '."dev-cc1"' envs.json), and I've also confirmed that the environment variable is passed in correctly jq --arg ENV "$ENV" -n 'env.ENV'.
I tried a ton of different ways to substitute this env var in but none worked.. Could anyone please give this a second pair of eyes?
Try
ENV="dev-cc1" jq '.[env.ENV]' envs.json
or
export ENV="dev-cc1"
jq '.[env.ENV]' envs.json
or using a jq variable:
ENV="dev-cc1"
jq --arg ENV "$ENV" '.[$ENV]' envs.json
Related
I am using below snippet in my jenking groovy file, where I am getting null response.
def Services= sh(script: "curl -s --header \"PRIVATE-TOKEN: ${gittoken}\" ${url}| jq -r .${Servicename}[]", returnStdout: true)
file which I am downloading is like below.
{
"FrameWork1": [
"sample/sample1",
"sample/sample2"
]
}
Basically I am getting values of Framework1
if I give below one I am getting the first value of Framework object
Working one:###############
def Services= sh(script: "curl -s --header \"PRIVATE-TOKEN: ${gittoken}\" ${url}| jq -r .${Servicename}[1]", returnStdout: true)
jq filter should be .FrameWork1[] to get a list of strings
https://jqplay.org/s/3iCv-off4ep
Don't use shell parameter expansion to generate the jq program, pass the shell parameters as arguments to jq instead (then you do not have to worry about contexts, quoting, escaping, etc.)
... | jq -r --arg svc "$Servicename" '.[$svc][]'
I have this line here that is inside of a groovy function and i am trying to return a cluster ID
EMR_ID = sh(returnStdout: true, script: "aws emr list-clusters --active --profile \'${PROFILE}\' | jq -r '.Clusters[] | select (.Name=="\'${ENV}\'-emr-cluster") | .Id'")
Without the environmental variables, this works fine.
so the $PROFILE param is set to dev and the $ENV is set to aws-dev.
I keep getting the error that complains about the $ENV var, saying that an unexpected bracket is showing up
It is rarely a good idea to pass environment variables using string-interpolation. There are much better ways.
One you might consider is modifying your invocation of jq as follows:
jq -r --arg env "${ENV}" '.Clusters[] | select (.Name=="\($env)-emr-cluster") | .Id'
Here, $env is an ordinary jq variable, or more accurately perhaps, a defined constant.
After realising that the jenkins snippet generator was actually useful I used this:
sh '''jq -r --arg env "${ENV}" \'.Clusters[] | select (.Name=="\\($env)-emr-cluster") | .Id\' '''
and it worked!
I am fairly new to jq and I am using this tutorial to add a new Org to a hyperledger fabric network.
There is extensive use of jq throughout the tutorial, especially modifying json files.
The tutorial uses an example Org name but I am trying to make the org name dynamic. Everything works out well except when I try to pass variables to jq.
Here are the jq commands and their outputs.
jq version: 1.5.1
$ export MSPID=Org4MSP
$ echo $MSPID
Org4MSP
Trying to pass the variable using env.
Keyword: env.MSPID
$ jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"env.MSPID":.[1]}}}}}' config.json org4.json
Output snippet: Instead of printing Org4MSP, it prints the literal string env.MSPID
"env.MSPID": {
"groups": {},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
Trying to pass the variable using --arg option
Keyword: "$MSP"
jq --arg MSP "$MSPID" -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"$MSP":.[1]}}}}}' config.json org4.json
Output snippet: Instead of printing Org4MSP, it prints the literal string $MSP
"$MSP": {
"groups": {},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 1,
"value": {
"identities": [
{
Trying to pass a variable using --arg option and without using double quotes:
keyword: $MSP
$ jq --arg MSP "$MSPID" -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {$MSP:.[1]}}}}}' config.json org4.json
jq: error: syntax error, unexpected ':', expecting '}' (Unix shell quoting issues?) at , line 1:
.[0] * {"channel_group":{"groups":{"Application":{"groups": {$MSP:.[1]}}}}}
jq: 1 compile error
Trying to pass variable using env. and without double quotes:
keyword: env.MSPID
$ jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {env.MSPID:.[1]}}}}}' config.json org4.json
jq: error: syntax error, unexpected FIELD, expecting '}' (Unix shell quoting issues?) at , line 1:
.[0] * {"channel_group":{"groups":{"Application":{"groups": {env.MSPID:.[1]}}}}}
jq: 1 compile error
I apologize if this seems to be a trivial question but I have searched online and in docs and do not understand why the JSON key will not convert to the shell variable's value.
Thank you
Environment variables
In your sub-expression:
{"env.MSPID":.[1]}
you have quoted env.MSPID thereby making it a literal string. Since you want to invoke the env function, you should instead write:
{ (env.MSPID):.[1]}
The parentheses are needed to ensure that jq will evaluate the parenthesized expression properly.
{$MSP:.[1]}
As noted above, when an expression must be evaluated to determine the string-value of a key, the expression must be parenthesized, e.g.
{($MSP):.[1]}
OK, this might be a silly question. I've got the test.json file:
{
"timestamp": 1234567890,
"report": "AgeReport"
}
What I want to do is to extract timestamp and report values and store them in some env variables:
export $(cat test.json | jq -r '#sh "TIMESTAMP=\(.timestamp) REPORT=\(.report)"')
and the result is:
echo $TIMESTAMP $REPORT
1234567890 'AgeReport'
The problem is that those single quotes break other commands.
How can I get rid of those single quotes?
NOTE: I'm gonna leave the accepted answer as is, but see #Inian's answer for a better solution.
Why make it convoluted with using eval and have a quoting mess? Rather simply emit the variables by joining them with NULL (\u0000) and read it back in the shell environment
{
IFS= read -r -d '' TIMESTAMP
IFS= read -r -d '' REPORT
} < <(jq -r '(.timestamp|tostring) + "\u0000" + .report + "\u0000"' test.json)
This makes your parsing more robust by making the fields joined by NULL delimiter, which can't be part of your string sequence.
From the jq man-page, the #sh command converts its input to be
escaped suitable for use in a command-line for a POSIX shell.
So, rather than attempting to splice the output of jq into the shell's export command which would require carefully removing some quoting, you can generate the entire commandline inside jq, and then execute it with eval:
eval "$(
cat test.json |\
jq -r '#sh "export TIMESTAMP=\(.timestamp) REPORT=\(.report)"'
)"
is there any lvm.conf editor?
I'm trying to set global_filter, use_lvmtad and some other options, currently using sed:
sed -i /etc/lvm/lvm.conf \
-e "s/use_lvmetad = 1/use_lvmetad = 0/" \
-e "/^ *[^#] *global_filter/d" \
-e "/^devices {/a\ global_filter = [ \"r|/dev/drbd.*|\", \"r|/dev/dm-.*|\", \"r|/dev/zd.*|\" ]"
but I don't like this too much, is there any better way?
I found only lvmconfig tool, but it can only display certain configuration sections, and can't edit them.
If you using Ubuntu variant then you can use the LVM GUI to configure and manage the LVM. Refer this link
It seems that augtool is exactly what I was looking for.
These two packages should be enough to proper processing lvm.conf file:
apt install augeas-tools augeas-lenses
Example usage:
augtool print /files/etc/lvm/lvm.conf
And you should get the whole parse tree on stdout.
If the parser fails you won’t get any output, print the error message using:
augtool print /files/etc/lvm/lvm.conf/error
The augtool equivalent for the sed command from the original question:
augtool -s <<EOT
set /files/etc/lvm/lvm.conf/global/dict/use_lvmetad/int "0"
rm /files/etc/lvm/lvm.conf/devices/dict/global_filter
set /files/etc/lvm/lvm.conf/devices/dict/global_filter/list/0/str "r|^/dev/drbd.*|"
set /files/etc/lvm/lvm.conf/devices/dict/global_filter/list/1/str "r|/dev/dm-.*|"
set /files/etc/lvm/lvm.conf/devices/dict/global_filter/list/2/str "r|/dev/zd.*|"
EOT