了解Shell Scripting中的mkfifo PIPE用法

时间:2016-07-31 12:23:16

标签: shell ksh mkfifo

我遇到了下面的代码,它使用了多个进程的PIPE 我是shell脚本的新手,因此不完全理解以下代码的含义/意图:

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.....

问题:

  1. 第3行:检查脚本是否少于1个参数,然后打印用法?

  2. 第8行:是否检查了父进程,子进程是在即将推出的代码行中启动的,不会进入此if块?

  3. 第19行:此行似乎启动了一个新的子进程。子进程是否与父进程脚本$0相同?语句SELF_LOGGING=1是否设置了一个新的(环境?)变量,以便在子进程中跳过第8行?为什么在未定义此变量的情况下,脚本(父进程)的初始执行行为是正确的,我的意思是如果未定义变量,那么if如何计算为true。或者是我完全错了。

  4. 第28行:为什么在PIPE上完成了rm

  5. 第39行:这部分是子进程还是父进程?输入文件似乎位于$1

  6. 对此有何回应表示感谢。感谢。

1 个答案:

答案 0 :(得分:2)

  

第3行:检查脚本的参数是否小于1   打印用法。

是$#是脚本的总参数,不包括脚本

  

2)第8行:这是对父进程的检查,子进程是否已启动   在即将出现的代码行中,不会输入这个if块吗?

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

好吧,SELF_LOGGING可以是环境变量(因为它全是大写)或父进程中设置的变量。在你的情况下,后者,是的,但不要在脚本中使用所有大写变量,因为它们通常是为系统保留的。它也应该是

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

第19行:这一行似乎启动了一个新的子进程。是孩子吗   进程与父进程脚本$ 0相同?

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

它自己调用的脚本,所以你是对的,$0是正在执行的命令的名称,在你的情况下是脚本本身。

  

语句SELF_LOGGING = 1,是否设置了新的(环境?)   变量

父级中的任何变量对子级都是可见的。但严格来说,它不是一个环境变量。

  

第28行:为什么在PIPE上完成rm。   正如评论明确指出Unlink $PIPE because the parent process no longer needs it

rm $PIPE

非常好,因为$PIPE的扩展值确实是一个文件。阅读mkfifo [ manpage ]

  

5)第39行:这部分是子进程还是父进程?

考虑递归。