我在SLES 11 SP3上,使用GNU bash 3.2.51。我注意到在执行source filename
时出现了异常行为 - 它执行任何处理命令行参数$*
的行为。
文件f1.sh
#!/bin/bash
#this is only a test driver
echo FYI PWD=$PWD
./f2.sh "$*"
文件f2.sh
#!/bin/sh
#this is the application script
echo args in f2.sh were $*
档案f3.sh
#!/bin/bash
#this is the real driver code
echo FYI PWD=$PWD
source ~/.bashrc
./f2.sh "$*"
当我执行f1.sh cat f2.sh
时,我得到以下似乎没问的
/tmp> ./f1.sh cat f1.sh
FYI PWD=/tmp
args were cat f1.sh
但是当我执行f3.sh cat f2.sh
时,非常意外地
/tmp> ./f3.sh cat f1.sh
cat: f1.sh: No such file or directory
cat: f1.sh: No such file or directory
FYI PWD=/usr/app/DB/DB00
./f3.sh: line 4: ./f2.sh: No such file or directory
最后,我决定在执行f3.sh
之前将shift
修改为$*
除source ~/.bashrc
个值{/ 1}}
#!/bin/bash
#this is the real driver code
echo FYI PWD=$PWD
cmd="$*"
while shift; do true; done #<<<<<<<<<<<<<<< get rid of hanging args
source ~/.bashrc
./f2.sh ${cmd}
但我不知道为什么会这样。或许知识渊博的人可以准确地解释发生了什么。 (也许有一个选项)非常感谢。
答案 0 :(得分:1)
source
不使用$*
;但是,获取另一个脚本会在相同的上下文中执行它,从而使$*
可用。这里~/.bashrc
可能使用$*
或$@
的脚本参数。
以下是origin.sh
的示例:
#! /bin/bash
echo " args before: $*"
source ./script.sh
echo " args after: $*"
script.sh
:
#! /bin/bash
echo "args in the script: $*"
# shift the list twice
shift
shift
执行./origin.sh
显示:
$ ./origin.sh foo bar qux
args before: foo bar qux
args in the script: foo bar qux
args after: qux
这确认script.sh
可以访问$*
,可以使用并修改它。
现在,如果我将origin.sh
更改为执行script.sh
而不是采购它,那么它将在另一个shell中进行评估,并且无法访问origin.sh
的{{1}} }:
$*
结果:
#! /bin/bash
echo " args before: $*"
./script.sh
echo " args after: $*"