天道酬勤,学无止境

If a Julia script is run from the command line, does it need to be re-compiled every time?

I've read through quite some documentation and questions but I'm still confused about this.

In the Profiling section of the documentation it's suggested to first run the target function in the REPL once, so that it's already compiled before being profiled. However, what if the script is fairly complicated and is inteded to be run in the command line, taking arguments? When the julia process finishes and I run the script the second time, is the compilation performed again? Posts like https://stackoverflow.com/a/42040763/1460448, Julia compiles the script every time? give conflicting answers. They also seem to be old while Julia is constantly evolving.

It seems to me that the second run takes exactly as much time as the first run in my experience. The startup time is quite long. How should I optimize such a program? Adding __precompile__() doesn't seem to have changed the execution time at all.

Also, what should I do when I want to profile such a program? All resources on profiling talk about doing so in the REPL.

评论

Please correct me if I am wrong, but it sounds like you have written some long script, say, myfile.jl, and then from your OS command line you are calling julia myfile.jl args.... Is this correct? Also, it sounds like myfile.jl does not define much in the way of functions, but is instead just a sequence of commands. Is this correct? If so, then as has been suggested in the comments on the question, this is not the typical work-flow for julia, for two reasons:

1) Calling julia from the command line, ie julia myfile.jl args... is equivalent to opening a REPL, running an include command on myfile.jl, and then closing the REPL. The initial call to include will compile any methods that are needed for the operations in myfile.jl, which takes time. But since you're running from the command line, once the include is finished, the REPL automatically closes, and all that compiled code is thrown away. This is what DNF means when he says the recommended workflow is to work within a single REPL session, and don't close it until you are done for the day, or unless you deliberately want to recompile all the methods you are using.

2) Even if you are working within a single REPL session, it is extremely important to wrap pretty much everything you do in functions (this is a very different workflow to languages like Matlab). If you do this, Julia will compile methods for each function that are specialized on the types of the input arguments that you are using. This is essentially why Julia is fast. Once a method is compiled once, it remains available for the entire REPL session, but is disposed of when you close the REPL. Critically, if you do not wrap your operations in functions, then this specialized compilation does not occur, and so you can expect very slow code. In julia, we call this "working in the global scope". Note that this feature of Julia encourages a coding style consisting of breaking your tasks down into lots of small specialized functions rather than one behemoth consisting of 1000 lines of code. This is a good idea for many reasons. (in my own codebase, many functions are a single-liners, most are 5 lines or less)

The two points above are absolutely critical to understand if you are working in Julia. However, once you are comfortable with them, I would recommend that you actually put all your functions inside modules, and then call your module(s) from an active REPL session whenever you need it. This has the additional advantage that you can just add a __precompile__() statement at the top of your module, and then julia will precompile some (but not necessarily all) of the code in that module. Once you do this, the precompiled code in your module doesn't disappear when you close the REPL, since it is stored on the hard-drive in a .ji file. So you can start a new REPL session, type using MyModule, and your precompiled code is immediately available. It will only need to re-compile if you alter the contents of the module (and this all happens automatically).

I disagree somewhat with my colleagues. There are absolutely valid scenarios where one would rely on running julia scripts. E.g. when you have a pipeline of scripts (e.g. matlab, python, etc) and you need to plug in a julia script somewhere in the middle of all that, and control the overall pipeline from a shell script. But, whatever the use case, saying "just use the REPL" isn't a proper answer to this question, and even if one couldn't come up with "valid" scenarios, it is still a question worth answering directly rather than with a workaround.

What I do agree on is that the solution to having appropriate code is to wrap everything critical that needs to be precompiled into modules, and only leave all but the most external commands at the script top-level. This is not too dissimilar to the matlab or C++ world anyway, where you're expected to write thorough functions, and only treat your script / main function as some sort of very brief, top-level entry point whose job is to simply prepare the initial environment, and then run those more specialised functions accordingly.

