当前位置:K88软件开发文章中心网站服务器框架Shell → 文章内容

Shell 进程操作

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-23 14:39:38

进程的输入关联到管道的输入文件描述符,这个关联过程通过输入输出重定向函数 dup (或者 fcntl )来实现。范例:有名管道(named pipe)有名管道实际上是一个文件(无名管道也像一个文件,虽然关系到两个文件描述符,不过只能一边读另外一边写),不过这个文件比较特别,操作时要满足先进先出,而且,如果试图读一个没有内容的有名管道,那么就会被阻塞,同样地,如果试图往一个有名管道里写东西,而当前没有程序试图读它,也会被阻塞。下面看看效果。$ mkfifo fifo_test #通过mkfifo命令创建一个有名管道$ echo "fewfefe" > fifo_test#试图往fifo_test文件中写入内容,但是被阻塞,要另开一个终端继续下面的操作$ cat fifo_test #另开一个终端,记得,另开一个。试图读出fifo_test的内容fewfefe这里的 echo 和 cat 是两个不同的程序,在这种情况下,通过 echo 和 cat 启动的两个进程之间并没有父子关系。不过它们依然可以通过有名管道通信。这样一种通信方式非常适合某些特定情况:例如有这样一个架构,这个架构由两个应用程序构成,其中一个通过循环不断读取 fifo_test 中的内容,以便判断,它下一步要做什么。如果这个管道没有内容,那么它就会被阻塞在那里,而不会因死循环而耗费资源,另外一个则作为一个控制程序不断地往 fifo_test 中写入一些控制信息,以便告诉之前的那个程序该做什么。下面写一个非常简单的例子。可以设计一些控制码,然后控制程序不断地往 fifo_test 里头写入,然后应用程序根据这些控制码完成不同的动作。当然,也可以往 fifo_test 传入除控制码外的其他数据。应用程序的代码 $ cat app.sh #!/bin/bash FIFO=fifo_test while :; do CI=`cat $FIFO` #CI --> Control Info case $CI in 0) echo "The CONTROL number is ZERO, do something ..." ;; 1) echo "The CONTROL number is ONE, do something ..." ;; *) echo "The CONTROL number not recognized, do something else..." ;; esac done控制程序的代码 $ cat control.sh #!/bin/bash FIFO=fifo_test CI=$1 [ -z "$CI" ] && echo "the control info should not be empty" && exit echo $CI > $FIFO一个程序通过管道控制另外一个程序的工作 $ chmod +x app.sh control.sh #修改这两个程序的可执行权限,以便用户可以执行它们 $ ./app.sh #在一个终端启动这个应用程序,在通过./control.sh发送控制码以后查看输出 The CONTROL number is ONE, do something ... #发送1以后 The CONTROL number is ZERO, do something ... #发送0以后 The CONTROL number not recognized, do something else... #发送一个未知的控制码以后 $ ./control.sh 1 #在另外一个终端,发送控制信息,控制应用程序的工作 $ ./control.sh 0 $ ./control.sh 4343这样一种应用架构非常适合本地的多程序任务设计,如果结合 web cgi,那么也将适合远程控制的要求。引入 web cgi 的唯一改变是,要把控制程序 ./control.sh 放到 web 的 cgi 目录下,并对它作一些修改,以使它符合 CGI 的规范,这些规范包括文档输出格式的表示(在文件开头需要输出 content-tpye: text/html 以及一个空白行)和输入参数的获取 (web 输入参数都存放在 QUERY_STRING 环境变量里头)。因此一个非常简单的 CGI 控制程序可以写成这样:#!/bin/bashFIFO=./fifo_testCI=$QUERY_STRING[ -z "$CI" ] && echo "the control info should not be empty" && exitecho -e "content-type: text/html\n\n"echo $CI > $FIFO在实际使用时,请确保 control.sh 能够访问到 fifo_test 管道,并且有写权限,以便通过浏览器控制 app.sh :http://ipaddress\_or\_dns/cgi-bin/control.sh?0问号 ? 后面的内容即 QUERY_STRING,类似之前的 $1 。这样一种应用对于远程控制,特别是嵌入式系统的远程控制很有实际意义。在去年的暑期课程上,我们就通过这样一种方式来实现马达的远程控制。首先,实现了一个简单的应用程序以便控制马达的转动,包括转速,方向等的控制。为了实现远程控制,我们设计了一些控制码,以便控制马达转动相关的不同属性。在 C 语言中,如果要使用有名管道,和 Shell 类似,只不过在读写数据时用 read,write 调用,在创建 fifo 时用 mkfifo 函数调用。范例:信号(Signal)信号是软件中断,Linux 用户可以通过 kill 命令给某个进程发送一个特定的信号,也可以通过键盘发送一些信号,比如 CTRL+C 可能触发 SGIINT 信号,而 CTRL+\ 可能触发 SGIQUIT 信号等,除此之外,内核在某些情况下也会给进程发送信号,比如在访问内存越界时产生 SGISEGV 信号,当然,进程本身也可以通过 kill,raise 等函数给自己发送信号。对于 Linux 下支持的信号类型,大家可以通过 man 7 signal 或者 kill -l 查看到相关列表和说明。对于有些信号,进程会有默认的响应动作,而有些信号,进程可能直接会忽略,当然,用户还可以对某些信号设定专门的处理函数。在 Shell 中,可以通过 trap 命令(Shell 内置命令)来设定响应某个信号的动作(某个命令或者定义的某个函数),而在 C 语言中可以通过 signal 调用注册某个信号的处理函数。这里仅仅演示 trap 命令的用法。$ function signal_handler { echo "hello, world."; } #定义signal_handler函数$ trap signal_handler SIGINT #执行该命令设定:收到SIGINT信号时打印hello, world$ hello, world #按下CTRL+C,可以看到屏幕上输出了hello, world字符串类似地,如果设定信号 0 的响应动作,那么就可以用 trap 来模拟 C 语言程序中的 atexit 程序终止函数的登记,即通过 trap signal_handler SIGQUIT 设定的 signal_handler 函数将在程序退出时执行。信号 0 是一个特别的信号,在 POSIX.1 中把信号编号 0 定义为空信号,这常被用来确定一个特定进程是否仍旧存在。当一个程序退出时会触发该信号。$ cat sigexit.sh#!/bin/bashfunction signal_handler { echo "hello, world"}trap signal_handler 0$ chmod +x sigexit.sh$ ./sigexit.sh #实际Shell编程会用该方式在程序退出时来做一些清理临时文件的收尾工作h

上一页  [1] [2] [3] [4]  下一页


Shell 进程操作