这个面试项目建议的专业水平是多少?未设定的foo;回音棒|读foo; echo $ foo

时间:2012-03-27 04:31:31

标签: bash ksh zsh sh

想象一下,您正准备进行深入的技术面试,并要求您评估您在shell脚本编写方面的专业知识(假设在1到10的范围内)。然后查看以下shell命令行示例并回答问题:这是做什么的?为什么?

unset foo; echo bar | read foo; echo "$foo"

您需要达到什么级别的专业知识才能正确回答这个问题一般情况(不仅仅是针对一个或另一个特定的shell版本)?

现在想象你给出了以下例子:

cat "$SOMELIST_OF_HOSTS" | while read host; do ssh $host "$some_cmd"; done

...并且采访者解释说这个命令“不起作用”,它似乎只在(大)文件中列出的一些主机上执行 ssh 命令(在每几百个主机名中都有类似的东西,似乎从列表中散落出来)。当然他或她问:为什么这样做?你怎么能解决它?

然后评估您能够正确回答这些问题的人的专业水平。

2 个答案:

答案 0 :(得分:1)

第一个是新手 中间(见下文)级别。应该在Bash的前1000行中遇到unsetechoread和基本变量使用,处理典型的shell代码。

第二个是中级IMO;在我发现像ssh吞噬标准输入之类的无害命令之前,我一直在使用Bash几年。这是ssh命令的一个很好的测试,但是因为它有点异常,所以最好只用cat来测试候选人是否理解问题的基础。

但正如我认为@ IgnacioVazquez-Abrams指出的那样,你只能根据两个狭隘的问题评价很多 - 作为others have pointed out,为什么不给他们一个实际问题呢?你会更好地了解他们实际完成工作的能力。

编辑:正如@ IgnacioVazquez-Abrams也指出的那样,这些基本上都是测试同样的事情。所以我给两个中间人评价。

答案 1 :(得分:0)

请注意,第一个示例取决于shell。管道是IPC(进程间通信)操作员,shell可以通过在管道的任一侧创建子shell来实现它。 (从技术上讲,我认为一些shell甚至可以在单独的子流程中评估双方。)

read命令是内置的(必须是固有的)。因此,在诸如bash的shell和经典的Bourne shell派生类中,suprocess(subshel​​l)位于管道的右侧(从当前shell读取),并且该过程在其read之后结束(在这个例子中的分号)。 Korn shell(至少可以追溯到'93)和zsh将它们的子shell放在管道的另一侧,并将数据读取到当前进程中。

这是面试问题的重点。

我在这里提出的问题是寻找一些共识或指标来评估这个问题的高度。这不是琐事的问题,因为它确实会影响真实世界的脚本和shell脚本的可移植性,它依赖于对底层UNIX和shell语义(IPC,管道和子进程/子shell)的基本理解。

第二个例子类似但更微妙。我将指出以下更改“有效”(ssh将在文件中的每个主机上执行):

cat $SOME_FILE | while read host; do ssh "$host" "$some_cmd" < /dev/null; done

这里的问题是ssh命令缓冲输入,即使远程命令永远不会从 stdin 读取。因为shell / subshel​​l(从管道读取)和ssh共享相同的输入流,ssh正在“窃取”来自管道的大部分输入,只留下偶尔的行read命令。

这不是一个人为的问题。我实际上在工作中遇到过这个问题而且必须弄明白。我从经验中知道,理解第二个例子至少比第一个例子高出一两个等级。我也知道,根据多年的经验,我采访过的候选人(系统管理员和编程职位)中只有不到10%可以立即得到第一个问题。

我从未在现场采访中使用过第二个问题而且我不鼓励这样做。