Pass variable to a string in a shell file
Solution 1
You need to use doubles-quotes instead of single-quotes - single-quotes prevent variable expansion from taking place. Try this instead:
#!/bin/bash
NETWORKNAME=PCEXCHANGE
VERSION=1.1.0
ORGANIZATIONS=( "Asus" "Dell" "HP" "Amazon" )
PRODUCERS=( "Asus" "Dell" "HP" )
MAKERS=( "Amazon" )
for org in ${PRODUCERS[@]}
do
for maker in ${MAKERS[@]}
do
docker exec cli.${maker} bash -c "peer channel create -c ${org,,} -f ./channels/${org}.tx -o orderer.${NETWORKNAME,,}.com:7050"
done
done
Solution 2
To safely pass variables into a bash -c
child shell, you would use
bash -c 'script goes here' bash "arg1" "arg2" "arg3" ...
That is,
#!/bin/bash
NETWORKNAME=PCEXCHANGE
VERSION=1.1.0
ORGANIZATIONS=( "Asus" "Dell" "HP" "Amazon" )
PRODUCERS=( "Asus" "Dell" "HP" )
MAKERS=( "Amazon" )
for org in "${PRODUCERS[@]}"; do
for maker in "${MAKERS[@]}"; do
docker exec "cli.$maker" \
bash -c 'peer channel create -c "$1" -f "$2" -o "$3"' bash \
"${org,,}" "./channels/$org.tx" "orderer.${NETWORKNAME,,}.com:7050"
done
done
This would allow the child shell script to work even if any of the producers had spaces in their values.
Also note the quoting of the other expansions in the script, which makes it work even when producers or makers have spaces in their values.
The bash
argument after the text of the bash -c
script itself is what's passed into $0
. This is usually the name of the script or the interpreter, so we simply pass the string bash
.
Related videos on Youtube
Comments
-
0xSEGFAULT over 1 year
I for some reason can't figure this out. I need the following to look like this. I basically don't want to write the same command 20-50 times depending or even more. Thanks!
The problem with the current loop below is that the vars ${NETWORKNAME,,} inside the string in the command return an empty string. Example
docker exec cli.Amazon bash -c 'peer channel create -c asus -f ./channels/Asus.tx -o orderer..com:7050'
Which is obviously not a correct command
What I'm looking for
docker exec cli.Amazon bash -c 'peer channel create -c asus -f ./channels/Asus.tx -o orderer.pcexchange.com:7050'
Current code
#!/bin/bash NETWORKNAME=PCEXCHANGE VERSION=1.1.0 ORGANIZATIONS=( "Asus" "Dell" "HP" "Amazon" ) PRODUCERS=( "Asus" "Dell" "HP" ) MAKERS=( "Amazon" ) for org in ${PRODUCERS[@]} do for maker in ${MAKERS[@]} do docker exec cli.${maker} bash -c 'peer channel create -c ${org,,} -f ./channels/${org}.tx -o orderer.${NETWORKNAME,,}.com:7050' done done
-
0xSEGFAULT almost 6 years@ilkkachu hey man thanks for replying. I posted what I'm looking for in the edit above. Thanks!
-
-
igal almost 6 years@0xSEGFAULT Glad to have helped. If this solved your problem, you could mark it as accepted.
-
Kusalananda almost 6 yearsNote that since every expansion is unquoted in this code, the shell will perform word splitting and filename globbing on everything.