LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Array loops and checking if file exists (https://www.linuxquestions.org/questions/linux-newbie-8/array-loops-and-checking-if-file-exists-4175500660/)

TRUNoise 04-05-2014 04:56 AM

Array loops and checking if file exists
 
Quite simple problem I have here. I have made a script to automaticaly run files in folders in the current directory, to start multiple servers at once each from their own file. The problem with that is that the script assumes every folder in the current directory is a server, so for instance if the folder contained server1, server2, and notaserver, the script would try to run the start script in the notaserver folder even though it's not really a server. I need the script to check if the start.sh file exists in the server folder before it tries to execute it; if the file doesn't exist: don't attempt to execute it nor say that the folder/server was found.

Any help is appreciated. :)

Below is the code used in the script. Please tell me what I have to add/remove/change/etc in order for this to happen.

Code:

#!/bin/bash

# General stuff
serverdir='.'
servers=( $(ls -l $serverdir | grep '^d' | awk '{ print $9 }') ) # Print all the folders in the current dir in array form
exec=start.sh # Executable inside server dirs (Almost always start.sh)

# Colors variables for asthetic purposes aka eye candy
RCol='\e[0m'    # Text Reset
# Regular          Bold                Underline          High Intensity      BoldHigh Intens    Background          High Intensity Backgrounds
Bla='\e[0;30m';    BBla='\e[1;30m';    UBla='\e[4;30m';    IBla='\e[0;90m';    BIBla='\e[1;90m';  On_Bla='\e[40m';    On_IBla='\e[0;100m';
Red='\e[0;31m';    BRed='\e[1;31m';    URed='\e[4;31m';    IRed='\e[0;91m';    BIRed='\e[1;91m';  On_Red='\e[41m';    On_IRed='\e[0;101m';
Gre='\e[0;32m';    BGre='\e[1;32m';    UGre='\e[4;32m';    IGre='\e[0;92m';    BIGre='\e[1;92m';  On_Gre='\e[42m';    On_IGre='\e[0;102m';
Yel='\e[0;33m';    BYel='\e[1;33m';    UYel='\e[4;33m';    IYel='\e[0;93m';    BIYel='\e[1;93m';  On_Yel='\e[43m';    On_IYel='\e[0;103m';
Blu='\e[0;34m';    BBlu='\e[1;34m';    UBlu='\e[4;34m';    IBlu='\e[0;94m';    BIBlu='\e[1;94m';  On_Blu='\e[44m';    On_IBlu='\e[0;104m';
Pur='\e[0;35m';    BPur='\e[1;35m';    UPur='\e[4;35m';    IPur='\e[0;95m';    BIPur='\e[1;95m';  On_Pur='\e[45m';    On_IPur='\e[0;105m';
Cya='\e[0;36m';    BCya='\e[1;36m';    UCya='\e[4;36m';    ICya='\e[0;96m';    BICya='\e[1;96m';  On_Cya='\e[46m';    On_ICya='\e[0;106m';
Whi='\e[0;37m';    BWhi='\e[1;37m';    UWhi='\e[4;37m';    IWhi='\e[0;97m';    BIWhi='\e[1;97m';  On_Whi='\e[47m';    On_IWhi='\e[0;107m';

# Echo the detected servers (all the folders in the current dir)
echo
echo -e "${Gre}[${BICya}Detecting servers in $serverdir${Gre}]"
for i in "${servers[@]}"
do
    echo -e "${Gre}[${Cya}$i ${Gre}- ${Cya}Found${Gre}]"
done
echo

# Select server then run executable
echo -e "${Gre}[${BICya}Starting detected servers${Gre}]"
for i in "${servers[@]}"
do
    echo -e "${Gre}[${Cya}$i ${Gre}- ${Cya}Starting${Gre}]"
    echo -e "${Gre}[${Cya}$i ${Gre}- ${Cya}Directory changed${Gre}]"
    cd $i
    echo -e "${Gre}[${Cya}$i ${Gre}- ${Cya}Executing $exec${Gre}]"
    sh $exec
    cd ..
