首页 > 解决方案 > 在shell脚本中,从while循环中的文件读取后无法访问外部变量

问题描述

#!/bin/sh
# Read in classpath
if [ x"${JAVA_CLASSPATH}" != x ]; then
    classpath="${JAVA_CLASSPATH}"
else
    classpath=""
    while read file; do
        classpath="${classpath}:${JAVA_APP_DIR}/lib/$file"
    done < ${JAVA_APP_DIR}/lib/classpath
fi
echo classpath is ${classpath}

我正在尝试通过从文件中读取来构建类路径,但是在 while 循环之外无法访问类路径变量。请指定在 while 循环之外访问类路径变量的方法。回显语句的结果。

echo : classpath is 

PS:我看到了其他类似的问题,我没有使用这些问题中提到的任何管道。我的代码反映了为这些问题指定的答案,但我仍然面临这个问题。这也是一个 shell 脚本而不是 bash。

标签: shellsh

解决方案


很可能${JAVA_APP_DIR}/lib/classpath不存在。

比较以下两段相似的代码(只有第一行不同),在POSIX兼容的dashshell 下测试:

  1. 输入文件dummyfile存在。

    echo baz > dummyfile
    unset foo
    if false
    then : 
    else while [ -z "$foo" ] ; do
             foo="bar"
         done < dummyfile
    fi
    echo "=$foo="
    

    输出:

    =bar=
    
  2. 输入文件dummyfile不存在。

    rm -f dummyfile
    unset foo
    if false
    then : 
    else while [ -z "$foo" ] ; do
             foo="bar"
         done < dummyfile
    fi
    echo "=$foo="
    

    输出:

    dash: 65: cannot open dummyfile: No such file
    ==
    

    循环的内容while从未运行过。


请注意,代码有点奇怪:

  • while循环总是运行一次并退出,因为was$foounsetthen 被重置。

  • 有一个done < dummyfile,但不能read从中输入任何内容。然而,即使没有read命令,该文件的存在与<重定向相结合,决定了是否$foo设置。

  • 即使是空文件也可以:

    unset foo
    if false
    then : 
    else while [ -z "$foo" ] ; do
             foo="bar"
         done < /dev/null
    fi
    echo "=$foo="
    

推荐阅读