想象一下,您正准备进行深入的技术面试,并要求您评估您在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 命令(在每几百个主机名中都有类似的东西,似乎从列表中散落出来)。当然他或她问:为什么这样做?和你怎么能解决它?
然后评估您能够正确回答这些问题的人的专业水平。
答案 0 :(得分:1)
第一个是新手 中间(见下文)级别。应该在Bash的前1000行中遇到unset
,echo
,read
和基本变量使用,处理典型的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(subshell)位于管道的右侧(从当前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 / subshell(从管道读取)和ssh
共享相同的输入流,ssh
正在“窃取”来自管道的大部分输入,只留下偶尔的行read
命令。
这不是一个人为的问题。我实际上在工作中遇到过这个问题而且必须弄明白。我从经验中知道,理解第二个例子至少比第一个例子高出一两个等级。我也知道,根据多年的经验,我采访过的候选人(系统管理员和编程职位)中只有不到10%可以立即得到第一个问题。
我从未在现场采访中使用过第二个问题而且我不鼓励这样做。