0

I have a bash script, where the psql connect string is stored in a variable.

After this I have defined three functions. —————————

export PC="usr/bin/psql --host=abx --port=1234 --dbname=A --username=user"

function one
{
$PC<<EOF
SEL 1;
EOF
}

function two
{
while IFS= read -r line
do
 three $line
done < file
}

function three
{
if [ $1 == Y ]
then
$PC<<EOF
Update table;
EOF
fi
}

#main function
one
two

————————

When I execute the script, function one works, retrieves data from the database, but function three invoked from function two keeps failing with the message

bash: psql -u …($PC expanded): command not found

I have checked both the PATH variable and IFS, no issues there.

Now, if I use the expanded $PC inside the function three definition, then it works.

So only when I use a variable it fails? Any ideas?

roaima
  • 107,089
  • 14
  • 139
  • 261
Bash3d
  • 1
  • 1
  • 1
    [How can we run a command stored in a variable?](https://unix.stackexchange.com/q/444946/108618) [What are curly quotes and can I use them in my code?](https://unix.stackexchange.com/q/704762/108618) – Kamil Maciorowski Jan 18 '23 at 20:59
  • @KamilMaciorowski Would you care to explain? I am able to run the command stored in a variable from first function. Only when I call it from a function within a function it fails. How is quotes/braces significant here? – Bash3d Jan 18 '23 at 21:22
  • 1
    @roaima sorry, that was a typo in question. I am using straight quotes in the actual code. Corrected it in question now. – Bash3d Jan 18 '23 at 21:58
  • "_I am able to run the command stored in a variable from first function_" - it's an unreliable way of running a command. Use functions for commands and variables for data – roaima Jan 18 '23 at 22:03
  • @roaima I Agree, but unfortunately I cannot change the method. This variable in question is set in a master script that’s read only and we just source them in other scripts. Even if I were to use a function here in my script, I will have to use this variable, and that again yields the same result. – Bash3d Jan 18 '23 at 22:41
  • Then you need to tell the author of the master script that they are using functions and variables incorrectly. This is a common cause of unexpected errors – roaima Jan 18 '23 at 23:00
  • @roaima Alright. But could you please help me understand why this particular function alone fails to recognize a properly expanded variable as a command, while the initial function can? And thanks for the responses.. I appreciate it.. – Bash3d Jan 18 '23 at 23:32

1 Answers1

0

This is untested, but what if you tweaked your code to be something like this?

pc()
{
  /usr/bin/psql --host=abx --port=1234 --dbname=A --username=user
}

one()
{
  pc << EOF
SEL 1;
EOF
}

two()
{
  while IFS= read -r line
  do
    three "$line"
  done
}

three()
{
  if [ "$1" = Y ]
  then
    pc << EOF
Update table;
EOF
  fi
}

# main function

one
two < file
Jim L.
  • 7,188
  • 1
  • 13
  • 25
  • Hi Jim, Thanks for the reply. Yes, this works. So does using the expanded value directly in function defintion. Any idea why the variable method would work in a function, but not from within a second function, even when its getting expanded correctly? – Bash3d Jan 18 '23 at 21:39
  • Thanks, @roaima! Yes, my reply was rather hastily done. – Jim L. Jan 18 '23 at 22:56
  • @roaima Yes, I typically do. Again, too much cut-and-paste. – Jim L. Jan 18 '23 at 23:08
  • @Bash3d it seems that `while IFS= ` is overwriting the `IFS` variable (this is set to `''` empty string) and is passed to function three. I was unable to reproduce your behavior, all works well in my machine (I'm using Linux and bash version is 5.2.15). – Edgar Magallon Jan 19 '23 at 02:42
  • @Bash3d A possible solution in your case is in `function three` add this line at the beginning: `IFS=' '` (set IFS to a space char) and instead of using curly braces for your function, you can use parenthesis. It'd be: `three() ( your code )`. Or instead of parenthesis in your function three you can call this one by using: `(three "$line")` in your `function two` – Edgar Magallon Jan 19 '23 at 02:45
  • @EdgarMagallon I too suspected that IFS is messing up the command. So tried setting the IFS back to default inside function three before the command, but to no avail. It really irks me that I can’t find an explanation for this weird behaviour. I will try using parenthesis in function definition as you suggested, but doubt a sub shell is going to help. Will test and update here in some time. Thanks! – Bash3d Jan 19 '23 at 03:44