简体   繁体   中英

Exiting if a command returns an empty string when run in a heredoc (ssh … <<EOF)

I want my command to exit with a status of failure (1), if the command returns no output in EOF . But I'm unable to use variable to store the command or store the output in a file.

For example:

#!/bin/bash
a='Some other commands in local machine'
ssh ubuntu@xx.xx.xx.xx << EOF
echo $a;
ldt=$(date +'%Y%m%d')
awk -v start="$(date +'%Y/%m/%d %H:%M' --date '-1000 min')" - F'[[:space:]]*[|][[:space:]]*' '
(\$4>=start) && /INFO: Server startup in/
' /some/file/path-\$ldt.log
EOF

Now, If the command gives an empty output, it should exit 1 and if some text is displayed, it should exit 0 .

I'm unable to store the awk command in variable. If I store it in variable, the awk command doesn't work. Tried storing the output in the file but this also fails.

Please help me find a solution.

When you use an unquoted heredoc -- <<EOF -- expansions therein are run before it's fed on stdin to the command being invoked.

This includes $(awk ...) , making it difficult to correctly capture output from code generated on this way and operate on it later.

So -- one thing you can do is use a quoted heredoc, and then go back to the approach you tried earlier (capturing the awk results and branching on them), and it should work correctly.

The other thing you can do is have awk set its own exit status based on whether any matches are found.

Setting Exit Status In awk

#!/bin/bash
a='Some other commands in local machine'
printf -v args_q '%q ' "$a"

ssh ubuntu@xx.xx.xx.xx "bash -s $args_q" <<'EOF'
  a=$1
  echo "$a"
  ldt=$(date +'%Y%m%d')
  awk -v start="$(date +'%Y/%m/%d %H:%M' --date '-1000 min')" -F'[[:space:]]*[|][[:space:]]*' '
    BEGIN { found=0 }
    ($4>=start) && /INFO: Server startup in/ { print $0; found=1; }
    END { if (found == 0) { exit(1) } else { exit(0) } }
  ' "/some/file/path-$ldt.log"
EOF

Setting Exit Status After awk

#!/bin/bash
a='Some other commands in local machine'
printf -v args_q '%q ' "$a"

ssh ubuntu@xx.xx.xx.xx "bash -s $args_q" <<'EOF'
  a=$1
  echo "$a"
  ldt=$(date +'%Y%m%d')
  awk_result=$(
    awk -v start="$(date +'%Y/%m/%d %H:%M' --date '-1000 min')" -F'[[:space:]]*[|][[:space:]]*' '
      BEGIN { found=0 }
      ($4>=start) && /INFO: Server startup in/ { print $0; found=1; }
      END { if (found == 0) { exit(1) } else { exit(0) } }
    ' "/some/file/path-$ldt.log"
  )
  [[ $awk_result ]] && echo "$awk_result"
  [[ $awk_result ]] # success only if awk_result is nonempty
EOF

Note that this only works if <<EOF has been changed to <<'EOF' , such that the awk command is evaluated remotely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM