0

Early in this script users and their credentials are read into variables.

The following code works as intended to check the credentials of a mysql user.

lu="test"
lp="test-password"
ldb="local_db"

if mysql -u $lu -p"$lp" $ldb -e "quit"; then
  printf "true"
  return 0;
else
  printf "false"
  return 1;
fi

As this code executes it outputs the mysql warning about using passwords on the command line. I'd like to suppress that warning from the output while still evaluating the exit code of the mysql command.

In this answer on how to suppress the error message by using mysqlcommand 2>&1 | grep -v "Warning: Using a password", the output is stripped of only the warning. All other output is still shown.

I've tried to integrate this into my code without success. Is there a way I can do this?

dimmech
  • 481
  • 1
    Is there no other way to pass the password than on the command line? Why not fix the problem you are being warned about, rather than silencing the (valid) error message? – Wildcard Oct 19 '17 at 02:29
  • Because if you read my question, you'd see that I answered that preemptively. The script specifically works by reading in a file and I don't want to change that! – dimmech Oct 19 '17 at 03:35
  • 1
    See https://unix.stackexchange.com/a/205184/135943 for how to fix this securely. – Wildcard Oct 19 '17 at 05:03
  • Can't you just redirect standard error from mysql to /dev/null? Or do you still want to see other possible errors and warnings? – Kusalananda May 23 '18 at 13:47

2 Answers2

1

Yes. The problem you have is that the exit status of a pipeline is the exit status of the last element in the pipeline.

For recent versions of bash you can use the PIPESTATUS array, and write

mysqlcommand 2>&1 | grep -v ...
if [ ${PIPESTATUS[0]} -eq 0 ] ; then
    printf "true\n"
    return 0
 else
 ...

More portable solutions exist. You can run

( mysqlcommand ; echo $? > lastsqlret ;) 2>&1 | grep ...
if grep '^0$' lastsqlret ; then
...

using a temporary file and you can avoid the temporary file by using file descriptor manipulation.

icarus
  • 17,920
  • This is a hobby and I haven't had time to try this until now. Thanks for the pointer, I had to escape the brackets on the search term for the warning to be picked up i.e. ... 2>&1 |grep -v "\[Warning\]". – dimmech Dec 21 '17 at 18:54
  • Grep looks for regular expressions, and [ has a meaning in them. You can use the -F flag to make the search look for fixed strings. – icarus Dec 22 '17 at 22:07
0

The exit status of a pipe is always the exit status of the last command. In bash you can change this behavior by setting set -o pipefail. With this option, the entire command will have the exit status of the last non-zero exit status encountered, from the man page:

The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.

Example:

#!/bin/bash

false | true
echo "Without pipefail: $?"

set -o pipefail
false | true
echo "With pipefail: $?"

Produces:

Without pipefail: 0
With pipefail: 1
jlh
  • 221