Zak
Zak

Reputation: 7515

Bash multi-line command with input | output

My question is a simple one. I am looking to simply format my bash code into something a little more readable for other users .. While this works:

mysql --login-path=main-data -N -e "SELECT section_id FROM db.table WHERE contractor_id = '1'" | while read contractor_info_id; do

#......//

done

I don't understand why the backslash doesn't work with a input output statement separated by | .. IE

mysql --login-path=main-data -N -e "SELECT section_id\
FROM db.table\
WHERE contractor_id = '1'" | while read contractor_info_id; do

#......//

done

It generates a fatal error Syntax error: "done" unexpected

Why does multi-line formatting work on a single output command such as:

long_arg="my very long string\
 which does not fit\
 on the screen"

But not on an output | input command ?

Upvotes: 1

Views: 1397

Answers (4)

John Kugelman
John Kugelman

Reputation: 361739

mysql "..." | while read contractor_info_id; do
    #......//
done

Syntax error: "done" unexpected

This error is coming from bash, not from mysql, so we can rule out anything inside the double quotes. It doesn't matter what you're doing with backslashes there.

Do you actually have anything in place of #......//? You need at least one command inside the loop, otherwise you'll get this "done" unexpected error. Try :, a no-op command. That'll at least get rid of the syntax error.

mysql "..." | while read contractor_info_id; do
    :
done

"SELECT section_id\
FROM db.table\
WHERE contractor_id = '1'"

The backslashes won't cause bash any heartburn but they do lead to invalid SQL. Once the shell deletes the backslashes and newlines you're left with:

"SELECT section_idFROM db.tableWHERE contractor_id = '1'"

To fix that you can either add spaces, or just leave out the backslashes. MySQL doesn't care if there are newlines, nor does bash, so you can stick with what you wrote originally.

"SELECT section_id
FROM db.table
WHERE contractor_id = '1'"

Upvotes: 1

Paul Hodges
Paul Hodges

Reputation: 15348

Backslashes not needed inside quotes, and SQL isn't usually picky about extra whitespace anyway.

I don't have mysql installed here, but try this and let me know if it doesn't behave...

mysql --login-path=main-data -N -e "
  SELECT section_id
    FROM db.table
   WHERE contractor_id = '1'
" | while read contractor_info_id
    do echo $contractor_info_id
    done

Upvotes: 1

Zak
Zak

Reputation: 7515

The reason for this happening to me was a unique issue I was having with my IDE .. It was inserting an actual character for a line break rather than just a physical line-break itself. The problem wasn't the syntax I was attempting, rather the inserted characters on save. Thanks to all who thoughtfully answered my question. My original un-escaped syntax was correct to begin with.

Upvotes: 0

danielhoherd
danielhoherd

Reputation: 481

The reason the escaped line ending does not work in your mysql use case is that mysql does not require an escaped line ending. The text between the two double quotes is treated as the string, and escaped characters are no interpreted. (eg: \t would not put in a tab). You can se this in action with these examples:

$ echo "Hello from line one
> and hello from line two"
Hello from line one
and hello from line two
$ echo Hello from line one \
> and also from line one
Hello from line one and also from line one

TL;DR: Within double-quotes, the slash and CR is treated as part of the string, not interpreted as an escape character.

Upvotes: 1

Related Questions