done
echo

# Show online screens to make sure that the servers did actually start
echo -e ${Cya}Online screens${Gre}:${RCol}
screen -ls


grail 04-05-2014 05:09 AM

Quote:

The problem with that is that the script assumes every folder in the current directory is a server
Slight technical point, the script makes absolutely no assumptions. The programmer might but script just does what it is told.

As for your script:

Do not parse ls, for reasons found here

I fail to see where you test for the start.sh file??
Or is the issue you do not know how to test if a file exists? If not, I suggest you have a look at man test

TRUNoise 04-05-2014 05:24 AM

Quote:

Originally Posted by grail (Post 5147013)
Do not parse ls, for reasons found here

"If it ain't broke, don't fix it."

Quote:

Originally Posted by grail (Post 5147013)
I fail to see where you test for the start.sh file??
Or is the issue you do not know how to test if a file exists? If not, I suggest you have a look at man test

Yes, it was to show you the code that the test needs to work with to better the responses. :P

When I try to set the variable manualy, it won't set correctly and it errors out the script.
Code:

root@ubuntu:/home# test=${test -e hub/start.sh}
-bash: ${test -e hub/start.sh}: bad substitution


grail 04-05-2014 05:33 AM

test is a command, why would you need {} or is this a typo and should have been ()?

As for:
Quote:

"If it ain't broke, don't fix it."
Well it is broke if I try to test on my computer as the file / directory names start in the 8th column and this assumes no spaces, but I guess this script never has to work on another system so you should be fine.

TRUNoise 04-05-2014 05:49 AM

Quote:

Originally Posted by grail (Post 5147026)
As for:

Well it is broke if I try to test on my computer as the file / directory names start in the 8th column and this assumes no spaces, but I guess this script never has to work on another system so you should be fine.

The script works fine across 3 of my systems, don't understand why you say it's broken. Must be different OS releases/versions/etc

Code:

root@ubuntu:/home/mc# ./start

[Detecting servers in .]
[cloud - Found]
[games - Found]
[hub - Found]

[Starting detected servers]
[cloud - Starting]
[cloud - Directory changed]
[cloud - Executing start.sh]
[games - Starting]
[games - Directory changed]
[games - Executing start.sh]
[hub - Starting]
[hub - Directory changed]
[hub - Executing start.sh]

Online screens:
There are screens on:
        10355.hub      (04/05/2014 10:39:39 AM)        (Detached)
        10350.games    (04/05/2014 10:39:39 AM)        (Detached)
        10346.cloud    (04/05/2014 10:39:39 AM)        (Detached)
3 Sockets in /var/run/screen/S-root.

root@ubuntu:/home/mc#

Quote:

Originally Posted by grail (Post 5147026)
test is a command, why would you need {} or is this a typo and should have been ()?

It's in brackets since when the script comes to the point of where it needs to find the servers that need to be executed, it has to find if they have a start script inside of their folder. If they do, add them to the array of servers to start ($servers.)

In other words, when the script lists all the directors in the current dir, check to make sure they have a start file in them before telling itself to later start a script in a folder which doesn't exist. The output of the command test would determin wether it would be included or not in the array.

grail 04-05-2014 06:03 AM

Well this works for me:
Code:

tmp=( */start.sh )
servers=("${tmp[@]%/*}")

for i in "${servers[@]}"
do
    echo $i
done


TRUNoise 04-05-2014 06:13 AM

Quote:

Originally Posted by grail (Post 5147035)
Well this works for me:
Code:

tmp=( */start.sh )
servers=("${tmp[@]%/*}")

for i in "${servers[@]}"
do
    echo $i
done


This works perfect and is a lot better than what I was using before; thanks for the help.


All times are GMT -5. The time now is 11:06 AM.