2

I have created a bash script test.sh to check if some ports are listening or not. Since I dont want to hard-code either the ports or the command in the shell script, I put them both in a file config_file like key value pairs. Let me show the file and schell script below;

test.sh

#!/bin/bash
cat config_file| while read port command; do
    if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then
        echo "" > /dev/null
    else
        eval "$command"
    fi
done

config_file

80 /bin/bash /home/user/sample_script1.sh
22 /bin/bash /home/user/sample_script2.sh

Both files sample_script1.sh and sample_script2.sh are meant to touch some sample file. When I run ./test.sh , the sample files gets created correctly (means sample_script1.sh and sample_script2.sh got invoked). But I get

./test.sh: line 8: This: command not found

in the terminal. What could be the reason and how to fix this?

Alfred
  • 21,058
  • 61
  • 167
  • 249
  • 2
    See [Why should eval be avoided in Bash, and what should I use instead?](https://stackoverflow.com/q/17529220/4154375). – pjh May 18 '23 at 12:33
  • 2
    [Shellcheck](https://www.shellcheck.net/) identifies some issues with the code. The report includes links to more information about the problems and how to fix them. It's a good idea to run [Shellcheck](https://www.shellcheck.net/) on all new and modified shell code. – pjh May 18 '23 at 12:35

1 Answers1

2

You could split the config file to another field, something like:

#!/usr/bin/env bash

cat config.txt | {
  while read -r port shell command; do
    echo "$port"
    [[ -e "$shell" && -e "$command" ]] &&
    "$shell" "$command"
  done
}

It it is a file then you can do without the UUOC, just use shell redirection, something like:

#!/usr/bin/env bash

while read -r port shell command; do
  echo "$port"
  [[ -e "$shell" && -e "$command" ]] &&
  "$shell" "$command"
done < config.txt

Or if the input is coming from a stream/command, something like:

#!/usr/bin/env bash

while read -r port shell command; do
  echo "$port"
  [[ -e "$shell" && -e "$command" ]] &&
  "$shell" "$command"
done < <(my_command_with_output)

  • Make sure that there are no windows file ending aka carriage returns or some invisible characters from both files in question.
Jetchisel
  • 7,493
  • 2
  • 19
  • 18