📄 00000004.htm
字号:
<BR>------------------------------ <BR> <BR>Subject: How can a process detect if it's running in the background? <BR>Date: Thu Mar 18 17:16:55 EST 1993 <BR> <BR>3.7) 一个process 要怎样侦测出自己是否在背景状态执行? <BR> <BR> 首先,您是否想知道您自己是在背景状态下执行,或者在交谈状态下执行?如果 <BR> 您只是想藉此决定是否该在终端机上印出提示符号之类的讯息,那麽更合适的做 <BR> 法应该是检查您的标准输入是否为终端机: <BR> <BR> sh: if [ -t 0 ]; then ... fi <BR> C: if(isatty(0)) { ... } <BR> <BR> 一般来说,您无法得知自己是否在背景状态下执行。问题的根本在於不同的shell <BR> <BR> 与不同的 UNIX 版本对於「前景」与「背景」的定义可能有所不同。而且在最 <BR> 常见的系统上,前景与背景都有较好的定义,程式甚至可以在背景与前景之间任 <BR> 意切换! <BR> <BR> 在没有 job control 的UNIX系统上,若要把 process 放入背景状态通常是把 <BR> SIGINT 与 SIGQUIT 忽略掉,并且把标准输入转为"/dev/null",这是由shell处 <BR> 理的。 <BR> <BR> 在具有 job control 功能的 UNIX 系统,若shell支援 job control功能,那麽 <BR> shell只要把 process group ID 设成跟 terminal 所属的 PGID 不同即可把 <BR> process 切换至背景状态;如果要把 process 切回前景状态,只要把此 process <BR> 的 PGID 设成跟目前 terminal 所属的 PGID 即可。如果 shell 不支援 job <BR> control 功能,则不管UNIX 系统是否支援 job control 的功能,shell 对 <BR> process 的处理动作都是一样的(也就是忽略SIGINT 与 SIGQUIT,并且把标准 <BR> 输入转为"/dev/null")。 <BR> <BR>------------------------------ <BR> <BR>Subject: Why doesn't redirecting a loop work as intended? (Bourne shell) <BR>Date: Thu Mar 18 17:16:55 EST 1993 <BR> <BR>3.8) 为什麽在 Bourne shell 当中,对回圈的输出入转向无法达到预期的效果? <BR> <BR> 举个例子来说好了: <BR> <BR> foo=bar <BR> while read line <BR> do <BR> # do something with $line <BR> foo=bletch <BR> done < /etc/passwd <BR> <BR> echo "foo is now: $foo" <BR> <BR> 尽管 "foo=bletch" 已经设定了 foo 的值,然而在多种系统的 Bourne shell <BR> 上执行此 script 的时候仍会印出 "foo is now: bar"。为什麽呢?因为一些 <BR> 历史因素,在 Bourne shell 当中,一个控制结构(如一个回圈,或者一个 <BR> "if" 叙述)的重导向会造出一个新的 subshell,所以啦,在此 subshell 内 <BR> 所设定的变数当然不会影响目前 shell 的变数。 <BR> <BR> POSIX 1003.2 Shell and Tools Interface 的标准委员会已防止上述的问题, <BR> 也就是上述的例子在遵循P1003.2 标准的Bourne shells当中会印出 <BR> "foo is now: bletch"。 <BR> <BR> 在一些较古老的 (以及遵循 P1003.2 标准的) Bourne shell 当中,您可以使 <BR> 用以下技巧来避免重转向的问题: <BR> <BR> foo=bar <BR> # make file descriptor 9 a duplicate of file descriptor 0 <BR> # stdin); <BR> # then connect stdin to /etc/passwd; the original stdin is now <BR> # `remembered' in file descriptor 9; see dup(2) and sh(1) <BR> exec 9<&0 < /etc/passwd <BR> <BR> while read line <BR> do <BR> # do something with $line <BR> foo=bletch <BR> done <BR> <BR> # make stdin a duplicate of file descriptor 9, i.e. reconnect <BR> # it to the original stdin; then close file descriptor 9 <BR> exec 0<&9 9<&- <BR> echo "foo is now: $foo" <BR> <BR> 这样子不管在哪种 Bourne shell 应该都会印出 "foo is now: bletch"。 <BR> 接下来,看看以下这个例子: <BR> <BR> foo=bar <BR> <BR> echo bletch | read foo <BR> <BR> echo "foo is now: $foo" <BR> <BR> 这个例子在许多 Bourne shell 内都会印出 "foo is now: bar",有些则会 <BR> 印出 "foo is now: bletch"。为什麽呢?一般说来,一个 pipeline 里面 <BR> 的每一个部份都是在一个 subshell 中执行。但是有些系统的里 pipeline <BR> 的最後一个如果是如 "read" 这类的内建指令,并不会另外造出一个 <BR> subshell。 <BR> <BR> POSIX 1003.2 对这两种作法并没有硬性规定要用哪一种。所以一个 portable <BR> 的 shell script 不应该依赖这两种作法其中的一种。 <BR> <BR>------------------------------ <BR> <BR>Subject: How do I run ... interactive programs from a shell script ... ? <BR>Date: Thu Mar 18 17:16:55 EST 1993 <BR> <BR>3.9) 我要怎麽在一个 shell script 中或在背景执行 'ftp'、'telnet'、'tip' 等 <BR> interactive 的程式呢? <BR> <BR> 这些程式需要一个 terminal interface。这是 shell 所无法提供的。所以这些 <BR> 无法在 shell script 里自动执行这些程式。 <BR> <BR> 有一个就做 'expect' 的程式,可以用来做这件事,因为它提供了 <BR> programmable terminal interface。底下的例子是用 'expect' 来帮你 <BR>login: <BR> <BR> # username is passed as 1st arg, password as 2nd <BR> set password [index $argv 2] <BR> spawn passwd [index $argv 1] <BR> expect "*password:" <BR> send "$password\r" <BR> expect "*password:" <BR> send "$password\r" <BR> expect eof <BR> <BR> expect 为 telnet, rlogin,debugger 和一些没有内建 command language 的 <BR> 程式提供了一个近乎自动化的方法。Expect 里面的有一用以在玩 rogue <BR> (一个 Unix 中的古老游戏)时取得较佳初始情况,然後将控制权还回给使用者 <BR> 的例子。用这个 script 你就能得到『成功的一半』。 <BR> <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -