在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的值,然后打印新值。

10-07 16:28