0

I came across the code below, which uses PIPE with multiple processes.
I'm new to shell scripting, and therefore don't fully understand the meaning/intent of the following code:

1 #!/bin/ksh
2 
3 if [ $# -lt 1 ]; then
4     echo "Usage: $0 InputFile"
5     exit 1
6 fi
7 
8 if [ "$SELF_LOGGING" != "1" ]; then
9     # The parent process will enter this branch and set up logging
10
11    # Create a named piped for logging the child's output
12    PIPE=temporary.fifo
13    mkfifo $PIPE
14
15    date_string=`date +"%m_%d_%Y_%H_%M_%S"`
16    log_name="${date_string}_createzip.log"
17
18    # Launch the child process without redirected to the named pipe
19    SELF_LOGGING=1 ksh "$0" "$date_string" "$@" 2>&1 >$PIPE &
20
21    # Save PID of child process
22    PID=$!
23    
24    # Launch tee in a separate process
25    tee "$log_name" <$PIPE &
26
27    # Unlink $PIPE because the parent process no longer needs it
28    rm $PIPE
29
30    # Wait for child process running the rest of this script
31    wait $PID
32
33    # Return the error code from the child process
34    exit $?
35fi
36
37echo "Logging to file: $1_createzip.log"
38
39if [[ ! -r "$2" ||  ! -f "$2" ]]; then
40    echo "Error: cannot read input file. Exiting."
41    exit 1
42fi
43 ......MORE CODE.....

Questions:

  1. Line 3: checks if there is fewer than 1 argument to the script, then print the usage?

  2. Line 8: Is this check for parent process, the child process started in forthcoming lines of code, won't enter this if block ?

  3. Line 19: This line seems to launch a new child process. Is the child process same as parent process script $0? Is it that the statement SELF_LOGGING=1, sets a new (environment?) variable, so that Line 8 part is skipped in the child process? How come the initial execution of the script (parent process) behaves correctly where this variable is not defined, I mean if the variable is not defined then how come the if evaluates to true. Or is it that I've got this completely wrong.

  4. Line 28: why is rm done on PIPE.

  5. Line 39: Is this part for the child process or parent process? Input file seems to be at $1.

Would appreciate any response on the above. Thanks.

agc
  • 7,973
  • 2
  • 29
  • 50
Ankur
  • 11,239
  • 22
  • 63
  • 66

1 Answers1

2

Line 3: checks if the arguments to the script are less than 1, then print the usage.

yes $# is the total arguments to the script not including the script

2) Line 8: Is this check for parent process, the child process started in forthcoming lines of code, won't enter this if block ?

if [ "$SELF_LOGGING" != "1" ];

Well, SELF_LOGGING could either be an environment variable(coz it's all uppercase) or a variable set in the parent process. In your case latter, So yes, but don't use all uppercase variables in scripts as they are usually reserved for system. Also it should have been

[ "$self_logging" -ne "1" ] # if you're checking for integers.

Line 19: This line seems to launch a new child process. Is the child process same as parent process script $0?

In

 SELF_LOGGING=1 ksh "$0" "$date_string" "$@" 2>&1 >$PIPE &

the script it calling itself, so you're right and $0 is the name of command being executed, which in your case is the script itself.

Is it that the statement SELF_LOGGING=1, sets a new (environment?) variable

Any variable in the in the parent is visible to the child. But it is not an environment variable in strict sense.

Line 28: why is rm done on PIPE. As the comment clearly says Unlink $PIPE because the parent process no longer needs it And

rm $PIPE

is perfectly fine because expanded value of $PIPE is indeed a file. Read mkfifo [ manpage ].

5) Line 39: Is this part for the child process or parent process?

Think in terms of recursion.

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • Thanks sjsam. Yes, can't get my head (at the moment) around this parent/child work in the example. Will keep trying. – Ankur Jul 31 '16 at 14:35
  • 1
    By convention *all* environment variables are written in uppercase. The variable `SELF_LOGGING` *is* an environment variable in this case, as it is set in the invocation of the child process: `SELF_LOGGING=1 ksh "$0" ...` – Henk Langeveld Aug 03 '16 at 19:21