Search code examples
linuxbashuser-input

Linux How to take hostfile as an input from user and call it into script


I am using the below script for pinging the multiple Linux hosts which works perfectly fine if it put the hostfile by hardcoding into script itself but i want that to be on user input based.

While i am using read the file as an input from user but thats getting fail, please suggest me what i am doing wrong here.

#!/bin/bash
read -rsp $'Please Enter your hostFile name: ' target_File
echo $target_File
printf "$(date) Starting the Ping Check...."
function pingHost () {
    target_host=${1}
    ping -c2 ${target_host} >/dev/null 2>&1 &&
    printf "%-20s %-10s\n" "host ${target_host}" "ping SUCCESS" ||
    printf "%-20s %-10s\n" "host ${target_host}" "ping FAILED"
}
#
# Variable "data" seeks the filename containing host list.
data="$(< target_File)"
for line in $data
do
    pingHost ${line} &
done
wait
printf "Completed @=> $(date)"
printf "\n"

While giving the hostfile inside the script then it works as follows ..

data="$(< hostfile)" <-- this hard-coded file containing hosts

$ ./ping_parallel.bash
Sun May 22 10:55:24 IST 2022 Starting the Ping Check....

host savfav0194         ping SUCCESS
host savfav0268         ping SUCCESS
host savfav0263         ping SUCCESS
host savfav0196         ping SUCCESS
host savfav0260         ping SUCCESS
host savfav0259         ping SUCCESS
host savfav2088         ping SUCCESS
host savfav2135         ping SUCCESS
host savfav2136         ping SUCCESS
host savfav3088         ping SUCCESS
host savfav0257         ping SUCCESS
host savfav0262         ping SUCCESS
host savfav0261         ping SUCCESS
host savfav0270         ping SUCCESS
host savfav0255         ping SUCCESS
host savfav0265         ping SUCCESS
host savfav0266          ping FAILED

Completed @=> Sun May 22 10:55:26 IST 2022

Failing while trying user input :

Please Enter your hostFile name: target_File
Sun May 22 10:58:54 IST 2022 Starting the Ping Check...../ping_parallel.bash: line 22: target_File: No such file or directory
Completed @=> Sun May 22 10:58:54 IST 2022

Solution

  • As mentioned in the comment and also a good practice to use while over for, please refer for bash manual here.

    I just modified it with while, hopefully it should the Job for you!

    #!/bin/bash
    read -p $'Please Enter your hostFile name: ' target_File
    printf "$(date) Starting the Ping Check...."
    function pingHost () {
        target_host=${1}
        ping -c2 ${target_host} >/dev/null 2>&1 &&
        printf "%-20s %-10s\n" "host ${target_host}" "ping SUCCESS" ||
        printf "%-20s %-10s\n" "host ${target_host}" "ping FAILED"
    }
    while read -r line;
    do
        pingHost $line &
    done < $target_File
    wait
    printf "Completed @=> $(date)"
    printf "\n"
    

    Slight modification with your Script:

    #!/bin/bash
    read -rp $'Please Enter your hostFile name: ' target_File
    # Don't use variables in the printf format string. Use printf '..%s..' "$(date)".
    printf "Starting the Ping Check %s ....\n" "$(date)"
    # You Can Just use function name hence its your choice, i just removed.
    # pingHost i changed to "icmp_echo" as i used that 
    # function pingHost  () {
    icmp_echo  () {
        target_host=${1}
        ping -c2 "${target_host}"  >/dev/null 2>&1 &&
        printf "%-32s %-10s\n" "host ${target_host}" "ping SUCCESS" ||
        printf "%-32s %-10s\n" "host ${target_host}" "ping FAILED"
    }
    # Use a while loop and the read command. Where The -r option to read prevents backslash interpretation.By default,read modifies each line read, 
    # by removing all leading and trailing whitespace characters (spaces and tabs, if present in IFS).If that is not desired, the IFS variable may 
    # be cleared
    while IFS= read -r line
    do
        icmp_echo  "$line" &
    # Double quote to prevent globbing and word splitting.
    done < "$target_File"
    wait
    # Don't use variables in the printf format string. Use printf '..%s..' "$(date)".
    printf "Completed @=> %s" "$(date)"
    printf "\n"