我正在编写一个普通脚本,希望通过存储在同一文件夹中的属性文件进行控制。但是,我希望能够从任何地方调用此脚本。当我运行脚本时,它总是根据运行位置而不是脚本的位置查找属性文件。
如何从脚本内部访问脚本文件的路径?
Answers:
从Groovy 2.3.0开始,@groovy.transform.SourceURI
注释可用于使用脚本位置的URI填充变量。然后可以使用此URI来获取脚本的路径:
import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths
@SourceURI
URI sourceUri
Path scriptLocation = Paths.get(sourceUri)
请注意,这仅适用于URI为file:
URI(或具有已安装FileSystemProvider的其他URI方案类型)的情况,否则调用将抛出FileSystemNotFoundExceptionPaths.get(URI)
。某些groovy运行时(例如groovyshell和nextflow)将返回一个data:
URI,该URI通常与installed不匹配FileSystemProvider
。
sourceUri
收到该异常有什么价值?还是在@SourceUri
网上发生而不是在将其转换为a时发生Path
?
java.net.URI
;加上您显示的地图是java.net.URI
该类的属性。您确定它实际上是在设置地图,而不是地图URI
吗?无论如何,这看起来像是数据URL,而不是文件URL。脚本的来源实际上是本地文件,而不是通过网络序列化的东西或类似的东西吗?在这种情况下,甚至没有相应的文件,这说明了为什么无法将其转换为Path
。
@SourceURI
如果从Groovy控制台运行,则该方法不起作用,我已经在本地确认。当您直接从命令行运行脚本时会发生什么?例如groovy sourceUriTest.groovy
,用sourceUriTest.groovy
您的实际脚本文件替换“ ”?
您是正确的,new File(".").getCanonicalPath()
不起作用。返回工作目录。
获取脚本目录
scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
获取脚本文件路径
scriptFile = getClass().protectionDomain.codeSource.location.path
getClass().protectionDomain.codeSource
返回null。我正在使用Groovy 2.0.1。
MyClassName.class.protectionDomain.codeSource
代替(REF stackoverflow.com/questions/11747833/...)
/groovy
父目录还是正确的目录。那怎么办:getClass().getResource('/${yourScript}.groovy')
假设您的脚本在
如果您将Groovy代码作为脚本运行,这是有道理的,否则整个想法会有些混乱,IMO。解决方法在这里:https : //issues.apache.org/jira/browse/GROOVY-1642
基本上,这涉及更改startGroovy.sh以将Groovy脚本的位置作为环境变量传递。
对于gradle用户
我开始使用gradle时遇到相同的问题。我想通过远程Thrift编译器(我公司自定义)编译Thrift。
以下是我解决问题的方法:
task compileThrift {
doLast {
def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
ssh.run {
session(remotes.compilerServer) {
// Delete existing thrift file.
cleanGeneratedFiles()
new File("$projectLocation/thrift/").eachFile() { f ->
def fileName=f.getName()
if(f.absolutePath.endsWith(".thrift")){
put from: f, into: "$compilerLocation/$fileName"
}
}
execute "mkdir -p $compilerLocation/gen-java"
def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
assert compileResult.contains('SUCCESSFUL')
get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
}
}
}
}
另一种解决方案。即使您使用GrovyConsole运行脚本,它也可以完美运行
File getScriptFile(){
new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}
println getScriptFile()
解决方法:对我们来说,它运行在ANT环境中,并在Java环境属性(System.setProperty( "dirAncestor", "/foo" )
)中存储了一些位置父级(知道子路径),我们可以通过Groovy的来访问目录祖先properties.get('dirAncestor')
。
也许这将对此处提到的某些情况有所帮助。
java.nio.file.FileSystemNotFoundException: Provider "data" not installed