2013-11-25 74 views
0

我有一个Ubuntu机设置来砸默认的shell和$ PATH两种方式二进制:为什么bash的行为不同,当它被称为sh?

$ which bash 
/bin/bash 
$ which sh 
/bin/sh 
$ ll /bin/sh 
lrwxrwxrwx 1 root root 4 Mar 6 2013 /bin/sh -> bash* 

但是,当我尝试调用使用the inline file descriptor(仅Bash可以处理,但没有一个脚本SH)两个调用不同的表现:

$ . ./inline-pipe 
reached 
$ bash ./inline-pipe 
reached 
$ sh ./inline-pipe 
./inline-pipe: line 6: syntax error near unexpected token `<' 
./inline-pipe: line 6: `done < <(echo "reached")' 

示例脚本我指的是看起来像

#!/bin/sh 
while read line; do 
if [[ "$line" == "reached" ]]; then echo "reached"; fi 
done < <(echo "reached") 

现实一个是一点点长:

#!/bin/sh 
declare -A elements 
while read line 
do 
    for ele in $(echo $line | grep -o "[a-z]*:[^ ]*") 
    do 
     id=$(echo $ele | cut -d ":" -f 1) 
     elements["$id"]=$(echo $ele | cut -d ":" -f 2) 
    done 
done < <(adb devices -l) 
echo ${elements[*]} 
+0

用shebang(#!/ ...)看到实际的脚本 - 特别是引导线会很有帮助。其次,你现在用哪个“$”提示符运行哪个shell? – Daniel

+0

SRY,我认为这很清楚。它运行在默认shell(按照我的第一句话)bash。也会上传脚本。 – fragmentedreality

+2

http://www.gnu.org/software/bash/manual/bashref.html#Bash-POSIX-Mode –

回答

3

bash被调用为sh时,它(主要)会将自己限制为POSIX标准中的特征。流程替换不是这些功能之一,因此是错误。

+0

是的,引用标准总是非常有力的论据来摧毁一些东西,这些标准更好。特别是对于由_committee_“发明”的标准。 – peterh

+1

@MaXX我不知道我理解你的观点。 – chepner

+0

请尝试解释哪些不够明确。 – peterh

-2

我相信sh在Ubuntu其实是dash比功能较少的bash较小。

+2

该OP显然已重置'/ bin/sh'再次指向'bash'。 – chepner

0

理论上来说,它是bash的一个功能:如果您调用为“sh”,则默认关闭其所有功能。而root shell默认是“/ bin/sh”。

其主要目标是安全性。次要的是在系统的某些shell之间产生某种程度的兼容性,因为它使得系统脚本能够以交替(更快更安全)的环境运行。

这是理论。

实际上这样做是因为开发团队中总是有人想要通过各种论证(安全性,简单性,安全性和稳定性)来减少和消除所有事情 - 但这些论点总是朝着删除,删除,销毁)。

这是因为debian中的bash没有网络套接字,这是因为debian在20年内无法正常整合最佳压缩器(bz2,xz) - 这是因为根shell是默认如此简单,就像八十年代的PDP11一样。

+1

恐怕您错过了标准的主要用途,特别是Unix/POSIX。在这种情况下,**允许**开发人员创建可在兼容平台之间移植的脚本。没有隐藏的议程。 – jlliagre

+0

我希望你有权利,但我已经这么多了。特别是从bash中删除网络,gzip debs使我的观点如现在这样。 – peterh

+0

当前和以前的Debian版本都在bash中启用了网络支持,并且在POSIX模式下运行bash时此功能未被禁用。我没有看到gzipped debs如何与bash/sh行为或POSIX标准相关。 – jlliagre