Here's an example of what I mean:

# in file 'myscript.jl'
push!( LOAD_PATH, "./" )
import MyPrecompiledModule
println( "Hello from the script. The arguments passed into it were $ARGS" )
MyPrecompiledModule.exportedfun()

# in file 'MyPrecompiledModule.jl' (e.g. in the same directory as myscript.jl)
__precompile__()
module MyPrecompiledModule
  export exportedfun;
  function innerfun()
    println("Hello from MyPrecompiledModule.innerfun");
  end

  function exportedfun()
    innerfun()
    print("Hello from MyPrecompiledModule.exportedfun");
  end
end

In the above scenario, the compiled version of the MyPrecompiledModule will be used in the script (and if one does not exist, one will be compiled the first time you run the script), therefore any optimisations from compiling will not be lost at the end of the script, but you still end up with a standalone julia script you can use as part of a bash shell script pipeline process, that you can also pass arguments to. The myscript.jl script then only has to pass these on to the imported module functions if necessary, and perform any other commands that you don't particularly care about them being compiled / optimised or not, such as perform benchmarks, provide script usage instructions, etc.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 碾压Python!为什么Julia速度这么快?
    什么要选择 Julia?因为它比其他脚本语言更快,它在具备 Python、MATLAB、R 语言开发速度的同时,又能生成与 C 语言和 Fortran 一样快的代码。但 Julia 新手对这种说法可能会有点怀疑。 为什么其他脚本语言不也提升一下速度?Julia 可以做到的,为什么其他脚本语言做不到?你能提供基准测试来证明它的速度吗?这似乎有违“天底下没有免费的午餐”的道理。它真的有那么完美吗?很多人认为 Julia 运行速度很快,因为它是即时编译(JIT)型的(也就是说,每条语句都使用编译的函数来运行,这些函数要么在使用之前进行即时编译,要么在之前已经编译过并放在缓存中)。这就引出了一个问题:Julia 是否提供了比 Python 或 R 语言(MATLAB 默认使用 JIT)更好的 JIT 实现?因为人们在这些 JIT 编译器上所做的工作比 Julia 要多得多,所以我们凭什么认为 Julia 这么快就会超过这些编译器?但其实这完全是对 Julia 的误解。我想以一种非常直观的方式说明,Julia 的速度之所以快,是因为它的设计决策。Julia 的的核心设计决策是通过多重分派实现专门化的类型稳定性,编译器因此可以很容易地生成高效的代码,同时还能够保持代码的简洁,让它“看起来就像一门脚本语言”。但是,在本文的示例中,我们将看到 Julia 并不总是像其他脚本语言那样,我们必须接受
  • 需要pandoc 1.12.3或更高版本,但未找到(R闪亮)(pandoc version 1.12.3 or higher is required and was not found (R shiny))
    问题 我从托管在服务器上的我的应用程序Shining生成pdf报告时遇到问题。 该应用程序运行正常,但是当我按下按钮下载报告时,出现此错误: pandoc version 1.12.3 or higher is required and was not found. 问题是,如果我输入pandoc -v我将得到: pandoc 1.12.3.3 Compiled with texmath 0.6.6, highlighting-kate 0.5.6.1. Syntax highlighting is supported for the following languages: actionscript, ada, apache, asn1, asp, awk, bash, bibtex, boo, c, changelog, clojure, cmake, coffee, coldfusion, commonlisp, cpp, cs, css, curry, d, diff, djangotemplate, doxygen, doxygenlua, dtd, eiffel, email, erlang, fortran, fsharp, gnuassembler, go, haskell, haxe, html, ini, java, javadoc, javascript
  • 第 6 章 字符和字符串
    {{TOC}} 第 6 章 字符和字符串 6.1 Unicode 字符 在讲 Unicode 字符之前,我们先来简要介绍一下 ASCII 编码。 ASCII 是 American Standard Code for Information Interchange 的缩写,可以翻译为美国信息交换标准代码。它是由美国国家标准学会(American National Standard Institute, 简称 ANSI)制定的标准的单字节字符编码方案,主要用途是基于文本的数据交换。这个方案起始于上个世纪 50 年代的后期,并在 1967 年定案。它最初是美国的国家标准,是不同计算机在相互通信时共同遵守的西文字符编码标准。ASCII 编码支持的所有字符的集合被称为 ASCII 编码集。 ASCII 编码使用 1 个字节来表示 1 个字符。其中的 7 位二进制数字用于表示大写和小写的英文字母、0到9的数字、各种英文标点符号,以及一些不可打印字符和控制字符。而字节的最高位则用于奇偶校验。这使得 ASCII 编码集中只能容纳 128 个字符。 我们之前提到的 Unicode 字符实际上指的是 Unicode 编码标准所支持的字符。Unicode 是一个针对书面字符和文本的通用字符编码标准。它定义了多语言文本数据在国际间交换的统一方式,并为全球化软件创建了基础。Unicode 编码标准以
  • 如何将ProcessBuilder的输出重定向到字符串?(How to redirect ProcessBuilder's output to a string?)
    问题 我正在使用以下代码来启动流程构建器。我想知道如何将其输出重定向到String 。 ProcessBuilder pb = new ProcessBuilder( System.getProperty("user.dir") + "/src/generate_list.sh", filename); Process p = pb.start(); 我尝试使用ByteArrayOutputStream但似乎没有用。 回答1 从InputStream读取。 您可以将输出附加到StringBuilder : BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder builder = new StringBuilder(); String line = null; while ( (line = reader.readLine()) != null) { builder.append(line); builder.append(System.getProperty("line.separator")); } String result = builder.toString(); 回答2 使用Apache Commons
  • Problems with pip install numpy - RuntimeError: Broken toolchain: cannot link a simple C program
    I'm trying to install numpy (and scipy and matplotlib) into a virturalenv. I keep getting these errors though: RuntimeError: Broken toolchain: cannot link a simple C program ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 I have the command line tools for xcode installed $ which gcc /usr/bin/gcc $ which cc /usr/bin/cc I'm on Mac OSX 10.9 Using a brew installed python Edit Yes, trying to install with pip. The whole traceback is huge (>400 lines) Here is a section of it: C compiler: cc -fno-strict-aliasing -fno-common -dynamic
  • 什么是__pycache__?(What is __pycache__?)
    问题 据我了解,缓存是类似文件的加密文件。 我们如何处理__pycache__文件夹? 是我们提供给人们的,而不是我们提供的源代码吗? 只是我的输入数据吗? 这个文件夹不断创建,它是做什么用的? 回答1 当您在python中运行程序时,解释器首先将其编译为字节码(这过于简化),并将其存储在__pycache__文件夹中。 如果在其中查看,您会在项目文件夹中找到一堆共享.py文件名的文件,只有它们的扩展名是.pyc或.pyo。 它们分别是程序文件的字节码编译版本和优化的字节码编译版本。 作为程序员,您基本上可以忽略它……它所做的只是使您的程序启动更快。 脚本更改时,将重新编译它们,如果删除文件或整个文件夹并再次运行程序,它们将重新出现(除非您明确禁止这种行为)。 当您将代码发送给其他人时,通常的做法是删除该文件夹,但是是否执行此操作并不重要。 当您使用版本控制( git )时,此文件夹通常列在忽略文件( .gitignore )中,因此不包括在内。 如果您使用的是cpython(这是最常见的实现,因为它是参考实现),并且您不想要该文件夹,则可以通过使用-B标志启动解释器来取消显示该文件夹。 python -B foo.py 正如tcaswell指出的,另一种选择是将环境变量PYTHONDONTWRITEBYTECODE设置为任何值(根据python的手册页,任何“非空字符串”)。
  • 亚行外壳苏工作,但亚行根不(adb shell su works but adb root does not)
    问题 我将解锁的Galaxy S3(SGH-T999)植根 现在,我尝试从Windows命令提示符运行adb root ,但是,我得到adbd cannot run as root in production builds错误中adbd cannot run as root in production builds 。 所以,我检查的第一件事是我的手机是否真的扎根了? 所以我尝试了以下方法: 打开命令提示符 $adb devices // lists my device $adb shell //goes to shell $su // opens a 'SuperSu' prompt on my phone and I 'Grant' permission # // Before following the rooting instructions, I was getting 'no su command found' in the previous step. So, I believe my phone is ROOTED. **Correct me if I'm wrong.** 但是,当我执行adb root ,我得到adbd cannot run as root in production builds错误中adbd cannot run as root in
  • How do I determine whether a julia script is included as module or run as script?
    I would like to know how in the Julia language, I can determine if a file.jl is run as script, such as in the call: bash$ julia file.jl It must only in this case start a function main, for example. Thus I could use include('file.jl'), without actually executing the function. To be specific, I am looking for something similar answered already in a python question: def main(): # does something if __name__ == '__main__': main() Edit: To be more specific, the method Base.isinteractive (see here) is not solving the problem, when using include('file.jl') from within a non-interactive (e.g. script)
  • 如何在IntelliJ IDEA中输入命令行参数?(How do you input command line arguments in IntelliJ IDEA?)
    问题 我通常通过运行配置在Eclipse中输入命令行参数。 但是我不知道如何在IntelliJ IDEA中完成相同的任务。 回答1 Windows,Linux和某些Mac: ALT + SHIFT + F10,向右,E,Enter,Tab,输入命令行参数,然后按Enter。 ;-) 具有“ OS X 10.5”键架构的Mac: Ctrl + Alt + R,向右,E,Enter,Tab,输入命令行参数,然后按Enter。 回答2 在“运行”菜单上有一个“编辑配置”项,在工具栏上两个绿色的“运行”和“调试”箭头的左侧下拉菜单中。 在该面板中,使用左上角的“ +”按钮创建配置,然后可以选择包含main()的类,添加VM参数和命令行参数,指定工作目录和任何环境变量。 还有其他选项:代码覆盖率,日志记录,构建,JRE等。 回答3 如果您使用的是intellij,请转到Run > Edit Configurations菜单设置。 将出现一个对话框。 现在,您可以将参数添加到“ Program arguments输入字段中。 回答4 示例我有一个类Test: 然后。 转到config来运行类Test: 步骤1:添加应用 第2步: 您可以在“程序参数”文本框中输入参数。 回答5 我们不能进入终端并给出好的旧的java Classname arg1 arg2 arg3 我们必须编辑运行配置。
  • TypeScript文件更改时如何监视和重新加载ts节点(How to watch and reload ts-node when TypeScript files change)
    问题 我正在尝试使用TypeScript和Angular应用程序运行开发服务器,而无需每次都转换ts文件。 我发现我可以使用ts-node运行,但是我也想观看.ts文件并重新加载应用程序/服务器,就像使用gulp watch这样。 回答1 编辑:更新为nodemon的最新版本! 在开发环境中,我一直在苦苦挣扎,直到我注意到nodemon的API允许我们更改其默认行为以便执行自定义命令。 例如: nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' src/index.ts 甚至更好:将具有以下内容的nodemon的配置外部化为nodemon.json文件,然后按照Sandokan的建议运行nodemon : { "watch": ["src/**/*.ts"], "ignore": ["src/**/*.spec.ts"], "exec": "ts-node ./index.ts" } 这样,您就可以实时重载ts-node进程,而不必担心基础实现。 干杯! 已更新为最新版本的nodemon: 您可以运行此命令,例如: nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "ts-node
  • pip安装numpy的问题-RuntimeError:断开的工具链:无法链接简单的C程序(Problems with pip install numpy - RuntimeError: Broken toolchain: cannot link a simple C program)
    问题 我正在尝试将numpy(以及scipy和matplotlib)安装到virturalenv中。 我一直收到这些错误: RuntimeError: Broken toolchain: cannot link a simple C program ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 我已经安装了用于xcode的命令行工具 $ which gcc /usr/bin/gcc $ which cc /usr/bin/cc 我在Mac OSX 10.9上使用Brew安装的python 编辑是的,尝试使用pip安装。 整个回溯是巨大的(> 400行) 这是其中的一部分: C compiler: cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes
  • set -e和exec“ $ @”对于docker入口点脚本有什么作用?(What does set -e and exec “$@” do for docker entrypoint scripts?)
    问题 我已经注意到,许多docker的entrypoint.sh脚本都会执行以下操作: #!/bin/bash set -e ... code ... exec "$@" set -e和exec "$@"是什么? 回答1 它基本上接受传递给entrypoint.sh任何命令行参数,并将其作为命令执行。 目的基本上是“在此.sh脚本中执行所有操作,然后在同一shell中运行用户在命令行中传递的命令”。 看: 什么是特殊的美元符号外壳变量? 需要Linux bash内置exec命令行为的解释 回答2 set -e将shell选项设置为如果正在运行的任何命令以非零退出代码退出,则立即退出。 该脚本将返回失败命令的退出代码。 在bash手册页中: 设置-e: 如果管道(可能由一个简单命令组成),列表或复合命令(请参见上面的SHELL GRAMMAR)以非零状态退出,则立即退出。 如果失败的命令是一会儿或直到关键字之后紧随其后的命令列表的一部分,if或elif保留字之后的部分测试,以及在&&或||中执行的任何命令的一部分,则外壳程序不会退出。 列出最后一个&&或||之后的命令,管道中除最后一个命令之外的任何命令,或者该命令的返回值用!反转。 如果除子Shell之外的复合命令由于在-e被忽略时命令失败而返回非零状态,则该Shell不会退出。 在退出外壳程序之前,将执行ERR上的陷阱(如果已设置
  • 使用简单构建工具(sbt)和IntelliJ调试Scala代码(Debugging Scala code with simple-build-tool (sbt) and IntelliJ)
    问题 使用IntelliJ的内置调试器调试由sbt管理的Scala代码的最简单方法是什么? sbt的Google代码站点的“ RunningSbt”文档列出了用于运行项目或测试的主类的命令,但似乎没有用于调试的命令。 后续问题:使用sbt的jetty-run命令时,将IntelliJ调试器附加到Jetty的最简单方法是什么? 回答1 对于IntelliJ中的常规调试,无论是否使用sbt编译代码,都可以按常规方式使用应用程序运行/调试配置。 要连接到在Jetty中运行的应用程序,您需要创建一个远程调试配置。 当您这样做时,IntelliJ将为您提供一组用于运行远程JVM的命令行参数-类似 -Xdebug -Xrunjdwp:transport = dt_socket,server = y,suspend = n,address = 5005 使用这些参数启动sbt,然后执行jetty-run 。 最后,在IntelliJ中启动您的远程调试配置。 该线程可能有用。 回答2 Mac,Linux和Windows的官方SBT软件包中有一个非常方便的-jvm-debug标志。 您可以使用该标志来指定调试端口: sbt -jvm-debug 5005 在幕后,这会以典型的冗长的调试方式启动JVM for SBT: -Xdebug -Xrunjdwp:transport=dt_socket
  • 如何在Vim中复制到剪贴板?(How to copy to clipboard in Vim?)
    问题 是否可以直接从Vim复制到剪贴板? yy仅将内容复制到Vim的内部缓冲区。 我想复制到操作系统的剪贴板。 Vim中是否有这样的命令,或者您只能在Vim中提取内容? 回答1 *寄存器将执行此操作。 在Windows中, +和*是等效的。 在unix中, +和*之间有细微的差别: 在Windows下,*和+寄存器是等效的。 但是,对于X11系统,它们有所不同。 对于X11系统,*是选择项,而+是剪切缓冲区(如剪贴板)。 http://vim.wikia.com/wiki/Accessing_the_system_clipboard *可能是您大多数时候想要的,所以我使用*因为它在两种环境下都能发挥预期的功能。 在Linux发行版中,您必须先安装vim-gtk (aka gvim )才能获得剪贴板功能。 这是因为非gtk vim通常在没有X11支持的情况下进行编译。 这是为了使其能够在仅控制台计算机(通常是服务器)上运行。 对于那些对于在拉动或放置时如何使用寄存器感到困惑的人,您只需要写"然后是寄存器的名称。因此,要将某些内容复制到剪贴板寄存器中,请键入"*y ,然后键入"*p (贷记:凯尔·马修斯(Kyle Mathews) 回答2 在Mac OSX上 复制选定的部分:直观地选择文本(在正常模式下键入v或V ),然后键入:w !pbcopy 复制整个文件:%w !pbcopy
  • 是否在Bash中运行了最后一个命令?(Echoing the last command run in Bash?)
    问题 我试图回显在bash脚本中运行的最后一个命令。 我找到了一种处理某些history,tail,head,sed ,当从解析器的角度来看命令在我的脚本中代表特定行时,这种方法可以很好地工作。 但是在某些情况下,例如在将命令插入到case语句中时,我不会获得预期的输出: 剧本: #!/bin/bash set -o history date last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //') echo "last command is [$last]" case "1" in "1") date last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //') echo "last command is [$last]" ;; esac 输出: Tue May 24 12:36:04 CEST 2011 last command is [date] Tue May 24 12:36:04 CEST 2011 last command is [echo "last command is [$last]"] [Q]有人可以帮助我找到一种方法来回显上次运行的命令,而不管该命令在bash脚本中的调用方式/位置如何? 我的答案
  • 如果命令失败如何退出? [复制](How to exit if a command failed? [duplicate])
    问题 这个问题已经在这里有了答案: 如果有任何命令返回非零值,则中止shell脚本(9个答案) 5天前关闭。 我是shell脚本方面的菜鸟。 如果命令失败,我想打印一条消息并退出脚本。 我试过了: my_command && (echo 'my_command failed; exit) 但它不起作用。 它会继续执行脚本中此行之后的指令。 我正在使用Ubuntu和bash。 回答1 尝试: my_command || { echo 'my_command failed' ; exit 1; } 四个变化: 将&&更改为|| 用{ }代替( ) 介绍; exit后 {之后和}之前的空格 由于您要打印消息并仅在命令失败时退出(以非零值退出),因此需要|| 不是&& 。 cmd1 && cmd2 将在cmd1成功(退出值0 )时运行cmd2 。 然而 cmd1 || cmd2 当cmd1失败(退出值非零)时将运行cmd2 。 使用( )可以使其中的命令在子外壳中运行,并从那里调用exit会导致您退出该子外壳,而不是原始外壳,因此在原始外壳中继续执行。 要克服这种情况,请使用{ } bash需要最后两个更改。 回答2 其他答案很好地解决了直接问题,但您可能也对使用set -e感兴趣。 这样,任何失败的命令(在特定上下文之外,例如if测试)都将导致脚本中止。 对于某些脚本,它非常有用。
  • Bash中的错误处理(Error handling in Bash)
    问题 您最喜欢Bash处理错误的方法是什么? 我在网上发现的处理错误的最好例子是由William Shotts,Jr在http://www.linuxcommand.org上编写的。 他建议使用以下函数在Bash中进行错误处理: #!/bin/bash # A slicker error handling routine # I put a variable in my scripts named PROGNAME which # holds the name of the program being run. You can get this # value from the first item on the command line ($0). # Reference: This was copied from <http://www.linuxcommand.org/wss0150.php> PROGNAME=$(basename $0) function error_exit { # ---------------------------------------------------------------- # Function for exit due to fatal program error # Accepts 1 argument: # string
  • Execute Shell如何/何时在Jenkins中将构建标记为失败?(How/When does Execute Shell mark a build as failure in Jenkins?)
    问题 我在寻找答案时发现的恐怖故事... 好的,我有一个.sh脚本,它几乎完成了詹金斯应该做的所有事情: 从SVN检出源建立项目部署项目自己清洗 因此,在Jenkins中,我只需要通过在Execute Shell命令中运行脚本来“构建”项目。 脚本已运行(下载了源代码,项目正在构建/部署中),但随后将构建标记为失败:生成步骤'Execute shell'将构建标记为失败,即使脚本已成功运行! 我尝试用以下命令关闭脚本: 退出0(仍将其标记为失败) 出口1(按预期将其标记为失败) 完全没有退出命令(将其标记为失败) Execute Shell何时,如何以及为什么将我的构建标记为失败? 回答1 首先,将鼠标悬停在下面的灰色区域上。 这不是答案的一部分,但绝对必须说: 如果您有一个shell脚本自己单独执行“签出,构建,部署”,那么为什么要使用Jenkins? 您将继承詹金斯的所有功能,使其成为现实。 您可能还需要cron或SVN提交后钩子,直接调用该脚本。 詹金斯(Jenkins)执行SVN结帐本身至关重要。 它允许仅在有更改时(或按计时器或手动(如果您愿意))触发构建。 它跟踪构建之间的更改。 它显示了这些更改,因此您可以查看哪个构建适用于哪些更改集。 当提交者的更改导致成功或失败的构建时,它将通过电子邮件发送给提交者(同样,根据您的喜好进行配置)。 当他们的修复修复了失败的构建时
  • Remote debugging won't stop at breakpoints
    I'm having a problem with xdebug not stopping at breakpoints when using remote debugging (everything is fine when running scripts via the command line). It will break at the first line of the program, then exit, not catching any breakpoints. It used to work fine, until I switched over to using MacPorts for Apache and PHP. I've tried re-compiling it several times (with several versions), but no dice. I'm using PHP 5.3.1 and Xdebug 2.1.0-beta3 I've also tried at least 3 different debugging programs (MacGDBp, Netbeans and JetBrains Web IDE). My php.ini settings look like: [xdebug] xdebug.remote
  • 两种几乎完全相同的批处理脚本之一中的语法错误:“)”不能在此处进行语法处理(Syntax error in one of two almost-identical batch scripts: “)” cannot be processed syntactically here)
    问题 我正在尝试为自动Unity构建设置Jenkins服务器。 因此,我写了两个(在我看来)基本相同的批处理脚本。 Jenkins通过使用以下Execute Windows batch command的“ Execute Windows batch command步骤,将这两个脚本作为构建步骤运行 命令: E:\unityImport.bat 然后Execute Windows batch command第二个Execute Windows batch command步骤,使用 命令: E:\unityBuild.bat 两者的开始都是一样的,因为我需要收集一些文件路径,尤其是项目的统一版本。 因此,在两个脚本中,我都使用完全相同的方式来解析和字符串拆分项目版本。 它们之间唯一的不同是,第一个启动Unity并将专用的unitypackage (保存在下一步执行的方法)导入到项目中,而第二个再次启动Unity执行实际的构建(不幸的是,它一次都没用... Unity似乎尝试在导入unitypackage之前执行该方法)。 但是,第二个脚本始终会因语法错误而失败 此处不能在句法上处理“)”。 我试图实现的是 读出文件%WORKSPACE%\ProjectSettings\ProjectVersion.txt SET /p TEST=<%WORKSPACE%\ProjectSettings