免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: woodie
打印 上一主题 下一主题

[shell问答录]:命令、进程、子shell... [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
11 [报告]
发表于 2006-04-20 19:38 |只看该作者

To waker兄。

您的说法我部分同意,另外的部分则不能苟同。^_^
* shell脚本可以不在首行指定解释器,缺省的解释器/bin/sh会被用来解释、执行它。这一点你说的是对的,又是我孤陋寡闻了,受教。

* |不是重定向的操作符,这点也同意,我说错了。

至于赋值操作能不能算作命令,我的理解和你不同。
bash man page没有明确的说法,那让我们看看ksh的。下面摘自是Korn shell 93的man page:
...
Commands.
    A simple-command  is a list of variable assignments (see VariableAssignments  below) or a sequence of blank  separated words which may be preceded by a list of variable assignments (see Environment  below). The first word specifies the name of the command to be executed. Except as specified below, the remaining words are passed as arguments to the invoked command. ...


第一句就明确指出赋值的列表是simple-command的一种。
再看另一段(抱歉,做这样大段的引述):
...
A command  is either a simple-command or one of the following. Unless otherwise stated, the value returned by a command is that of the last simple-command executed in the command.

for vname  [  in word  . . .  ] ;do list  ;done
    Each time a for command is executed, vname  is set to the next word  taken from the in word  list. If in word  . . . is omitted, then the for command executes the do list  once for each positional parameter that is set starting from 1 (see ParameterExpansion below). Execution ends when there are no more words in the list.
for (( [ expr1  ] ; [ expr2  ] ; [ expr3  ] )) ;do list  ;done
    The arithmetic expression expr1 is evaluated first (see ArithmeticEvaluation below). The arithmetic expression expr2 is repeatedly evaluated until it evaluates to zero and when non-zero, list is executed and the arithmetic expression expr3 evaluated. If any expression is omitted, then it behaves as if it evaluated to 1.
select vname  [  in word  . . .  ] ;do list  ;done
    A select command prints on standard error (file descriptor 2) the set of words, each preceded by a number. If in word  . . . is omitted, then the positional parameters starting from 1 are used instead (see ParameterExpansion  below). The PS3 prompt is printed and a line is read from the standard input. If this line consists of the number of one of the listed words, then the value of the variable vname  is set to the word  corresponding to this number. If this line is empty, the selection list is printed again. Otherwise the value of the variable vname  is set to null. The contents of the line read from standard input is saved in the variable REPLY. The list  is executed for each selection until a break  or end-of-file  is encountered. If the REPLY variable is set to null  by the execution of list, then the selection list is printed before displaying the PS3 prompt for the next selection.
case word  in [  [ ( ]pattern  [  | pattern   ] . . . ) list  ;;  ] . . . esac
    A case command executes the list  associated with the first pattern  that matches word. The form of the patterns is the same as that used for file-name generation (see FileNameGeneration  below). The ;; operator causes execution of case to terminate. If ;& is used in place of ;; the next subsequent list, if any, is executed.
if list  ;then list  [  elif list  ;then list   ] . . . [  ;else list   ] ;fi
    The list  following if is executed and, if it returns a zero exit status, the list  following the first then is executed. Otherwise, the list  following elif is executed and, if its value is zero, the list  following the next then is executed. Failing each successive elif list , the else list  is executed. If the if list  has non-zero exit status and there is no else list, then the if command returns a zero exit status.
while list  ;do list  ;done
until list  ;do list  ;done
    A while command repeatedly executes the while list  and, if the exit status of the last command in the list is zero, executes the do list; otherwise the loop terminates. If no commands in the do list  are executed, then the while command returns a zero exit status; until may be used in place of while to negate the loop termination test.
((expression ))

    The expression  is evaluated using the rules for arithmetic evaluation described below. If the value of the arithmetic expression is non-zero, the exit status is 0, otherwise the exit status is 1.
(list )

    Execute list  in a separate environment. Note, that if two adjacent open parentheses are needed for nesting, a space must be inserted to avoid evaluation as an arithmetic command as described above.
{ list ;}

    list  is simply executed. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur at the beginning of a line or after a ; in order to be recognized.
[[ expression  ]]

    Evaluates expression  and returns a zero exit status when expression  is true. See ConditionalExpressions  below, for a description of expression.
function varname  { list  ;}
varname  () { list  ;}
    Define a function which is referenced by varname. A function whose varname  contains a . is called a discipline function and the portion of the varname  preceding the last . must refer to an existing variable. The body of the function is the list  of commands between { and }. A function defined with the function varname  syntax can also be used as an argument to the . special built-in command to get the equivalent behavior as if the varname () syntax were used to define it. (See Functions  below.)
time [  pipeline   ]

    If pipeline  is omitted the user and system time for the current shell and completed child processes is printed on standard error. Otherwise, pipeline  is executed and the elapsed time as well as the user and system time are printed on standard error.

The following reserved words are recognized as reserved only when they are the first word of a command and are not quoted:

    if then else elif fi case esac for while until do done { } function select time [[ ]] !
...

看到吗?连[[...]], ((...))也被承认是command(*not* just statement)。^_^

再看看linux下的ash的man page:
...
   Simple Commands
     If a simple command has been recognized, the shell performs the following actions:

           1.   Leading words of the form "name=value" are stripped off and assigned to the environment of the simple com-
                mand.  Redirection operators and their arguments (as described below) are stripped off and saved for pro-
                cessing.

           2.   The remaining words are expanded as described in the section called "Expansions", and the first remaining
                word is considered the command name and the command is located.  The remaining words are considered the
                arguments of the command. If no command name resulted, then the "name=value" variable assignments recog-
                nized in item 1 affect the current shell.

...

其中也承认只有赋值命令而没有命令名的“Simple Commands”。

呵呵,太长了!先贴这么多,其余的下一回贴再贴。^_^

[ 本帖最后由 woodie 于 2006-4-20 20:11 编辑 ]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
12 [报告]
发表于 2006-04-20 20:07 |只看该作者

To waker again.

上面是引述几段man page来支持我的观点。下面再提出两条理由:
1.赋值可以出现在一条命令所出现的所有位置(话说得太满了,如果有例外麻烦大家告诉我,我好赶快修改^_^)
a=1 > /dev/null
a=1 < /dev/stdin
a=1 &
if a=1; then
a=1
fi
while a=1; do
a=1
done
echo `a=1`
...
2.赋值“命令”(请先允许我这么称呼它吧,^_^)同样有返回值:
a=1
echo $?
0
执行正常,返回0。
false|a=1
echo $?
0
$?为pipe的最后一条命令的执行状态,而前一级的false应该是返回1。
false|a=1
set|grep PIPE
PIPESTATUS=([0]="1" [1]="0")
这样看的更清楚些。

所以,我认为赋值可以作为命令这一点应该没有问题,至于是否是内部命令则可以商榷。不过就其表现,把它归入builtin命令一类,也无太大不妥。这是我个人看法,大家可以争鸣。^_^也许我们可以开一个新的分类?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
13 [报告]
发表于 2006-04-20 20:18 |只看该作者

To waker once more.

不好意思,关于shell脚本,我仍然坚持我的观点:
我的看法:无论如何,脚本不作为单独的进程运行,单独运行的是脚本的解释器进程。

今天晚了,我们明天再做友好的争论吧!Anyhow, 谢谢您上面的回贴!^_^

论坛徽章:
0
14 [报告]
发表于 2006-04-20 20:31 |只看该作者
学习,可惜我初学,看不太懂

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
15 [报告]
发表于 2006-04-20 21:25 |只看该作者

回复 13楼 woodie 的帖子

不管怎么说,woodie的理解是对的。至于表达出来的用词是否准确,无大碍

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
16 [报告]
发表于 2006-04-20 21:46 |只看该作者
以下面代码为例
  1. r2007@www r2007 $ a=1
  2. r2007@www r2007 $ echo $a
  3. 1
  4. r2007@www r2007 $ a=2 :
  5. r2007@www r2007 $ echo $a
  6. 1
  7. r2007@www r2007 $ a=2 echo $a
  8. 1
  9. r2007@www r2007 $ echo $a
  10. 1
  11. r2007@www r2007 $ a=2 eval echo '$a'
  12. 2
  13. r2007@www r2007 $ echo $a
  14. 1
  15. r2007@www r2007 $ a=2 env
  16. a=2
  17. MANPATH=/usr/share/man:/usr/local/share/man
  18. ...
  19. ...
  20. ...
  21. _=/bin/env
复制代码

可以看出var=val,在不同的上下文中有不同的解释。如果单独出现则是普通的赋值语句,如果有其他命令,则是用来定义环境变量的,且不影响当前的环境。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
17 [报告]
发表于 2006-04-21 08:01 |只看该作者
赋值语句是一个简单命令,我理解错了

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
18 [报告]
发表于 2006-04-21 09:20 |只看该作者
关于进程,争论究竟是bash的进程还是foobar.script的进程,这本来就是没有意义的
想如果以CMD代表进程的话,你的说法是对的,但我想CMD代表进程是不严谨的,代表进程的只能是PID

找个极端的例子:zombie进程又是哪个CMD的呢?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
19 [报告]
发表于 2006-04-21 15:12 |只看该作者
To waker:

关于脚本,我想你的理解也有一定的道理,我也不能强求你认同我的观点,大家各自阐述自己的意见也不错啊。
我想再说两条理由,不一定站得住脚:

1.脚本无法自主执行,它从来都没有取得CPU时间片去执行哪怕是一句机器代码,它只是被动的为解释程序所解释执行。
2.ready, running, wait等等进程的状态也不好安在它身上。
3.脚本在实际应用中不能作为系统进程调度的一个基本单元,那么认为它可以作为进程又有何益处呢?
nice script-name?
killall script-name?

至于进程与command,那是两个不同的概念,进程应该属于操作系统的范畴,命令在这里主要是shell中的概念。二进制可执行文件是命令,shell builtin,alias,function,甚至脚本文件自己也可以当作命令。和你一样,我也不同意将两个概念划等号。^_^

还有你举的zombie,它只是一种特殊的进程,或者说是进程的一种特殊的状态。zombie之于进程,就如同死人之于活人。zombie已经死亡,但它死亡之前毕竟曾经是某个程序的运行实例,而那个程序可能恰恰就是一条external command。

我也同意你:争论这一点实际的意义并不大。^_^

不过同你的争论让我提高不少,谢谢你,也谢谢CU这个平台吧!^_^

论坛徽章:
0
20 [报告]
发表于 2006-04-22 03:21 |只看该作者
非常精彩的讨论,呵呵,第一次看到waker的错误,俺以前都把waker当真理的,HOHO

但是,我还有个疑问:eval属于build in还是?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP