How to Display Nc Return Value in Linux Shell Script

How to use the exit code of netcat command in a if condition?

I think the problem comes down to usage of how you are storing the nc command in a variable to eval it later. When you did

nc_output=$(nc ${host} ${port} -w 5)
# ^^ ^

The marked syntax $(..) is for command substitution in bash, which runs the command inside and stores the output of the command in the variable used. So the above line runs the nc command and stores the output returned in the variable nc_output. Remember this only stores the standard output of the command and not the return code of the nc command which should been fetched from the variable $?

I'm guessing your intention was to store the command in a variable and then eval it once and get the exit code, but you are doing it wrong by eval-ing the output returned from the nc command which is roundabout and unnecessary.

The ideal way should have been just

nc "${host}" "${port}" -w 5
nc_exit_code=$?

and use this variable in the condition

if [ "$nc_exit_code" -ne 0 ]; then

Note that the $ prefix before the variable name. You need to use the $var syntax to access the value of the identifier var in shell syntax. You weren't using the symbol in your original post. Not doing so will compare a literal string nc_output with 0 which does not make sense as the native types of two are different from one another.

Also storing this exit code explicitly in a variable is redundant, the if conditionals work directly on the exit code of the command returned, so just

if ! nc "${host}" "${port}" -w 5; then
echo "PORT ${port} CLOSED on ${host}"
else
echo "PORT ${port} OPEN on ${host}"
fi

should be sufficient for your logic.

A bash script written around the nc command. How do I prepend text before each line?

Try this:

sed -u "s/$/said user2 /" | nc xxx.xxx.xxx.xxx 44444
sed -u "s/$/ said user1 /" | nc -l 44444

What does the ! in `while ! nc ...; do...; done` mean

Here, ! is a keyword (thanks to user1934428 for the correction) which performs a NOT operation.

If the command nc -z "$host" "$port" didn't performed successfully, it would return "false" (i.e. a non-zero value). Hence, the ! [nc command] would return "true" (i.e. zero).

So it's like "while this nc command fails, do the loop. After ten tries ($j is greater than or equal to 10), give up".

You might want to have a peek on this interactive tutorial and this Wikibook.

How to properly capture the return value of a unix command?

Variables are interpolated inside backticks, so the $? in

my $pstate=`nc -z 8.8.8.8 441; echo $?`

refers to Perl's $?, not the shell's $?. And what the shell sees is something like

nc -z 8.8.8.8 441 ; echo 0

To fix this, you can escape the shell command

my $pstate=`nc -z 8.8.8.8 441; echo \$?`;

or use the qx operator with the single quote as a separator (this is the one exception to the "interpolation inside the qx operator" rule)

my $pstate=qx'nc -z 8.8.8.8 441; echo $?';

or use readpipe with a non-interpolated quote construction

my $pstate= readpipe( 'nc -z 8.8.8.8 441; echo $?' );
my $pstate= readpipe( q{nc -z 8.8.8.8 441; echo $?} );

assign output of memcache command to a variable in shell/bash script

You could just do:

output=$(echo -e 'get mykey\r' | nc localhost 11211 | awk 'NR==2')
echo "$output"

but check the man page for nc to see if it has any options to control what it outputs.

Get return value of command mv -n linux

No, $? won't tell you if the -n option prevented mv from doing the move since the exit status will be 0 in this case.


Solution 1: you can check that the original file didn't move...

mv -n file1 file2
[ -e file1 ] && echo "Hmmm, mv didn't have any effect"

However there is a possibility of a race condition if another program recreates file1 in the meantime between the move and your test.


Solution 2: since you seem to use GNU mv, the -v option can be helpful to find out if the move succeeded

if mv -v -n file1 file2 | grep -q .; then
echo "The move succeeded"
fi

With -v, if the move occurs, mv will output renamed 'file1' -> 'file2'. Piping its output to grep -q . tests whether mv output anything on its standard output.

If there is an error, mv will output on its standard error and the grep will fail too.

Trying to embed newline in a variable in Bash

