query return null in bash for psql - bash

I am tring to get the count for the records in a certain table in bash scripts but the $num is null when returned (should be a number). And the query is correct when I directly run in pgadmin that I can get the number of rows. Any one know what is wrong?
declare -a ROW=($(psql \
-X \
-U $DB_USER \
-h $DB_HOST \
-d $DB_NAME \
-p $DB_PORT \
--set ON_ERROR_STOP=on \
--no-align \
-t \
--field-separator ' ' \
--quiet \
-c "SELECT count(*) as num
FROM table_test)")
)
echo "num_error: $num here"
if [[ $num == 0 ]]; then
echo "no error occur within the past 1 hour"
elif [[ $num == '' ]]; then
echo "return nothing"
else echo "$num"
fi

SQL aliases don't become shell variables, so using AS num in the query will not set $num in the shell.
The output of the query is being put in the ROW array, so you can get the value you want from ${ROW[0]}. There's also no need to use an array if the query just returns a single value. So you could do:
num=$(psql \
-X \
-U $DB_USER \
-h $DB_HOST \
-d $DB_NAME \
-p $DB_PORT \
--set ON_ERROR_STOP=on \
--no-align \
-t \
--field-separator ' ' \
--quiet \
-c "SELECT count(*)
FROM table_test)")
)

Related

While Loop stuck indefinitely using string comparison condition - Shell Script

I am trying to check the output from an http call, if the variable matches the a string I want to terminate the loop. Unfortunately, that is not happening in my case it is not terminating the loop. Here is my code :
while [[ "$BUILD_STATUS" != "SUCCESS" ]];
do
http_response_1=$(curl -s -o response_1.json -w "%{http_code}" ${CREATE_BUILD_URL}/${BUILD_CODE}/progress -H 'Authorization: Token' -H 'Content-Type:application/json')
BUILD_PERCENTAGE=$(jq -r .percentage response_1.json)
BUILD_STATUS=$(jq .buildStatus response_1.json)
echo "$BUILD_STATUS"
rm response_1.json
echo "File Removed"
sleep 10
done
Directly have jq make the string comparison and return a status accordingly:
#!/usr/bin/env sh
while
build_percentage="$(
curl \
--silent \
--write-out "%{http_code}" \
--header 'Authorization: Token' \
--header 'Content-Type:application/json' \
--url "${CREATE_BUILD_URL}/${BUILD_CODE}/progress" |
jq \
--exit-status \
--raw-output \
'.percentage,
if .buildStatus != "SUCCESS"
then empty
else halt_error(1)
end
' 2>/dev/null
)"
do
printf 'Build percentage: %d%%\n' "$build_percentage"
sleep 10
done
printf 'Build percentage: %d%%\nStatus: SUCCESS!\n' "$build_percentage"

Bash scripts return a substring not whole value in column for psql

