LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Shell script calling shell script - List of all (http://www.linuxquestions.org/questions/programming-9/shell-script-calling-shell-script-list-of-all-872445/)

nikunjbadjatya 04-01-2011 03:50 PM

Shell script calling shell script - List of all
 
Hi LQ members,

I am working on a build-test system of a set of codes.
The system ( large enough ) is such that one shell script does some work and calls another shell script.. this inturn calls a third shell script and so on..

My question is : How to get the list of all such shell scripts according to the way they are called. ? More like a shell script flow tree.!! ?

Ex.
Code:

#./1.sh
  |
  `--> 2.sh
  |
  `--> 3.sh
        |
        `--> 4.sh
            |
            `--> 5.sh ....
                  .
                  .
                  .
etc.



Thanks,

Nikunj
Bangalore, India

Cpare 04-01-2011 04:01 PM

Not sure how many shell scripts you’re talking about, but we do something similar where I work (shell scripts call each other like functions), to keep troubleshooting easier we add a "Echo Starting $0" to the start of every .sh, and an "Echo Exiting $0" at the end, this way we can quickly tell what is blowing up, and where we need to troubleshoot. There has been talk about having the ability add a 'debug' flag to each to enable/disable the output, but it's pretty low on the priority list.

Nominal Animal 04-01-2011 06:23 PM

Quote:

Originally Posted by nikunjbadjatya (Post 4311030)
My question is : How to get the list of all such shell scripts according to the way they are called. ? More like a shell script flow tree.!! ?

I guess the simplest option would be the command
Code:

ps axfu
but it outputs all processes as a process tree.

The do-it-yourself way would be to find out the PID of the original parent, e.g. via the process name, the use ps to list all its children recursively. Here is an example bash script; give it the name(s) of the parent script(s) as parameters:
Code:

#!/bin/bash
if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    echo "" >&2
    echo "Usage: $0 [ -h | --help ]" >&2
    echo "      $0 name-of-command-or-script .." >&2
    echo "" >&2
    exit 1
fi
pids=()
while [ $# -gt 0 ]; do
    if ! pids=(${pids[@]} `ps -C "$1" --no-headers -o pid`) ; then
        echo "$1: No such process." >&2
    fi
    shift 1
done
if [ ${#pids[@]} -lt 1 ]; then
    echo "No parent processes." >&2
    exit 1
fi

Processes () {
    local indent="$1"
    local separator="$2"
    shift 2

    while [ $# -gt 0 ]; do
        echo -n "$indent"
        ps --pid $1 --no-headers -o args
        Processes "$indent$separator" "$separator" `ps --ppid $1 --no-headers -o pid`
        shift 1
    done
}

Processes "" "    " ${pids[@]}

The actual work is done in the recursive Processes function. It uses ps --pid parent --no-headers -o pid to list the pids of all child processes (processes started by parent). You should be able to modify the output to suit your liking. Also, you can output various other information; the current one just prints the command line used to run the process. See man ps and STANDARD FORMAT SPECIFIERS section for the fields you can output via ps.

Hope this helps.

nikunjbadjatya 04-09-2011 03:30 AM

Hi Nominal,
Thanks a lot for your script.
I created few sample scripts ( 1.sh --> 2.sh --> 3.sh --> 4.sh, 5.sh ) and put echo statements in them. Script 5.sh has a while infinite loop.

I tried running it as
Code:

[Terminal 1]
#./1.sh
...
...

[Terminal 2]
#./script_tree.sh 1.sh
1.sh: No such process.
No parent processes.

Where script_tree.sh is your script.!!

I checked with below command and found nothing.
Code:

#ps -ef | grep 1.sh
Any idea what is wrong here.?? I should be getting the tree.?

Thanks,
Nikunj

konsolebox 04-09-2011 05:14 AM

hey, this software might just be exactly what you need ;)

http://loader.sourceforge.net/

theNbomr 04-09-2011 12:14 PM

Please be aware that there are some different flavors of 'ps', each with their own options and output formatting. If you are running on a non-Linux host, this will probably have an impact, especially on something like Solaris. This particularly sucks, since there really is no standard API for acquiring information about the process table, and parsing the output of ps seems to be the standard method with the likes of the OP's problem. Nominal's use of very specific format specification is probably the best defense against the schizophrenic behavior of ps.

--- rod.

nikunjbadjatya 04-13-2011 10:09 AM

Thanks for the useful information folks. !!

Nominal Animal 04-13-2011 07:27 PM

Quote:

Originally Posted by nikunjbadjatya (Post 4318836)
I tried running it as
Code:

[Terminal 1]
#./1.sh
...
...

[Terminal 2]
#./script_tree.sh 1.sh
1.sh: No such process.
No parent processes.


I cannot reproduce that on my machine (Ubuntu 10.10) using bash, dash or sh. Obviously, the script cannot find any running processes with 1.sh as the command, i.e. ps -C 1.sh returns no processes.

Also, if
Code:

ps x -o pid,args | grep -e 1.sh
returns no matches, then 1.sh has already exited and reaped.

If a process is no longer seen by ps, it is impossible to find which processes it started. (You can, however, use the Linux audit service to track program executions (exec system calls) and process creation (fork system calls), and afterwards look at the log to find out which processes spawned which.

My script only takes a snapshot of the current process relationships.

Quote:

Originally Posted by nikunjbadjatya (Post 4318836)
I checked with below command and found nothing.
Code:

#ps -ef | grep 1.sh

Then 1.sh is no longer running, I'd say.

I tried with these four scripts, 1.sh to 4.sh:
Code:

#!/bin/sh
echo "1.sh ($$): Start"
./2.sh &
sleep 1
./3.sh &
sleep 1
./4.sh &
sleep 1
wait
echo "1.sh ($$): Exit"

Code:

#!/bin/sh
echo "2.sh ($$): Start"
./3.sh &
sleep 1
./4.sh &
sleep 1
wait
echo "2.sh ($$): Exit"

Code:

#!/bin/sh
echo "3.sh ($$): Start"
./4.sh &
sleep 1
wait
echo "3.sh ($$): Exit"

Code:

#!/bin/sh
echo "4.sh ($$): Start"
sleep 1
echo "4.sh ($$): Exit"

I started the above ./1.sh in one terminal, and in about a second, ran ./script_tree.sh 1.sh in another terminal. This is the result I get:
Code:

/bin/bash ./1.sh
    /bin/bash ./2.sh
        /bin/bash ./4.sh
            sleep 1
        sleep 1
    /bin/bash ./3.sh
        /bin/bash ./4.sh
            sleep 1
        sleep 1
    sleep 1

If you wait for too long, 1.sh exits, and you'll get the "1.sh: No such process.", "No parent processes." error message.


All times are GMT -5. The time now is 10:32 AM.