linux - 令人困惑的 shell 语法

标签 linux bash shell unix

在 Kernighan & Pike 的一个示例中,The Unix Programming Environment,作者在与命令相同的行中进行变量赋值。该行是这样的:

if PATH=$opath "$@" >$new

此行之前的那些变量的值是:

PATH=/bin:/usr/bin

和 opath=/a/really:/long/list/of:/pathnames

让我感到困惑的是,当我将该行更改为

if PATH=$opath echo $PATH

标准输出是:

/bin:/usr/bin

我已经在 sh 和 bash 中证实了这一点。谁能告诉我 Kearnighan & Pike 在这里做什么?自 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

我明白程序在做什么,如果 "$@">$new 的退出状态为 0,if 条件将如何评估为真。我不明白的是为什么没有为 PATH 分配值有问题的“if”行中的 $opath。

最佳答案

shell 执行的扩展

PATH=$opath echo $PATH

是(按此顺序):

  1. $PATH 扩展为其当前值
  2. $opath展开成它的值
  3. PATH等于$opath的扩展的环境中执行echo命令。

因此该命令会看到 PATH 的修改值,但赋值不会影响 shell 执行的扩展。

此外,即使后续命令也看不到$opath 的新值,它仅限于当前命令。

当命令部分为空时(即只有一个赋值),这个逻辑会改变;

PATH=$opath
echo $PATH

会先改变当前执行环境下$PATH的值,然后打印新值。

关于linux - 令人困惑的 shell 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20809702/

相关文章:

c - 为库函数定义 errno 值

linux - Jenkins + Build Flow,如何将变量从一个作业传递到另一个作业

linux - InputStreamReader getResourceAsStream 可以在 Linux 中运行吗?

bash - rm 命令在 shell 内部不起作用

bash - 在 bash 中拆分列表

linux - 如何使用 shell 命令控制/检查 gpio 状态(at91sam9260 开发板)

java - 将 jar 文件包含到使用 cpanel 的 php 项目中

linux - shell 脚本: Redirect output of program to changing files

python - Bash 脚本到 python 脚本的转换

shell - applescript/shell 中的单引号转义