3

I am not experienced in the Unix environment and have to adjust a script. I guess this is basic knowledge but I could not find a simple solution by googling it.

The script gets all webappsrv in a directory to restart them:

TMPLIST=`cd $MYWEBAPPSRV_DIR; /bin/echo *`

So this returns a list like this:

myAppSrv_1
myAppSrv_11
myAppSrv_12
myAppSrv_2
myAppSrv_3
...
myApSrv_9
somescript
somemorescriptfiles

How do I exclude the scriptfiles and only select the wanted directories? And how can I change the order in a simple way, because the servers need to be restarted by numeric number order (1, 2, 3, ..., 11, 12)? I can not rename the directories. I know it would be possible to breakdown the directories in text and numeric parts and then reorder by the numeric part, but is there a simpler option, like a special sort parameter?

3

Zsh is available on most distributions but often not part of the default installation. If installing it is not a problem, use it, as its glob qualifier feature solves your problem very easily:

#!/bin/zsh
cd $MYWEBAPPSRV_DIR
TMPLIST=(*(/n))
for app in $TMPLIST; do … done

The glob * lists all the files (except dot files), then glob qualifier / selects only the ones that are directories, and n causes numerical sorting for sequences of digits instead of the default lexicographic order. If you don't want to change to the directory, but you want to exclude the directory part from the matches, then use a history expansion modifier to keep only the base name part:

#!/bin/zsh
TMPLIST=($MYWEBAPPSRV_DIR/*(/n:t))
for app in $TMPLIST; do … done

If installing zsh is not practical, and you're running a system with GNU coreutils (e.g. non-embedded Linux, Cygwin) and the file names don't contain special characters (whitespace or wildcards) then you can use ls -v to sort file names with numerical order for sequences of digits, and -F to show file types combined with a text filter to select only directories.

TMPLIST=$(ls -Fv $MYWEBAPPSRV_DIR | sed -n 's!/$!!p')
for app in $TMPLIST; do … done
2

change it like this.. and give a try

TMPLIST=`cd $MYWEBAPPSRV_DIR; ls -l | awk '/myApp/{print $NF}' | sort -t_ -n -k2`

TMPLIST=`cd $MYWEBAPPSRV_DIR; ls -1 | awk '/myApp/' | sort -t_ -n -k2`
2
for (( n = 1; n < 12; ++n )); do
    for appsrv_dir in "$MYWEBAPPSRV_DIR"/*_"$n"; do
        if [[ -d "$appsrv_dir" ]]; then
             ( cd "$appsrv_dir" && somecommand )
        fi
    done
done

This iterates through the numbers 1 to 12 and matches anything in the $MYWEBAPPSRV_DIR directory that has this number at the end of its name (with an underscore before it). If it's a directory, do whatever you need to do with it. This syntax requires either bash or ksh.

"12" should obviously be the highest numerical suffix of any directory under $MYWEBAPPSRV_DIR.

Another way of doing it, with explicit sorting of the directory names: First, make the list of directories:

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done

This goes through everything in the directory $MYWEBAPPSRV_DIR that has a filename ending with _ followed by either one or two digits, and sends those filenames to standard output if they are actually names of directories.

Then sort these names based on the number after _:

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done | sort -t '_' -k2,2n

Assuming there's only one underscore in the name, this will sort the names in ascending numerical order based on the number in the suffix. The sort utility reads from standard input and writes the sorted list of directories to standard output.

Then do whatever it is you need to do with these directories:

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done | sort -t '_' -k2,2n |
while read appsrv_subdir; do
    ( cd "$MYWEBAPPSRV_DIR/$appsrv_subdir" && somecommand )
done
1

If you don't need to exclude any of the directories you can also do:

ls -d */ | sort -t_ -n -k2
1

To sort entries by proper numerical order (e.g 1, 2, 3, [...], 9, 10, 11, 12) instead of character sorting (e.g. 1, 10, 11, 12, 2, 3, [...], 9) you can use the ls command with option -v, and print one per line with option -1.

Change your command to TMPLIST="$(ls -v1 $MYWEBAPPSRV_DIR)" to create a list with all the files in the correct order.

I'm not completely sure exactly what you mean when you say you only want a directory, not a file. If I've misunderstood, please clarify. Here's a script which, given a path, will execute some code if it is a file or different code if it is a directory. Store the path to be checked in a variable named $test for this to work.

if [ "$(ls -ld $test | grep '^d')" != "" ]
then echo "Directory code here"
else echo "File code here"
fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.