在unix编程环境kernighan&pike的一个例子中,作者在命令行中执行变量赋值。行是这样的:
if PATH=$opath "$@" >$new
其中,该行之前的变量值为:
路径=/bin:/usr/bin
和opath=/a/really:/long/list/of:/pathnames
让我困惑的是当我把这条线改成
if PATH=$opath echo $PATH
标准是:
/bin:/usr/bin
我已经在sh和bash中都证实了这一点。有人能告诉我卡尼根和派克在这里干什么吗?自1982年以来,shell实现的这一方面是否发生了变化,或者发生了其他事情?
编辑:这是这本书的全部程序。
#!/bin/bash
# overwrite: copy standard input to output after EOF
# final version
opath=$PATH
PATH=/bin:/usr/bin
case $# in
0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2
esac
file=$1; shift
new=/tmp/overwr1.$$; old=/tmp/overwr2.$$
trap 'rm -f $new $old; exit 1' 1 2 15
if PATH=$opath "$@" >$new
then
cp $file $old
trap '' 1 2 15
cp $new $file
else
echo "overwrite: $1 failed, $file unchanged" 1>&2
exit 1
fi
rm -f $new $old
我理解程序在做什么,如果“$@”>新的出口状态为0,IF条件如何评估为TRUE。我不明白的是,为什么path没有在“if”行中指定$opath的值。
最佳答案
shell执行的扩展
PATH=$opath echo $PATH
是(按此顺序):
将
$PATH
扩展到当前值将
$opath
扩展为其值在
echo
等于PATH
扩展的环境中执行$opath
命令。因此,命令会看到修改后的值
PATH
,但赋值不会影响shell执行的扩展。此外,即使后续命令也看不到新值
$opath
,它仅限于当前命令。当命令部分为空时(即只有一个赋值),这个逻辑就会改变;
PATH=$opath
echo $PATH
将首先在当前执行环境中更改
$PATH
的值,然后打印新值。