命令适用于交互式shell,但不适用于shell脚本

时间:2012-09-10 22:03:51

标签: bash shell debian javac

我编写了一个脚本,它将为javac生成适当的参数来编译我的项目,以便更加熟练地掌握shell脚本。

这很奇怪..脚本运行完美,但如果脚本运行带有这些参数的javac它不起作用,如果我在交互式shell中运行完全相同的命令,它会。一切都以绝对路径输出,所以我在这里几乎不知所措。

示例目录结构:

src/File.java
src/File.png
src/dir/File2.java
jars/Library.jar

预期产出:

build/File.class
build/File.png
build/dir/File2.class

shell脚本:

#! /bin/sh

cwd=$(pwd)

if [ -d "build" ]; then
    rm -rf $cwd/build/*
else
    mkdir $cwd/build
fi

find $cwd/src \( ! -path '*/.*' \) -type f ! -iname "*.java" | xargs -I{} cp --parents {} $cwd/build

cmd=$(echo javac -sourcepath $cwd/src -classpath $(find $cwd/jars -type f | awk '{ printf("\"%s\";", $0);}'  | awk '{ print substr($0, 0, length($0)); }') -d $cwd/build $(find $cwd/src \( ! -path '*/.*' \) -type f -iname "*.java"))

$cmd
echo $cmd

命令输出:

javac -sourcepath /home/test/src -classpath "/home/test/jars/Library.jar" -d /home/test/build /home/test/src/File.java /home/test/src/dir/File2.java

我的实际项目太大了,无法在这里发布,但基本上发生的是我得到了大量的错误输出,好像类路径设置不正确(它们是库函数的错误)。如果我从echo语句中复制命令,粘贴它,然后按Enter键就可以完美地运行。

我不明白。

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

一般情况下,任何时候你都可以剪切粘贴一个命令并使其工作,但是当它运行该命令时shell没有工作,某处存在引用问题。不要试图找出它是什么,而是让shell评估字符串。换句话说,而不是:

$cmd

你希望shell评估$ cmd,就像你直接输入它一样:

eval $cmd

答案 1 :(得分:1)

您对-classpath的参数所引用的引号按字面处理,因为它们是$cmd值的一部分。扩展$cmd后不会删除它们,并将生成的字符串解析为命令行。就像你在命令行输入一样

$ javac -sourcepath /home/test/src -classpath \"/home/test/jars/Library.jar\" -d /home/test/build /home/test/src/File.java /home/test/src/dir/File2.java