I want to get the value of message in db, which for example is "the error is missing index " but when I run the code belong, it only return me 'the' for error_type. How could this happen that only return me the first word but not the whole value of the query result? How can I get the query results with the whole value?
declare -a ROW=($(psql \
-X \
-U $DB_USER \
-h $DB_HOST \
-d $DB_NAME \
-p $DB_PORT \
--single-transaction \
--set AUTOCOMMIT=off \
--set ON_ERROR_STOP=on \
--no-align \
-t \
--field-separator ' ' \
--quiet \
-c "SELECT message
FROM error_message
WHERE created_at > '$t1' and created_at < '$t'")
)
error_type=${ROW[0]}
echo $error_type
Don't use an array, use an ordinary string variable to contain the whole result.
error_type=$(psql \
-X \
-U $DB_USER \
-h $DB_HOST \
-d $DB_NAME \
-p $DB_PORT \
--single-transaction \
--set AUTOCOMMIT=off \
--set ON_ERROR_STOP=on \
--no-align \
-t \
--field-separator ' ' \
--quiet \
-c "SELECT message
FROM error_message
WHERE created_at > '$t1' and created_at < '$t'")
echo "$error_type"
Remember to quote variables unless you need word splitting and wildcard expansion to be done.

Add a conditional SORT variable to mongoexport

I'm trying to set up a conditional --sort option in mongoexport but I'm having trouble with the string interpretation of my variable.
Here is the code I'm trying to run :
#!/bin/bash
if [[ $IS_PROD == "true" ]]
then
SORT='--sort "{_id : -1}"'
else
SORT=""
fi
$MONGODB_HOME/bin/mongoexport \
--host=$HOST \
--port=$PORT \
--username=$USER \
--password=$PWD \
--db=$DB \
--limit=$LIMIT \
$SORT \
--collection=my_collection | \
sed 's,\\,\\\\,g' \
> $TMP_FILE
While running this I get the following error error parsing command line options: invalid argument for flag '--sort' (expected string): invalid syntax
I've tried several quotes configuration and still couldn't make it work. Could someone please help me on this one?
Thanks
using bash array
#!/bin/bash
if [[ $IS_PROD == "true" ]]
then
SORT=(--sort "{_id : -1}")
else
SORT=()
fi
$MONGODB_HOME/bin/mongoexport \
--host=$HOST \
--port=$PORT \
--username=$USER \
--password=$PWD \
--db=$DB \
--limit=$LIMIT \
"${SORT[#]}" \
--collection=my_collection | \
sed 's,\\,\\\\,g' \
> $TMP_FILE
Explanation: using single quotes prevent shell expansions and double quotes are literal, but after variable expansion the double quotes are still litteral and expanded string is split by spaces.
Otherwise to work around unbound variable bug
#!/bin/bash
options=(--host=$HOST \
--port=$PORT \
--username=$USER \
--password=$PWD \
--db=$DB \
--limit=$LIMIT)
if [[ $IS_PROD == "true" ]]
then
options+=(--sort "{_id : -1}")
fi
$MONGODB_HOME/bin/mongoexport \
"${options[#]}" \
--collection=my_collection | \
sed 's,\\,\\\\,g' \
> $TMP_FILE

Bash - pass argument from array

I am using bash to call tool written in java (gatk) and I need to pass multiple arguments from array as input arguments. I tried it this way, but it seems not working. Could you please help me, how to solve it?
Code:
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
for foo in array
do
--variant $foo \
done
What i want to be called:
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
for foo in array
do
--variant file1 \
--variant file2 \
--variant file3 ...etc
done
edit: sorry for misunderstandings
array=("file1","file2","file3"...)
Thanks
I assume that what you actually want is that if array contains a b c, to have the command
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
--variant a --variant b --variant c
If that is so, you can prepare a second array:
array=("file 1" "file 2" "file 3")
declare -a fullarray
for i in "${array[#]}"
do
fullarray+=( --variant "$i" )
done
And then
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
"${fullarray[#]}"
This will also make sure that if any of the names in array contains a space, it will still be passed as a proper parameter and not split into two (assuming that you didn't mess it up when you added it to the array).
With echo and $():
array=(file1 file2 file3)
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
$(for foo in ${array[*]}
do
echo -n " --variant $foo"
done)
You can do this with the following:
java $GATK \
-T GenotypeGVCFs \
-R $ref \
-o output.vcf \
${array[*]/#/ --variant }
#RealSkeptic's answer is the best. I'd write, for readability:
array=( "file 1" "file 2" "file 3" )
args=(
"$GATK"
-T GenotypeGVCFs
-R "$ref"
-o output.vcf
)
for foo in "${array[#]}"; do args+=( --variant "$foo" ); done
java "${args[#]}"

Makefile: Splitting a string and looping through results

I am trying to write a target in a makefile which will read a variable(having IPs) from one of the .mk file and if a space separated list found split it and take some action.
Issue i am facing that the string do not split and in for loop do not get the value either.
Have tried following
GWTS_FE_IPS=2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5
test:
$(eval IPS=$(shell echo "$(GW_IPS)" |awk -F " " '{print NF}'))
if [ ${IPS} -gt 1 ]; then \
echo "Multiple Ips [$(GW_IPS)]"; \
for ip in $(shell echo "${GW_IPS}" | sed -e 's/ /\n/g'); \
do \
echo ".... $(ip) ...."; \
done \
else \
echo "Single IP [$(GW_IPS)]"; \
fi
Result i get is
2600:40f0:3e::2n2600:40f0:3e::3n2600:40f0:3e::4n2600:40f0:3e::5
if [ 4 -gt 1 ]; then \
echo "Multiple Ips [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]"; \
for ip in 2600:40f0:3e::2n2600:40f0:3e::3n2600:40f0:3e::4n2600:40f0:3e::5; \
do \
echo ".... ...."; \
done \
else \
echo "Single IP [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]"; \
fi
Multiple Ips [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]
.... ....
Can any one give some pointers.
You are trying to do too many things at once without testing any of them. When you try new tools, try them one at a time.
GWTS_FE_IPS=2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5
IPS := $(words $(GWTS_FE_IPS))
test:
#if [ ${IPS} -gt 1 ]; then \
echo "Multiple Ips [$(GW_IPS)]"; \
for ip in $(GWTS_FE_IPS) ; \
do \
echo ".... $$ip ...."; \
done \
else \
echo "Single IP [$(GW_IPS)]"; \
fi

Resources