bash [[: not found, '[[' is a keyword not a builtin

 
 

这个问题是源于在在android 4.0 的 CTS测试中需要编译签名版本中遇到。在使用脚本vendor\Modul\security\platform 下的脚本gen_private_keys调用development\tools\make_key 来生成公钥和私钥过程中报的错。

Android 签名版本生成参考

gen_privae_keys脚本内容如下:

#sign key info
#C   --->  Country Name (2 letter code)
#ST  --->  State or Province Name (full name)
#L   --->  Locality Name (eg, city)
#O   --->  Organization Name (eg, company)
#OU  --->  Organizational Unit Name (eg, section)
#CN  --->  Common Name (eg, your name or your server’s hostname)
#emailAddress --->  Contact email address
AUTH='/C=CN/ST=FuJian/L=XiaMen/O=npjocj/OU=npjocj/CN=npjocj/[email protected]'
sh ../../../../development/tools/make_key platform "$AUTH"
sh ../../../../development/tools/make_key media "$AUTH"
sh ../../../../development/tools/make_key shared "$AUTH"
sh ../../../../development/tools/make_key releasekey "$AUTH"

问题描述:

在linux中运行脚本时

./gen_private_keys

如图:


../../../../development/tools/make_key: 34: [[: not found
../../../../development/tools/make_key: 34: -e: not found

make_key中部分代码

30		if [[ -e $1.pk8 || -e $1.x509.pem ]]; then
31		  echo "$1.pk8 and/or $1.x509.pem already exist; please delete them first"
32		  echo "if you want to replace them."
33		  exit 1
34		fi

分析:

1. 遇到这个问题的时候先了解一下双方括号“[[ ]]”和 "-e"

在版本2.02的Bash中,引入了[[ ... ]]扩展测试命令, 注意[[是一个关键字, 并不是一个命令。【[[ is a keyword not a builtin Advanced Bash Scripting Guide 7.1 Test Constructs】[[ ]]结构比[ ]结构更加通用. 这是一个扩展的test命令, 是从ksh88中引进的.

-e:判断表示文件存在,相关的其他

-e file 文件 file 已经存在
-f file 文件 file 是普通文件
-s file 文件 file 大小不为零
-d file 文件 file 是一个目录
-r file 文件 file 对当前用户可以读取
-w file 文件 file 对当前用户可以写入
-x file 文件 file 对当前用户可以执行
-g file 文件 file 的 GID 标志被设置
-u file 文件 file 的 UID 标志被设置
-O file 文件 file 是属于当前用户的
-G file 文件 file 的组 ID 和当前用户相同
file1 -nt file2 文件 file1 比 file2 更新
file1 -ot file2 文件 file1 比 file2 更老
注意:上表中的 file 及 file1、file2 都是指某个文件或目录的路径。


2.经过半天的查找发现在我自己电脑上运行生成公钥私钥的脚本却不提示该错误。在其他几台服务器上测试后发现报一样的错。同事的机子上也是一样的错无提示。
怀疑跟bash的版本有关系,因为ubuntu虚拟机环境公司有一个文件时配置好的虚拟机文件,服务器上用这个,有的同事图省事没有没有自己搭建,是用现成的:

bash -version
结果发现bash版本一样。

GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

3. 那会不会是linux版本的问题呢??
服务器的linux版本

Linux bs30_u64 2.6.32-33-generic #71-Ubuntu SMP Wed Jul 20 17:27:30 UTC 2011 x86_64 GNU/Linux
Ubuntu 10.04.3 LTS

我自己本机的版本
Linux ubuntu_64 2.6.32-45-generic #101-Ubuntu SMP Mon Dec 3 15:39:38 UTC 2012 x86_64 GNU/Linux
Ubuntu 10.04.4 LTS

比较kernel和系统版本,大版本上都是一样,子版本上的区别,这个就要分析版本间的差别了。结果尝试着更新内核也没用

手动去升级了ubuntu的内核版本到

Linux ubuntu_64 2.6.38-11-generic #50~lucid1-Ubuntu SMP Tue Sep 13 21:53:24 UTC 2011 x86_64 GNU/Linux

4.是不是什么软件引起的。试过用一样的sources.list去升级,也用了

dpkg -l >> /home/sourcecode/soft.txt

导出的信息如下,省略

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                                   Version                                               Description
+++-======================================-=====================================================-============================================
ii  abs-guide                              4.1-1                                                 The Advanced Bash-Scripting Guide
ii  acpi-support                           0.136.1                                               scripts for handling many ACPI events
ii  acpid                                  1.0.10-5ubuntu2.1                                     Advanced Configuration and Power Interface e
ii  adduser                                3.112ubuntu1                                          add and remove users and groups
ii  adium-theme-ubuntu                     0.1-0ubuntu1                                          Adium message style for Ubuntu
ii  aisleriot                              1:2.30.0-0ubuntu6                                     Solitaire card games
ii  alacarte                               0.13.1-0ubuntu1                                       easy GNOME menu editing tool
ii  alsa-base                              1.0.22.1+dfsg-0ubuntu3                                ALSA driver configuration files

将两台虚拟机下安装的的软件进行比较,差不多软件安装都一样,除了Version不一样

在我自己安装完虚拟机后有做 apt-get update 有做过升级,于是我把安装的软件生成

看了早期的一些帖子关于sh-utils工具包的问题,试着下载了ftp://ftp.gnu.org/old-gnu/sh-utils/ 下的sh-utils-2.0.tar.gz版本,需要执行编译安装

./configure

make

make install

编译出错,想想这也是早期的东西,想必现在这个工具包已经不能用了,没有继续再试。

转换一下思路,出错的语句中无非是判断文件存不存在,判断退出。

可不可以换成是[...],结果不行 还有-e的错

使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如,
&&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中
的话, 会报错.


解决:目前的解决方法只能将将调用脚本的语句改成bash里传统的调用 ./xxx.sh
sh and bash are two different shells. While in the first case you are passing your script as an argument to the sh interpreter, in the second case you decide on the very first line which interpreter will be used.
因为 "[[" 在bash里只是个关键字 而不是个命令,Bash把[[ $a -lt $b ]]看作一个单独的元素, 并且返回一个退出状态码。【参考:Advanced Bash Scripting Guide 7.1 Test Constructs】在ksh好像可以。

./../../../../development/tools/make_key platform "$AUTH"
./../../../../development/tools/make_key media "$AUTH"
./../../../../development/tools/make_key shared "$AUTH"
./../../../../development/tools/make_key releasekey "$AUTH"

可能的原因:

bash脚本中调用了bash脚本

./gen_private_keys
调用了再调用make_key,这样在子进程中调用了bash ,所以还是用bash的 ./xxx.sh调用脚本,而不使用通用的 sh xxx.sh


你可能感兴趣的:(bash [[: not found, '[[' is a keyword not a builtin)