[筆記] How `bun ./script.sh` works
在逛 FB 的時候看到[這篇](https://www.facebook.com/huli.blog/posts/550887134138158)
裡面提到:
> 此時有人說了句:「bun 可以執行 sh」
> 才發現原來 JavaScript 只是假象 😂
> 總之呢,這題看似是 JavaScript,但因為 bun 獨樹一格的行為(明明是個 JavaScript runtime,卻支援 bun test.sh)變成了 sh jail,十分有趣
但翻 docs 沒看到這個說明 所以 trace 了一下 code 來了解它怎麼做的
## trace
[src/cli.zig#L1564](https://github.com/oven-sh/bun/blob/main/src/cli.zig#L1564)
```
pub const Command = struct {
fn start() {
const tag = which(); // AutoCommand
```
第一個參數不是特定 command 的狀況下 會進到 `AutoCommand` ([src/cli.zig#L1918-L2061](https://github.com/oven-sh/bun/blob/main/src/cli.zig#L1918-L2061))
其中裡面的判斷式如下:
[src/cli.zig#L1990-L1992](https://github.com/oven-sh/bun/blob/main/src/cli.zig#L1990-L1992)
```
if (strings.endsWithComptime(ctx.args.entry_points[0], ".sh")) {
break :brk options.Loader.bunsh;
}
```
所以如果檔名是 `.sh` 結尾 就會用 `bunsh` 這個 loader 來處理
[src/cli.zig#L2008-L2010](https://github.com/oven-sh/bun/blob/main/src/cli.zig#L2008-L2010)
```
if (loader.canBeRunByBun()) {
was_js_like = true;
if (maybeOpenWithBunJS(ctx)) {
```
檢查能不能用 bun 執行 如果可以就給他跑 ([canBeRunByBun 的實作](https://github.com/oven-sh/bun/blob/main/src/options.zig#L713-L718))
[src/cli.zig#L2143](https://github.com/oven-sh/bun/blob/main/src/cli.zig#L2143)
`maybeOpenWithBunJS` 做一些處理後就會丟給 `BunJS.Run.root` 執行
[src/bun_js.zig#L180-L181](https://github.com/oven-sh/bun/blob/main/src/bun_js.zig#L180-L181)
```
pub fn boot(ctx: Command.Context, entry_path: string) !void {
// ...
// The shell does not need to initialize JSC.
// JSC initialization costs 1-3ms. We skip this if we know it's a shell script.
if (strings.endsWithComptime(entry_path, ".sh")) {
const exit_code = try bootBunShell(ctx, entry_path);
```
`BunJS.Run.root` 裡面 call `bootBunShell`
[src/bun_js.zig#L168](https://github.com/oven-sh/bun/blob/main/src/bun_js.zig#L168)
```
fn bootBunShell {
// ...
return bun.shell.Interpreter.initAndRunFromFile(ctx, mini, entry_path);
```
最終透過 `bun.shell.Interpreter.initAndRunFromFile` ([src/shell/interpreter.zig#L1434](https://github.com/oven-sh/bun/blob/main/src/shell/interpreter.zig#L1434)) 執行 bun shell
p.s.
後面才查到其實在 bun 文件裡面有 (https://bun.sh/docs/bundler/loaders#sh-loader)
實際上他其實是 [bun shell](https://bun.sh/docs/runtime/shell) 語法 而不是平常用的 sh XD
2024-09-28 02:08:26
留言
Last fetch: --:--
現在還沒有留言!