M
M
Maxim Kudryavtsev2016-06-17 05:28:02
linux
Maxim Kudryavtsev, 2016-06-17 05:28:02

Why does script execution always follow the ELSE branch?

Good day colleagues.
I have the following code in a bash script:

#!/bin/bash
set -e
if [ -n "$(cat /etc/passwd | cut -d: -f1 | grep -q "$CUSTOM_USER")" ]; then
    echo "FATAL ERROR: user \"$CUSTOM_USER\" already exist"
    exit 1
else
    USER_CREATE_CMD="$CUSTOM_USER"
fi

The whole problem is in the first line. I pass an existing or non-existing user - processing goes along the else branch in any case.
The logic of what needs to be done is simple - if a user with the same name is already in the system, then throw an error. If not, write its name to a variable that will be used later in the code.
I don’t often intersect with bash scripts, so can you explain why this happens? What am I missing?
UPD:
The unquoted version produces exactly the same behavior
if [ -n $(cat /etc/passwd | cut -d: -f1 | grep -q "$CUSTOM_USER") ]; then

Answer the question

In order to leave comments, you need to log in

6 answer(s)
A
Aves, 2016-06-17
@Aves

grep -qalways an empty string, [ -n '' ]will always be false
If you need to check the exit code, you can do

if cat /etc/passwd | cut -d: -f1 | grep -q "$CUSTOM_USER"; then

In general, grep is not very suitable for determining the presence of a user, it is better to doif id $CUSTOM_USER &>/dev/null; then

A
Azazel PW, 2016-06-17
@azazelpw

#!/bin/bash
while IFS=":" read LOGIN_NAME LOGIN_PASSWD LOGIN_UID LOGIN_GID LOGIN_DESC LOGIN_HOME LOGIN_SHELL ;
do
echo $LOGIN_NAME
if 
then
echo "FATAL ERROR: user \"$CUSTOM_USER\" already exist"
else
 USER_CREATE_CMD="$CUSTOM_USER"
fi
done < /etc/passwd

A
alegzz, 2016-06-17
@alegzz

why shouldn't it be false?
if ; then

J
jcmvbkbc, 2016-06-17
@jcmvbkbc

man grep says
-q: Quiet; do not write anything to standard output.
And the line if [ -n "$(cat /etc/passwd | cut -d: -f1 | grep -q "$CUSTOM_USER")" ]; just checks that there is something on the output.
Check the grep exit code, or replace this whole canoe with getent passwd "$CUSTOM_USER" and check its exit code.

A
abcd0x00, 2016-06-18
@abcd0x00

Programs return an exit code (return code). If grep finds text, it prints the found text and returns a success exit code (zero). If grep finds no text, it prints nothing and returns a failed exit code (one). Here, the -q option turns off only the output text, and the exit code is both returned and returned. In the shell, the $() construct only deals with output text and does not know about the return code. Therefore, for her, the found and not found texts look the same - in the form of emptiness.

K
Kevin1, 2016-07-07
@Kevin1

Good afternoon,
In shell/bash, it's very common to check strings like this: if [ "x" != "x$some_var" ]; then ...
thus avoiding comparison with the empty string.
Try writing the condition like:

if [ "x" != "x$(cat /etc/passwd | cut -d: -f1 | grep -q "$CUSTOM_USER")" ];

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question