-1

Script only opens up Postgres but does not process any commands after that.

#/bin/bash
filename='mac_addresses.txt'
filelines=`cat $filename`
echo Start
for line in $filelines ; do
    psql pcoip_mc_db postgres
    update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
    \q
done

Expected results are to see this script go line by line in the mac_addresses.txt file and, after connecting to Postgres, run this command on every mac address in mac_addresses.txt:

update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
0

2 Answers 2

0

The problem is that the update and the \q are not handled as input to the psql command, but as shell commands. You have to tell bash that this is supposed to be the standard input for psql, for example with a “here document”:

#/bin/bash
filename='mac_addresses.txt'
filelines=`cat $filename`
echo Start
for line in $filelines ; do
    psql pcoip_mc_db postgres <<EOF
    update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
EOF
done

Warning: this code is still unsafe and vulnerable to SQL injection. If any of the entries in the file contain spaces or single quotes, you will get errors and worse.

Sign up to request clarification or add additional context in comments.

Comments

0

These 3 lines are not doing what you expect:

psql pcoip_mc_db postgres
update endpoint set endpoint_group_id = 15 where mac_address='$filelines';
\q

Each line should be a bash command. So you need to wrap the SQL query in a string and then pass it to the psql command. Like this:

psql pcoip_mc_db postgres -c "update endpoint set endpoint_group_id = 15 where mac_address='$line';"

(-c tells psql to execute the string as an SQL command)

Also, this bash will be a bit inefficient as you're going to connect and disconnect from the database for every line of the file. A more idiomatic bash script would transform each line of the file into an appropriate SQL expression, and then pipe all the generated SQL into a single psql connection. This can replace your script with a single line:

<"$filename" awk '{print "update endpoint set endpoint_group_id = 15 where mac_address=\'"'"'"$0"\'"'"';"}' | psql pcoip_mc_db postgres

(As a further improvement, you could even generate a single SQL query using an IN clause, such as: update endpoint set endpoint_group_id = 15 where mac_address IN ('mac1', 'mac2', ...);)

12 Comments

Do I need the < in front of $filename? Will this one liner pull the mac addresses from my mac_address.txt file? I am getting the following: ]$ <$filename awk '{print "update endpoint set endpoint_group_id = 15 where mac_address=\'"'"'"$0"\'"'"';"}' | psql pcoip_mc_db postgres -bash: $filename: ambiguous redirect $ <$mac_addresses.txt awk '{print "update endpoint set endpoint_group_id = 15 where mac_address=\'"'"'"$0"\'"'"';"}' | psql pcoip_mc_db postgres -bash: .txt: No such file or directory
The "<" tells bash to treat that file as input to the awk command. I've slightly changed the answer to put quotes around "$filename" (this is an annoying bashism to handle whitespace in the filename variable)
Thank you George! So will I still have a separate mac_addresses.txt file? If I am understanding correctly this code below will go inside my script.sh file? <"$filename" awk '{print "update endpoint set endpoint_group_id = 15 where mac_address=\'"'"'"$0"\'"'"';"}' | psql pcoip_mc_db postgres
You need to either define "$filename" the same way you do in your question, with filename='mac_addresses.txt' or you could replace the beginning of the command directly with <mac_addresses.txt
So I ran this and received: ./script.sh awk: cmd. line:1: warning: escape sequence \'' treated as plain '' UPDATE 1 UPDATE 1 Is this anything to be concerned about?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.