从阅读this thread开始,看起来可以使用shebang来运行Rust *。
#!/usr/bin/env rustc
fn main() {
println!("Hello World!");
}
使这个可执行文件运行并编译,但不运行代码。
chmod +x hello_world.rs
./hello_world.rs
但是,这只会将代码编译为hello_world
。
可以直接执行*.rs
个文件,类似于shell脚本吗?
*这引用了rustx,我调查了这个,但它是一个bash脚本,每次都编译脚本(没有缓存)并且永远不会从temp目录中删除文件,尽管这可以改进。它也有很大的局限性,它不能使用板条箱。
答案 0 :(得分:14)
有cargo-script
。这也允许你使用依赖。
通过cargo-script
安装cargo install cargo-script
后,您可以创建脚本文件(hello.rs
),如下所示:
#!/usr/bin/env run-cargo-script
fn main() {
println!("Hello World!");
}
要执行它,您需要:
$ chmod +x hello.rs
$ ./hello.rs
Compiling hello v0.1.0 (file://~/.cargo/.cargo/script-cache/file-hello-d746fc676c0590b)
Finished release [optimized] target(s) in 0.80 secs
Hello World!
要使用crates.io中的crates,请参阅上面链接的README中的教程。
答案 1 :(得分:1)
这似乎有效:
#!/bin/sh
//usr/bin/env rustc $0 -o a.out && ./a.out && rm ./a.out ; exit
fn main() {
println!("Hello World!");
}
答案 2 :(得分:0)
我为此专门编写了一个工具:Scriptisto。这是一个完全与语言无关的工具,可与其他编译语言或具有昂贵验证步骤的语言(带有mypy的Python)一起使用。
对于Rust,它也可以在后台获取dependencies或完全在Docker中构建,而无需安装Rust编译器。 scriptisto
将这些模板嵌入二进制文件中,以便您轻松引导:
$ scriptisto new rust > ./script.rs
$ chmod +x ./script.rs
$ ./script.rs
您可以执行new rust
而不是new docker-rust
,并且该构建不需要主机系统上的Rust编译器。
答案 3 :(得分:0)
#!/bin/sh
#![allow()] /*
exec cargo-play --cached --release $0 -- "$@"
*/
需要货运。您可以看到不需要任何here的解决方案:
#!/bin/sh
#![allow()] /*
# rust self-compiler by Mahmoud Al-Qudsi, Copyright NeoSmart Technologies 2020
# See <https://neosmart.net/blog/self-compiling-rust-code/> for info & updates.
#
# This code is freely released to the public domain. In case a public domain
# license is insufficient for your legal department, this code is also licensed
# under the MIT license.
# Get an output path that is derived from the complete path to this self script.
# - `realpath` makes sure if you have two separate `script.rs` files in two
# different directories, they get mapped to different binaries.
# - `which` makes that work even if you store this script in $PATH and execute
# it by its filename alone.
# - `cut` is used to print only the hash and not the filename, which `md5sum`
# always includes in its output.
OUT=/tmp/$(printf "%s" $(realpath $(which "$0")) | md5sum | cut -d' ' -f1)
# Calculate hash of the current contents of the script, so we can avoid
# recompiling if it hasn't changed.
MD5=$(md5sum "$0" | cut -d' ' -f1)
# Check if we have a previously compiled output for this exact source code.
if !(test -f "${OUT}.md5" && test "${MD5}" = "$(cat ${OUT}.md5)"); then
# The script has been modified or is otherwise not cached.
# Check if the script already contains an `fn main()` entry point.
if grep -Eq '^\s*(\[.*?\])*\s*fn\s*main\b*' "$0"; then
# Compile the input script as-is to the previously determined location.
rustc "$0" -o ${OUT}
# Save rustc's exit code so we can compare against it later.
RUSTC_STATUS=$?
else
# The script does not contain an `fn main()` entry point, so add one.
# We don't use `printf 'fn main() { %s }' because the shebang must
# come at the beginning of the line, and we don't use `tail` to skip
# it because that would result in incorrect line numbers in any errors
# reported by rustc, instead we just comment out the shebang but leave
# it on the same line as `fn main() {`.
printf "fn main() {//%s\n}" "$(cat $0)" | rustc - -o ${OUT}
# Save rustc's exit code so we can compare against it later.
RUSTC_STATUS=$?
fi
# Check if we compiled the script OK, or exit bubbling up the return code.
if test "${RUSTC_STATUS}" -ne 0; then
exit ${RUSTC_STATUS}
fi
# Save the MD5 of the current version of the script so we can compare
# against it next time.
printf "%s" ${MD5} > ${OUT}.md5
fi
# Execute the compiled output. This also ends execution of the shell script,
# as it actually replaces its process with ours; see exec(3) for more on this.
exec ${OUT} $@
# At this point, it's OK to write raw rust code as the shell interpreter
# never gets this far. But we're actually still in the rust comment we opened
# on line 2, so close that: */