Solution
As @Barmar points out, a carriage return was the problem. But couldn't find out where it was coming from, as it wasn't .gitconfig nor Visual Studio Code.
jq was pulling in the /r/n per this issue on GitHub. It doesn't look like their latest release includes the fix yet (--binary on windows).
Piping the output to tr during the array creation solved it.
environmentsNames=($(jq -r '.environments[].name' <<< "${configJSON}" | tr -d '\r')) # Returns an array of environment names
Orginal Problem
I'm putting together an open-source bash repo to make SSH/SSH-Agent/SFTP/Rsync connections and authentication easier/faster.
The user selects an environment to connect to, which is read from a json config file by jq. They see a message indicating what was selected, but this message is cut off per the below.
I've tried adding additional spaces, echo vs printf, changing the line's length, different terminals, removing the quotes and adding additional text, and more. In each case, this line is cut off to a specific number of characters that seems to be like 35-37.
It's not affecting functionality, but it's annoying and I'm curious to learn what I'm doing wrong. No idea why, but I've done some reading - is the shell consuming characters due to the length of my variables or something?
Thanks!
Here is what I am seeing:
Enter the number of the environment to work from. Use staging by default. 0
'ou selected '0' which represents 'stg
Here is what I expect:
Enter the number of the environment to work from. Use staging by default. 0
You selected '0' which represents 'stg'
Here is the code:
# Select environment to work from to set environment variables
envNumbers=() # Declare empty array
for i in "${!environmentsNames[@]}"; do
envNumbers+=($i) # Create array of environment numbers so it can be checked against later
printf "%s\t%s\n" "$i" "${environmentsNames[$i]}" # List environment names from environments.json file
done
chosenEnv=""
for i in 1 2 3; do # Three attempts to select the right environment
printf '\n'
read -p "Enter the number of the environment to work from. Use staging by default. " chosenEnv
if [[ ! "${envNumbers[@]}" =~ "$chosenEnv" ]]; then # Checks to ensure environment is valid
printf "Your entry $chosenEnv is not a valid environment number. \n"
else
echo "You selected '$chosenEnv' which represents '${environmentsNames[$chosenEnv]}'"
break # Leaves the loop if environment is valid
fi
if [[ $i == 3 ]]; then # On last try, exit the script
printf "You did not select a valid environment. Goodbye. \n"
sleep 5
exit 1 # Leaves the script
fi
printf "Try again. \n"
done
Edits
Here is where the environments variables is populated:
#!/bin/bash
configJSON="$(jq -r '.' "$DIR/config.json")" # Returns all environment data
defaultIdentity=$(jq -r '.defaultIdentity' <<< "${configJSON}")
sshAgentTime=$(jq -r '.sshAgentTime' <<< "${configJSON}")
environmentsNames=($(jq -r '.environments[] | .name' <<< "${configJSON}")) # Returns an array of environment names
Here is the template config json:
{
"defaultIdentity":"path/to/rsa/private/key",
"sshAgentTime":"4h",
"environments":
[
{
"name":"environment1",
"address":"12.345.67.890",
"username":"myusername",
"port":"99999",
"path":"path/to/target/directory",
"identity":"path/to/rsa/private/key",
"siteurl":"example1.com"
},
{
"name":"environment2",
"address":"12.345.67.899",
"username":"myusername",
"port":"99999",
"path":"path/to/target/directory",
"identity":"path/to/rsa/private/key",
"siteurl":"example2.com"
}
]
}
Once environment is selected, this runs to pull the selected environments credentials:
#!/bin/bash
if [ $chosenEnv ]; then
envName=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].name' <<< "${configJSON}")
envDomain=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].siteurl' <<< "${configJSON}")
envUsername=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].username' <<< "${configJSON}")
envAddress=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].address' <<< "${configJSON}")
envPort=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].port' <<< "${configJSON}")
envIdentity=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].identity' <<< "${configJSON}")
envLogin="$envUsername@$envAddress"
envPath=$(jq -r --argjson chosenEnv $chosenEnv '.environments[$chosenEnv].path' <<< "${configJSON}")
else
printf "Environment not selected or defined."
sleep 3
exit 1
fi