Bash `test`在当前shell中查找脚本时,比较的行为不同
我在bash脚本中有一个令人惊讶的行为。脚本如下所示,我已尽可能简化: test.sh:Bash `test`在当前shell中查找脚本时,比较的行为不同,bash,shell,Bash,Shell,我在bash脚本中有一个令人惊讶的行为。脚本如下所示,我已尽可能简化: test.sh: DBOK=$(sqlplus -s user/xxx as sysdba<<EOF set feed off pages 0 echo off SELECT decode(value,'TRUE','CLUSTER','FALSE','NONCLUSTER','UNKNOWN') from v\$parameter where name='cluster_database'; EOF ) ech
DBOK=$(sqlplus -s user/xxx as sysdba<<EOF
set feed off pages 0 echo off
SELECT decode(value,'TRUE','CLUSTER','FALSE','NONCLUSTER','UNKNOWN') from v\$parameter where name='cluster_database';
EOF
)
echo x"$DBOK"y
set -x
if [ "${DBOK}" == NONCLUSTER ]; then
echo "not a cluster do nothing"
fi
set +x
但是,如果我在“点空间斜杠”模式下运行脚本(根据需要:最终目标是修改当前进程的env),它将不起作用:
. /path/test.sh
test
xNONCLUSTERy
++ '[' 'NONCLUSTER' == NONCLUSTER ']'
++ set +x
作为sql脚本的结果加载变量可以很好地工作,并且结果看起来很好。但是在进行测试比较时,在当前进程中运行脚本似乎会破坏它
任何帮助都将不胜感激,我已经干涸了
在Adrian的评论之后使用hextump命令进行编辑:
$./test.sh
00000000 4e 4f 4e 43 4c 55 53 54 45 52 0a |NONCLUSTER.|
0000000b
xNONCLUSTERy
++ [[ NONCLUSTER == NONCLUSTER ]]
++ echo 'not a cluster do nothing' not a cluster do nothing
++ set +x
00000000 1b 5d 30 3b 6f 72 61 63 6c 65 40 6e 61 74 71 6f |.]0;oracle@natqo|
00000010 72 61 30 34 3a 7e 2f 73 63 72 69 70 74 73 2f 74 |ra04:~/scripts/t|
00000020 6f 6f 6c 73 20 7c 20 73 71 6c 70 6c 75 73 20 2d |ools | sqlplus -|
00000030 73 20 6c 65 64 62 61 40 51 42 4f 41 55 44 49 54 |s ledba@QBOAUDIT|
00000040 20 61 73 20 73 79 73 64 62 61 07 4e 4f 4e 43 4c | as sysdba.NONCL|
00000050 55 53 54 45 52 0a |USTER.|
00000056
xNONCLUSTERy
++ [[ NONCLUSTER == NONCLUSTER ]]
++ set +x
美元/test.sh
00000000 4e 4f 4e 43 4c 55 53 54 45 52 0a |NONCLUSTER.|
0000000b
xNONCLUSTERy
++ [[ NONCLUSTER == NONCLUSTER ]]
++ echo 'not a cluster do nothing' not a cluster do nothing
++ set +x
00000000 1b 5d 30 3b 6f 72 61 63 6c 65 40 6e 61 74 71 6f |.]0;oracle@natqo|
00000010 72 61 30 34 3a 7e 2f 73 63 72 69 70 74 73 2f 74 |ra04:~/scripts/t|
00000020 6f 6f 6c 73 20 7c 20 73 71 6c 70 6c 75 73 20 2d |ools | sqlplus -|
00000030 73 20 6c 65 64 62 61 40 51 42 4f 41 55 44 49 54 |s ledba@QBOAUDIT|
00000040 20 61 73 20 73 79 73 64 62 61 07 4e 4f 4e 43 4c | as sysdba.NONCL|
00000050 55 53 54 45 52 0a |USTER.|
00000056
xNONCLUSTERy
++ [[ NONCLUSTER == NONCLUSTER ]]
++ set +x
获取脚本时,您正在运行哪个shell 由于输出看起来不一样(
NOCLUSTER
vs.'NOCLUSTER'
),我假设它不是同一个shell,并且您当前运行的shell可能不允许将=
与不可移植的单括号表示法结合使用(但大多数现代shell允许)
对于支持它的shell,应该使用[…=…]
或[…==…]]
。我通常使用单括号表示法,除非我特别需要一个只随[[
一起提供的功能,比如=~
操作符
我似乎无法重现这一点:
$ /bin/bash --noprofile --norc
但对此类行为没有解释,但解决方法是分两步加载变量:
sqlplus -s ledba/xxx as sysdba<<EOF
spool /tmp/test.lst
set feed off pages 0 echo off
SELECT decode(value,'TRUE','CLUSTER','FALSE','NONCLUSTER','INCONNU') from v\$parameter where name='cluster_database';
spool off
EOF
DBOK=`cat /tmp/test.lst|sed 's/ *$//'`
sqlplus-s ledba/xxx作为sysdba我怀疑您的默认shell不是您认为的bash
。您使用的bash语法是=
,而正常的非bash测试无法识别=
。有两种选择:
- 使用
=
作为测试,而不是=
。这将适用于所有基于Posix的Shell和原始Bourne Shell
- 将
#!/bin/bash
添加到脚本顶部,以保证您使用的是bash而不是其他shell。永远不要使用shell。如果您完全使用bash,请在测试中使用[…]
而不是[…]
。这在Kornshell、Dash和Ash shell中也适用
即使/bin/sh
链接到/bin/bash
,当通过sh
调用bash时,bash的行为也不像bash。相反,它据称是在纯POSIX模式下运行的(我之所以这么说,是因为Kornshell是一个完全兼容POSIX的shell,我知道Kornshell所做的某些事情在/bin/sh
中无法工作)
在Mac OS X上,/bin/sh
链接到/bin/bash
。在Linux系统上,他们使用Ash或Dash shell作为/bin/sh
,这应该更符合POSIX。感谢您的输入,Adrian。不幸的是,它没有解决这个问题。shell是/bin/bash,我测试了单/双的所有组合括号中有=或==,但我得到了相同的结果。但是我现在有[[NONCLUSTER==NONCLUSTER]]处于“点空间斜线模式”?我更新了我的帖子,我无法重现你看到的行为。再次感谢Adrian。我得到了与你相同的反馈(除了我的“sh t.sh”没有错误,而是我的“sh”命令链接到bash,因此它在逻辑上工作)如您所见,我用x和y括起来检查变量是否有多余字符,但我必须假设有多余字符,这是sql oracle查询的结果?这个小错误是一个真正的噩梦,我看不到任何解决方法或替代方法来测试…!Atb。我的sh
也是bash
,但这并不能解释它为什么工作。如果作为sh
bash
调用,将进入POSIX
-兼容模式,因此实际上它不应该工作,除非此行为发生改变,但我在bash
更改日志中找不到任何支持此假设的内容。您使用的是bash
的哪个版本?我同意,但我测试了非printa的阅读我生成的一个文件中的ble字符以及set-x
的输出清楚地显示了该变量包含特殊字符(不管怎样,我的shell)所以我也不这么认为。但是你还是应该通过做一些检查,例如,hextump-C Bingo-Adrian,你太棒了!我回来时给出了完整的解释,但基本上我的变量不包含它在“点空间斜杠”中似乎包含的内容模式。#!/bin/bash解决了问题。我不应该信任$SHELL或任何其他测试。多亏了Adrian和David!这不正是我说的吗?还有,“在Linux系统上”这是一个错误的概括,不是每个Linux发行版都默认为/bin/sh
的ash
或dash
。
bash-4.2$ . ./t.sh
++ '[' NONCLUSTER = NONCLUSTER ']'
++ echo true
true
++ '[' NONCLUSTER == NONCLUSTER ']'
++ echo true
true
++ [[ NONCLUSTER == NONCLUSTER ]]
++ echo true
true
bash-4.2$ sh t.sh
+ sh t.sh
+ [ NONCLUSTER = NONCLUSTER ]
+ echo true
true
+ [ NONCLUSTER == NONCLUSTER ]
t.sh: 6: [: NONCLUSTER: unexpected operator
+ echo false
false
+ [[ NONCLUSTER == NONCLUSTER ]]
t.sh: 7: t.sh: [[: not found
+ echo false
false
sqlplus -s ledba/xxx as sysdba<<EOF
spool /tmp/test.lst
set feed off pages 0 echo off
SELECT decode(value,'TRUE','CLUSTER','FALSE','NONCLUSTER','INCONNU') from v\$parameter where name='cluster_database';
spool off
EOF
DBOK=`cat /tmp/test.lst|sed 's/ *$//'`