Summary

  1. Inserting a new line in the source code

     p="${var1}
    ${var2}"
    echo "${p}"
  2. Using $'\n' (only Bash and Z shell)

     p="${var1}"$'\n'"${var2}"
    echo "${p}"
  3. Using echo -e to convert \n to a new line

     p="${var1}\n${var2}"
    echo -e "${p}"

Details

  1. Inserting a new line in the source code

     var="a b c"
    for i in $var
    do
    p="$p
    $i" # New line directly in the source code
    done
    echo "$p" # Double quotes required
    # But -e not required

    Avoid extra leading newline

     var="a b c"
    first_loop=1
    for i in $var
    do
    (( $first_loop )) && # "((...))" is Bash specific
    p="$i" || # First -> Set
    p="$p
    $i" # After -> Append
    unset first_loop
    done
    echo "$p" # No need -e

    Using a function

     embed_newline()
    {
    local p="$1"
    shift
    for i in "$@"
    do
    p="$p
    $i" # Append
    done
    echo "$p" # No need -e
    }

    var="a b c"
    p=$( embed_newline $var ) # Do not use double quotes "$var"
    echo "$p"
  2. Using $'\n' (less portable)

    bash and zsh interprets $'\n' as a new line.

     var="a b c"
    for i in $var
    do
    p="$p"$'\n'"$i"
    done
    echo "$p" # Double quotes required
    # But -e not required

    Avoid extra leading newline

     var="a b c"
    first_loop=1
    for i in $var
    do
    (( $first_loop )) && # "((...))" is bash specific
    p="$i" || # First -> Set
    p="$p"$'\n'"$i" # After -> Append
    unset first_loop
    done
    echo "$p" # No need -e

    Using a function

     embed_newline()
    {
    local p="$1"
    shift
    for i in "$@"
    do
    p="$p"$'\n'"$i" # Append
    done
    echo "$p" # No need -e
    }

    var="a b c"
    p=$( embed_newline $var ) # Do not use double quotes "$var"
    echo "$p"
  3. Using echo -e to convert \n to a new line

     p="${var1}\n${var2}"
    echo -e "${p}"

    echo -e interprets the two characters "\n" as a new line.

     var="a b c"
    first_loop=true
    for i in $var
    do
    p="$p\n$i" # Append
    unset first_loop
    done
    echo -e "$p" # Use -e

    Avoid extra leading newline

     var="a b c"
    first_loop=1
    for i in $var
    do
    (( $first_loop )) && # "((...))" is bash specific
    p="$i" || # First -> Set
    p="$p\n$i" # After -> Append
    unset first_loop
    done
    echo -e "$p" # Use -e

    Using a function

     embed_newline()
    {
    local p="$1"
    shift
    for i in "$@"
    do
    p="$p\n$i" # Append
    done
    echo -e "$p" # Use -e
    }

    var="a b c"
    p=$( embed_newline $var ) # Do not use double quotes "$var"
    echo "$p"

    ⚠ Inserting "\n" in a string is not enough to insert a new line:
    "\n" are just two characters.

The output is the same for all

a
b
c

Special thanks to contributors of this answer: kevinf, Gordon Davisson, l0b0, Dolda2000 and tripleee.



  • See also BinaryZebra's answer, providing many details.
  • Abhijeet Rastogi's answer and Dimitry's answer explain how to avoid the for loop in the above Bash snippets.

Bash: Loop until command exit status equals 0

Keep it Simple

until nc -z 127.0.0.1 25565
do
echo ...
sleep 1
done

Just let the shell deal with the exit status implicitly

The shell can deal with the exit status (recorded in $?) in two ways, explicit, and implicit.

Explicit: status=$?, which allows for further processing.

Implicit:

For every statement, in your mind, add the word "succeeds" to the command, and then add
if, until or while constructs around them, until the phrase makes sense.

until nc succeeds; do ...; done


The -z option will stop nc from reading stdin, so there's no need for the < /dev/null redirect.

How do I redirect output to a variable in shell?

Use the $( ... ) construct:

hash=$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)


Related Topics



Leave a reply



Submit