简体   繁体   English

命令在交互式外壳程序中有效,但在外壳程序脚本中无效

[英]Command works in interactive shell but not shell script

I wrote a script that would generate the appropriate arguments to javac to compile my project in an effort to grow more proficient at shell scripting. 我编写了一个脚本,该脚本将生成适合Javac的参数来编译我的项目,以期变得更加精通Shell脚本。

The weird this is.. The script works perfectly, but if the script runs javac with those parameters it doesn't work, and if I run the exact same command in the interactive shell it does. 脚本工作正常,但是如果脚本使用这些参数运行javac则无法正常工作,并且如果我在交互式外壳程序中运行完全相同的命令,它将可以正常工作。 Everything is outputted with absolute paths, so I'm pretty much at a loss here. 一切都是通过绝对路径输出的,所以我在这里很茫然。

Example directory structure: 目录结构示例:

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

Expected output: 预期产量:

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

The shell script: 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

Command output: 命令输出:

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

My actual project is too large to post here, but basically what happens is I get a huge amount of error output, as if the classpath was improperly set (they're errors on library functions). 我的实际项目太大,无法在此处发布,但是基本上发生的是我收到大量错误输出,好像类路径设置不正确(它们是库函数的错误)。 If I copy the command from the echo statement, paste it, and hit enter it works perfectly. 如果我从echo语句复制命令,则将其粘贴,然后按Enter键即可正常运行。

I don't get it. 我不明白

Any ideas? 有任何想法吗?

In general, anytime you can cut-n-paste a command and make it work but the shell is not working when it is running that command, there is a quoting problem somewhere. 通常,只要您可以剪切-粘贴命令并使其正常运行,但是在运行该命令时Shell无法运行,则某处存在引用问题。 Rather than trying to figure out what it is, just make the shell evaluate the string. 与其尝试弄清楚它是什么,不如让shell对字符串进行评估。 In other words, instead of: 换句话说,代替:

$cmd

you want the shell to evaluate $cmd as if you had typed it directly: 您希望外壳程序像直接键入一样评估$ cmd:

eval $cmd

The quotation marks you put around the argument to -classpath are treated literally, because they are part of the value of $cmd . 逐字对待您在-classpath参数周围加上的引号,因为它们是$cmd值的一部分。 They are not removed after $cmd is expanded and the resulting string is parsed as a command line. 扩展$cmd并将结果字符串解析为命令行后,不会删除它们。 It's as if you had typed at the command line 就像您在命令行中键入一样

$ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM