Bash脚本故障:端口检测无效输出且循环无法终止
Hey there! Let's troubleshoot why your port-checking Bash script isn't working as intended. You said it should stop at the first open port (which should be 22, since all except 8080 are open) but instead it's spitting out invalid output and looping endlessly. Let's break down the common issues and fix this.
First, let's assume you might have a script that looks something like this (a common mistake):
ports=(22 80 443 8080) for port in "${ports[@]}" do nc -zv localhost $port if [ $? -eq 0 ]; then echo "succeeded $port" fi done
What's going wrong here?
- Unsuppressed output: The
nc -zvcommand prints its own connection messages (likeConnection to localhost 22 port [tcp/ssh] succeeded!) directly to the terminal—this is your "invalid output". - No loop termination: Without a
breakstatement inside theifblock, the script will keep checking every port in your list even after finding the first open one. - Potential hanging: If you're using a tool like
telnetinstead ofnc(or anncversion without timeout), the command might hang indefinitely waiting for a response, causing the loop to get stuck.
Here's the fixed script
#!/bin/bash # Define your list of ports to check ports=(22 80 443 8080) for port in "${ports[@]}" do # Use nc with a 1-second timeout, suppress all output nc -zv -w1 localhost "$port" > /dev/null 2>&1 # Check if the command succeeded (port is open) if [ $? -eq 0 ]; then echo "succeeded $port" # Immediately exit the loop once we find the first open port break fi done
Key fixes explained:
-w1: Adds a 1-second timeout tonc—this prevents the command from hanging if a port doesn't respond quickly.> /dev/null 2>&1: Redirects both standard output and error to/dev/null, so you only get your customsucceeded $portmessage.break: Stops the loop as soon as we find the first open port, so the script doesn't waste time checking the rest.
If you were using telnet instead of nc, switch to nc (it's more reliable for scripted port checks). If you must use telnet, you can add a timeout with something like timeout 1 telnet localhost $port > /dev/null 2>&1.
This script will output exactly succeeded 22 and stop, just like you expected.
内容的提问来源于stack exchange,提问作者Eka

