buninu-linux 0.8.55 → 0.9.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +46 -46
- package/README.md +7 -6
- package/initramfs/bin/tar +34 -46
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +103 -0
- package/initramfs/buninu/apps/bunmsh/PORTING.md +133 -15
- package/initramfs/buninu/apps/bunmsh/help/awk.md +38 -0
- package/initramfs/buninu/apps/bunmsh/help/break.md +21 -0
- package/initramfs/buninu/apps/bunmsh/help/chmod.md +8 -2
- package/initramfs/buninu/apps/bunmsh/help/cmp.md +29 -0
- package/initramfs/buninu/apps/bunmsh/help/continue.md +22 -0
- package/initramfs/buninu/apps/bunmsh/help/cp.md +4 -0
- package/initramfs/buninu/apps/bunmsh/help/diff.md +30 -0
- package/initramfs/buninu/apps/bunmsh/help/egrep.md +26 -0
- package/initramfs/buninu/apps/bunmsh/help/export.md +2 -2
- package/initramfs/buninu/apps/bunmsh/help/expr.md +30 -0
- package/initramfs/buninu/apps/bunmsh/help/fgrep.md +25 -0
- package/initramfs/buninu/apps/bunmsh/help/grep.md +4 -0
- package/initramfs/buninu/apps/bunmsh/help/ls.md +4 -2
- package/initramfs/buninu/apps/bunmsh/help/mkdir.md +1 -1
- package/initramfs/buninu/apps/bunmsh/help/print.md +3 -0
- package/initramfs/buninu/apps/bunmsh/help/return.md +23 -0
- package/initramfs/buninu/apps/bunmsh/help/sed.md +8 -3
- package/initramfs/buninu/apps/bunmsh/help/set.md +12 -3
- package/initramfs/buninu/apps/bunmsh/help/tr.md +4 -0
- package/initramfs/buninu/apps/bunmsh/help/trap.md +22 -0
- package/initramfs/buninu/apps/bunmsh/help/uniq.md +27 -0
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/awk.js +203 -0
- package/initramfs/buninu/apps/bunmsh/src/diff.js +222 -0
- package/initramfs/buninu/apps/bunmsh/src/fancy-ls.js +15 -4
- package/initramfs/buninu/apps/bunmsh/src/main.js +21 -5
- package/initramfs/buninu/apps/bunmsh/src/sed.js +159 -0
- package/initramfs/buninu/apps/bunmsh/src/shell.js +1283 -540
- package/initramfs/buninu/apps/bunmsh/test/awk-reference.test.js +35 -0
- package/initramfs/buninu/apps/bunmsh/test/awk.test.js +62 -0
- package/initramfs/buninu/apps/bunmsh/test/posix-bootstrap.test.js +595 -0
- package/initramfs/buninu/apps/bunmsh/test/utility-reference-cases.mjs +98 -0
- package/initramfs/buninu/apps/bunmsh/test/utility-reference.test.js +23 -0
- package/initramfs/buninu/apps/jsgotty/client-kitty.mjs +61 -0
- package/initramfs/buninu/apps/jsgotty/client.mjs +16 -0
- package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
- package/initramfs/buninu/apps/jsgotty/package.json +1 -1
- package/initramfs/buninu/apps/jsgotty/tests/client-kitty.test.mjs +43 -0
- package/initramfs/etc/resolv.conf +2 -1
- package/initramfs/usr/share/doc/buninu-linux/tar.md +12 -1
- package/package.json +1 -1
- package/scripts/arch.js +5 -5
- package/scripts/arch.sh +5 -5
- package/scripts/fetch.js +2 -0
- package/scripts/npm-packages.md +4 -3
- package/test/fetch-npm.test.js +1 -1
- package/test/tar-strip.test.js +36 -0
package/NOTICE.md
CHANGED
|
@@ -105,83 +105,83 @@ the built image redistributes them.
|
|
|
105
105
|
- License: GPL-2.0-only WITH Linux-syscall-note
|
|
106
106
|
- See: `LICENSES/GPL-2.0.txt` and `LICENSES/Linux-syscall-note.txt`
|
|
107
107
|
|
|
108
|
-
Linux 6.18.
|
|
109
|
-
The default build uses package `linux-virt`, version 6.18.
|
|
110
|
-
`--linux-lts` and `--real` use package `linux-lts`, version 6.18.
|
|
108
|
+
Linux 6.18.56 as packaged by Alpine Linux 3.24 from the `linux-lts` aport.
|
|
109
|
+
The default build uses package `linux-virt`, version 6.18.56-r0.
|
|
110
|
+
`--linux-lts` and `--real` use package `linux-lts`, version 6.18.56-r0.
|
|
111
111
|
Each comes from the x86_64 or aarch64 repository to match `--arch`. All
|
|
112
112
|
listed modules are the selected package's `.ko.gz` files decompressed without
|
|
113
113
|
modification.
|
|
114
114
|
|
|
115
|
-
- Upstream source: https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.
|
|
115
|
+
- Upstream source: https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.56.tar.xz
|
|
116
116
|
- Alpine build recipe, configuration and patches (Corresponding Source),
|
|
117
|
-
pinned to the commit shipping 6.18.
|
|
118
|
-
https://gitlab.alpinelinux.org/alpine/aports/-/blob/
|
|
117
|
+
pinned to the commit shipping 6.18.56-r0 (the same for both architectures):
|
|
118
|
+
https://gitlab.alpinelinux.org/alpine/aports/-/blob/efc8ddbb20c827d2bd8223c19a2625e754e5cb3c/main/linux-lts/APKBUILD
|
|
119
119
|
- Packages:
|
|
120
|
-
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/x86_64/linux-virt-6.18.
|
|
121
|
-
SHA-256 `
|
|
122
|
-
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/x86_64/linux-lts-6.18.
|
|
123
|
-
SHA-256 `
|
|
124
|
-
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/aarch64/linux-virt-6.18.
|
|
125
|
-
SHA-256 `
|
|
126
|
-
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/aarch64/linux-lts-6.18.
|
|
127
|
-
SHA-256 `
|
|
120
|
+
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/x86_64/linux-virt-6.18.56-r0.apk
|
|
121
|
+
SHA-256 `755deb045cfeb8c2bcaa2b2febe01ab2101d747921e64d4cd54d0312321e8d5d`
|
|
122
|
+
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/x86_64/linux-lts-6.18.56-r0.apk
|
|
123
|
+
SHA-256 `b0d8cc4d7e031b5619221e7978920d051bf1dd1e335f6d05d03964b2285fc3b4`
|
|
124
|
+
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/aarch64/linux-virt-6.18.56-r0.apk
|
|
125
|
+
SHA-256 `e3839bfd751ff0a4421484f712b9b29efb514024523736a0ef62521521571b12`
|
|
126
|
+
https://dl-cdn.alpinelinux.org/alpine/v3.24/main/aarch64/linux-lts-6.18.56-r0.apk
|
|
127
|
+
SHA-256 `795bcd49840be7f4ff9566f5f669201bd41202376a455b720a98eb814f0e72f8`
|
|
128
128
|
|
|
129
129
|
SHA-256 of files in the default x86_64 `linux-virt` image:
|
|
130
130
|
|
|
131
131
|
```text
|
|
132
|
-
kernel/x86_64/vmlinuz-virt
|
|
133
|
-
failover.ko
|
|
134
|
-
net_failover.ko
|
|
135
|
-
virtio_net.ko
|
|
132
|
+
kernel/x86_64/vmlinuz-virt dc99c86bb8e58cb4eda5f01eac44c4d972105945a46dfe76a9e86e8529915c72
|
|
133
|
+
failover.ko ddf94fe8a89b24e839f21866f828adc3eb91e62fa46dd977c74d7c2b6f92fe21
|
|
134
|
+
net_failover.ko fb710ef0450417dea2f6dede919d14f5a4a94b1be73f338cfe2ed05e32f0cc30
|
|
135
|
+
virtio_net.ko 2fb98ab7d06cfb7a1e1a07dcc5098da44316360097d75e288a30ad4855c449f7
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
SHA-256 of files in an x86_64 `--linux-lts` image:
|
|
139
139
|
|
|
140
140
|
```text
|
|
141
|
-
kernel/x86_64/vmlinuz-lts
|
|
142
|
-
failover.ko
|
|
143
|
-
net_failover.ko
|
|
144
|
-
virtio_net.ko
|
|
145
|
-
virtio_ring.ko
|
|
146
|
-
virtio.ko
|
|
147
|
-
virtio_pci_legacy_dev.ko
|
|
148
|
-
virtio_pci_modern_dev.ko
|
|
149
|
-
virtio_pci.ko
|
|
141
|
+
kernel/x86_64/vmlinuz-lts e893ce0f7aecbdf2dcf012659ec5a0b35740780ae5c3af5ad188029f5cd4aa8f
|
|
142
|
+
failover.ko 59e4e4808dca2d18d849c2da850e4ea659485007b09a690c7e57fb0e623cd1df
|
|
143
|
+
net_failover.ko 20dd06a6f6f1528079a438630d741f125d11cc9bae58d618e0e6381f8bff6f5c
|
|
144
|
+
virtio_net.ko 39bcd12bfc3149351fa226dabdbb1f82137c53f3b1ccbacbf30661bf8ff99ad4
|
|
145
|
+
virtio_ring.ko e8fdebd89345ef39a54d3b23e6f2a57c6c4b201708b35113705b56d0fa373596
|
|
146
|
+
virtio.ko d4ab148e31f5d4d5a1dd3c3f30bb52ba9a13e670929c9f7f1668396edf8049b7
|
|
147
|
+
virtio_pci_legacy_dev.ko 15c35c8875b68dcaed3ac58d463d1b3f2c3e52dcf9a3840366d3fa6da7cd4dd7
|
|
148
|
+
virtio_pci_modern_dev.ko 59bd6e34e6cf3c0ce54bab1eca1d7ac0325112280a6718613460002d2cde70d0
|
|
149
|
+
virtio_pci.ko cc3ad8eaffa321bd58dbd663afba074dee81a5ad6f283d50cd5b1b340672430e
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
`--real` additionally includes the following modules from that same
|
|
153
153
|
x86_64 `linux-lts` package for physical xHCI controllers and USB HID keyboards:
|
|
154
154
|
|
|
155
155
|
```text
|
|
156
|
-
usb-common.ko
|
|
157
|
-
usbcore.ko
|
|
158
|
-
xhci-hcd.ko
|
|
159
|
-
xhci-pci.ko
|
|
160
|
-
xhci-pci-renesas.ko
|
|
161
|
-
hid.ko
|
|
162
|
-
hid-generic.ko
|
|
163
|
-
usbhid.ko
|
|
156
|
+
usb-common.ko 37feaa14670d4bbd3dca77d701344d2fb02e2cb139d21c5af8b2c140aab5c6fe
|
|
157
|
+
usbcore.ko 75efddfd7d1bf996ad99f0d9be790be767ca72ebdb53a00194b449c3588faa16
|
|
158
|
+
xhci-hcd.ko bd5772b2ba908dff16c74ae10211a1e5cfd72910d861dbdf30b8f71c5995066a
|
|
159
|
+
xhci-pci.ko 6c688038c9b45297fce752c8f0443cd0f398f31e0b4efffd7f869325ce9884fa
|
|
160
|
+
xhci-pci-renesas.ko aa08808c9e609fe570a1c5b90d0f0ba33f2ca2e7d84e8ccbb3a2856fe65a7b3f
|
|
161
|
+
hid.ko 161160bf12d18a24c25aef6355e265142fc4fb2122b09923a6e184fabedf6246
|
|
162
|
+
hid-generic.ko 6d5ae3cfd8f8b034cbe444869485ac9012376c4ca604a3cd039f0cae442005f9
|
|
163
|
+
usbhid.ko 6ed1e4891b242f64520621d689a24828dfc24a96236c71b86d9af9361248aa5a
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
SHA-256 of files in the default aarch64 `linux-virt` image:
|
|
167
167
|
|
|
168
168
|
```text
|
|
169
|
-
kernel/aarch64/vmlinuz-virt
|
|
170
|
-
failover.ko
|
|
171
|
-
net_failover.ko
|
|
172
|
-
virtio_net.ko
|
|
169
|
+
kernel/aarch64/vmlinuz-virt 039c532c2fa8f49896a679065d79a03b8a444c9d54fa80ac9bc4d0ce1ecd0ca6
|
|
170
|
+
failover.ko ce65a98acce98720753c4a9a7e339f6c70d22eae70b65cc1b4211543a7c6c3a3
|
|
171
|
+
net_failover.ko 39c9222d800ae95d8a82ff797e408187411ac2ff47bec2c9d7ddbfe99537dbe3
|
|
172
|
+
virtio_net.ko 762f8e362ae2e2bbf200ab9bc742524999e8bce12c72671bf8560fd9bb7907d5
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
SHA-256 of files in an aarch64 `--linux-lts` image:
|
|
176
176
|
|
|
177
177
|
```text
|
|
178
|
-
kernel/aarch64/vmlinuz-lts
|
|
179
|
-
failover.ko
|
|
180
|
-
net_failover.ko
|
|
181
|
-
virtio_net.ko
|
|
182
|
-
virtio_pci_legacy_dev.ko
|
|
183
|
-
virtio_pci_modern_dev.ko
|
|
184
|
-
virtio_pci.ko
|
|
178
|
+
kernel/aarch64/vmlinuz-lts de5ff95fd663a30e53765cb0794707656bb80749d77f16bbf94225d17c512447
|
|
179
|
+
failover.ko 7f3d40067603c9916d22e9d85fea1512bd95c087aaae774e5ea70f8bacb7ae04
|
|
180
|
+
net_failover.ko 085e4fd53a40704408b6bf914ee464d16007296fa3615940fa54688afe84466c
|
|
181
|
+
virtio_net.ko 4ea86521819063df91cfd18191e8bc2bd2551392e8f7a33126df0aba675ee409
|
|
182
|
+
virtio_pci_legacy_dev.ko baf8033c183819a8bccacf36677247740a5cff9eec9b403b94840af258b60b6e
|
|
183
|
+
virtio_pci_modern_dev.ko 2905133de7c9baceff9fc6a27dba9b8469744019545c19cf1456e64f7e50f062
|
|
184
|
+
virtio_pci.ko 3b506947c25866e08a311f124cd143bd0f501179f0b556aed7ca4d6632143d8d
|
|
185
185
|
```
|
|
186
186
|
|
|
187
187
|
### linuxx64.efi.stub and linuxaa64.efi.stub
|
package/README.md
CHANGED
|
@@ -1112,7 +1112,7 @@ initramfs/ init.js, commands, userspace: the same for every archi
|
|
|
1112
1112
|
native/<arch>/ musl and the GCC runtime (committed); bun and modules (fetched)
|
|
1113
1113
|
```
|
|
1114
1114
|
|
|
1115
|
-
The `--real` inputs are Alpine v3.24 `linux-lts-6.18.
|
|
1115
|
+
The `--real` inputs are Alpine v3.24 `linux-lts-6.18.56-r0`, musl `1.2.6-r2`,
|
|
1116
1116
|
`systemd-efistub-260.2-r0`, `libstdc++`/`libgcc` `15.2.0-r5`, and Bun 1.4.2
|
|
1117
1117
|
`linux-x64-musl-baseline`. The aarch64 guest uses the same versions from
|
|
1118
1118
|
Alpine's aarch64 repository and Bun's `linux-aarch64-musl`. There is no BusyBox
|
|
@@ -1127,10 +1127,11 @@ extracts from it. Bumping a version changes both the file name and the hash, so
|
|
|
1127
1127
|
it always refetches.
|
|
1128
1128
|
|
|
1129
1129
|
The four application packages are pinned separately in
|
|
1130
|
-
`scripts/npm-packages.md`: `buninu-browser@0.2.
|
|
1130
|
+
`scripts/npm-packages.md`: `buninu-browser@0.2.3`,
|
|
1131
1131
|
`@drxiaozhi/casty@1.3.4`, `@drxiaozhi/jspulse@0.2.1`, and
|
|
1132
1132
|
`@drxiaozhi/jspinyin@0.1.1`. These were npm's `latest` versions when checked
|
|
1133
|
-
on 2026-10-11
|
|
1133
|
+
on 2026-10-11, with buninu-browser updated to npm's `latest` on 2026-10-12;
|
|
1134
|
+
fetch never resolves `latest` or a version range at runtime.
|
|
1134
1135
|
Each registry tarball was checked against its published SHA-512 integrity
|
|
1135
1136
|
before its SHA-256 was recorded in the shared pins file.
|
|
1136
1137
|
|
|
@@ -1274,7 +1275,7 @@ The physical boot chain is firmware → the UKI stub → its embedded
|
|
|
1274
1275
|
and, with the currently pinned kernel, embeds this complete command line:
|
|
1275
1276
|
|
|
1276
1277
|
```text
|
|
1277
|
-
console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.
|
|
1278
|
+
console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.56-0-lts rdinit=/bin/bun -- -e import('/init.js')
|
|
1278
1279
|
```
|
|
1279
1280
|
|
|
1280
1281
|
Serial kernel logging is retained, while the final console makes
|
|
@@ -1298,7 +1299,7 @@ the same way). Build without `--real`; this selects Alpine `linux-virt`, omits t
|
|
|
1298
1299
|
module set, and puts `ttyS0` last so serial stdio owns `/dev/console`:
|
|
1299
1300
|
|
|
1300
1301
|
```text
|
|
1301
|
-
console=tty0 console=ttyS0,115200 panic=0 PATH=/bin KERNEL_RELEASE=6.18.
|
|
1302
|
+
console=tty0 console=ttyS0,115200 panic=0 PATH=/bin KERNEL_RELEASE=6.18.56-0-virt rdinit=/bin/bun -- -e import('/init.js')
|
|
1302
1303
|
```
|
|
1303
1304
|
|
|
1304
1305
|
Build and boot it with:
|
|
@@ -1415,7 +1416,7 @@ The default `--real` image embeds this kernel command line (shown for the
|
|
|
1415
1416
|
currently pinned LTS release):
|
|
1416
1417
|
|
|
1417
1418
|
```text
|
|
1418
|
-
console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.
|
|
1419
|
+
console=ttyS0,115200 console=tty0 REAL_MACHINE=1 panic=0 PATH=/bin KERNEL_RELEASE=6.18.56-0-lts rdinit=/bin/bun -- -e import('/init.js')
|
|
1419
1420
|
```
|
|
1420
1421
|
|
|
1421
1422
|
The physical display (`tty0`) is the final console and therefore owns PID 1's
|
package/initramfs/bin/tar
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/bin/bun
|
|
2
2
|
// tar — a small tar/gzip/zstd CLI over Bun.Archive.
|
|
3
3
|
|
|
4
|
+
import { gunzipSync } from "node:zlib";
|
|
4
5
|
import { lstat, readdir } from "node:fs/promises";
|
|
5
6
|
import { linkSync, mkdirSync, rmSync, symlinkSync } from "node:fs";
|
|
6
7
|
import { basename, dirname, join, resolve } from "node:path";
|
|
@@ -180,11 +181,20 @@ const scanEntries = (bytes) => {
|
|
|
180
181
|
let longName = null;
|
|
181
182
|
let longTarget = null;
|
|
182
183
|
let extended = {};
|
|
184
|
+
let ended = false;
|
|
185
|
+
entries.concatenated = false;
|
|
183
186
|
while (offset + BLOCK <= bytes.length) {
|
|
184
187
|
const block = bytes.subarray(offset, offset + BLOCK);
|
|
185
188
|
offset += BLOCK;
|
|
186
|
-
if (block.every((byte) => byte === 0))
|
|
189
|
+
if (block.every((byte) => byte === 0)) {
|
|
190
|
+
// APK v2 joins tar streams; another header may follow the end markers.
|
|
191
|
+
ended = true;
|
|
192
|
+
longName = longTarget = null;
|
|
193
|
+
extended = {};
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
187
196
|
if (!checksumMatches(block)) return entries.length ? entries : null;
|
|
197
|
+
if (ended) { entries.concatenated = true; ended = false; }
|
|
188
198
|
const flag = String.fromCharCode(block[156] || 0x30);
|
|
189
199
|
const size = extended.size !== undefined ? Number(extended.size) : octal(block, 124, 12);
|
|
190
200
|
const dataBlocks = Math.ceil(size / BLOCK) * BLOCK;
|
|
@@ -227,7 +237,7 @@ const scanEntries = (bytes) => {
|
|
|
227
237
|
};
|
|
228
238
|
|
|
229
239
|
const tarBytes = (bytes) => {
|
|
230
|
-
if (bytes[0] === 0x1f && bytes[1] === 0x8b) return
|
|
240
|
+
if (bytes[0] === 0x1f && bytes[1] === 0x8b) return gunzipSync(bytes);
|
|
231
241
|
if (bytes[0] === 0x28 && bytes[1] === 0xb5 && bytes[2] === 0x2f && bytes[3] === 0xfd) {
|
|
232
242
|
return Bun.zstdDecompressSync(bytes);
|
|
233
243
|
}
|
|
@@ -292,59 +302,37 @@ const restoreLinks = (entries) => {
|
|
|
292
302
|
}
|
|
293
303
|
};
|
|
294
304
|
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
// reinterpret literal metacharacters in retained archive names.
|
|
299
|
-
if (options.operation === "x" && (options.strip > 0 || options.excludes.length)) {
|
|
305
|
+
// Read stdin only once. node:zlib expands every concatenated gzip member
|
|
306
|
+
// (APK signature, control and data), rather than just the first stream.
|
|
307
|
+
if (options.operation === "x" || options.operation === "t") {
|
|
300
308
|
try {
|
|
301
309
|
const bytes = tarBytes(await archiveBytes());
|
|
302
|
-
const
|
|
303
|
-
if (!entries) throw new Error("invalid tar archive");
|
|
310
|
+
const scanned = scanEntries(bytes);
|
|
304
311
|
const wanted = options.operands.length ? patterns().map((pattern) => new Bun.Glob(pattern)) : null;
|
|
312
|
+
const useScannedExtraction = options.strip > 0 || options.excludes.length || scanned?.concatenated;
|
|
313
|
+
if (useScannedExtraction && !scanned) throw new Error("invalid tar archive");
|
|
314
|
+
// Bun.Archive stops at the first tar end marker. Use the existing scanned
|
|
315
|
+
// extractor when later streams contain more entries; ordinary tar files
|
|
316
|
+
// retain the Bun.Archive extraction path.
|
|
317
|
+
const archive = useScannedExtraction ? null : new Bun.Archive(bytes);
|
|
318
|
+
const entries = scanned ?? [...(await archive.files(options.operands.length ? patterns() : undefined))]
|
|
319
|
+
.map(([name, file]) => ({ name, kind: "file", target: "", size: file.size, mode: 0o644, mtime: file.lastModified }));
|
|
305
320
|
const members = entries.filter((entry) => !excluded(entry.name)
|
|
306
321
|
&& !(entry.kind === "hardlink" && excluded(entry.target))
|
|
307
322
|
&& (!wanted || wanted.some((glob) => glob.match(entry.name))));
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (options.operation === "x" || options.operation === "t") {
|
|
318
|
-
let archive;
|
|
319
|
-
try {
|
|
320
|
-
archive = new Bun.Archive(await archiveBytes());
|
|
321
|
-
} catch (error) {
|
|
322
|
-
fail(error?.message || String(error));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// The header scan is what makes listing and links complete; if the bytes
|
|
326
|
-
// do not parse as tar, fall back to what Bun.Archive reports.
|
|
327
|
-
const scanned = scanEntries(tarBytes(await archiveBytes()));
|
|
328
|
-
const wanted = options.operands.length ? patterns().map((pattern) => new Bun.Glob(pattern)) : null;
|
|
329
|
-
const members = scanned
|
|
330
|
-
? scanned.filter((entry) => !wanted || wanted.some((glob) => glob.match(entry.name)))
|
|
331
|
-
: [...(await archive.files(options.operands.length ? patterns() : undefined))]
|
|
332
|
-
.map(([name, file]) => ({ name, kind: "file", target: "", size: file.size, mode: 0o644, mtime: file.lastModified }));
|
|
333
|
-
|
|
334
|
-
if (options.operation === "t") {
|
|
335
|
-
for (const entry of members.filter((entry) => !excluded(entry.name))) {
|
|
336
|
-
console.log(options.verbose ? verboseListing(entry) : entry.name);
|
|
337
|
-
}
|
|
338
|
-
} else {
|
|
339
|
-
try {
|
|
340
|
-
if (options.verbose) {
|
|
341
|
-
for (const entry of members) console.log(entry.name);
|
|
342
|
-
}
|
|
323
|
+
if (options.operation === "t") {
|
|
324
|
+
for (const entry of members) console.log(options.verbose ? verboseListing(entry) : entry.name);
|
|
325
|
+
} else if (useScannedExtraction) {
|
|
326
|
+
extractStripped(bytes, members, options.directory, options.strip, {
|
|
327
|
+
verbose: options.verbose, filtered: options.operands.length > 0 || options.excludes.length > 0,
|
|
328
|
+
});
|
|
329
|
+
} else {
|
|
330
|
+
if (options.verbose) for (const entry of members) console.log(entry.name);
|
|
343
331
|
await archive.extract(options.directory, options.operands.length ? { glob: patterns() } : undefined);
|
|
344
332
|
restoreLinks(members);
|
|
345
|
-
} catch (error) {
|
|
346
|
-
fail(error?.message || String(error));
|
|
347
333
|
}
|
|
334
|
+
} catch (error) {
|
|
335
|
+
fail(error?.message || String(error));
|
|
348
336
|
}
|
|
349
337
|
process.exit(0);
|
|
350
338
|
}
|
|
@@ -2,6 +2,109 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-visible changes to bunmsh are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.4.0] - 2026-10-13
|
|
6
|
+
|
|
7
|
+
### Added and fixed
|
|
8
|
+
|
|
9
|
+
- Respect builtin cat output redirects in shell subprocesses, including AWK pipes.
|
|
10
|
+
|
|
11
|
+
- Stream external stdout/stderr to the correct pipeline endpoint for `2>&1`,
|
|
12
|
+
`2>&1 >file` and `1>&2`, retaining downstream early-close handling.
|
|
13
|
+
|
|
14
|
+
- Support `cp -p` for regular files, preserving ownership, mode and timestamps.
|
|
15
|
+
|
|
16
|
+
- Evaluate `!` inside if/elif conditions with normal pipeline precedence,
|
|
17
|
+
including conditions joined with `&&` or `||`.
|
|
18
|
+
|
|
19
|
+
- AWK supports parenthesized print lists, continued arguments and buffered
|
|
20
|
+
output command pipes through bunmsh. Correct function parameter scope and
|
|
21
|
+
preserve replacement backslashes; GCC option generators match mawk output.
|
|
22
|
+
|
|
23
|
+
- Process mkdir operands in order so parent/child paths do not race.
|
|
24
|
+
|
|
25
|
+
- Preserve here-document bodies when connecting commands to compound operands.
|
|
26
|
+
|
|
27
|
+
- Distinguish backquoted brace groups from parameter expansions during tokenization.
|
|
28
|
+
|
|
29
|
+
- Handle traditional set - as an option delimiter, preserving bare-call arguments.
|
|
30
|
+
|
|
31
|
+
- Add byte-preserving adjacent-line uniq with -c/-d/-u and input/output files.
|
|
32
|
+
- Ignore empty nonexistent filenames with rm -f, including libtool cleanup.
|
|
33
|
+
|
|
34
|
+
- Recognize case/esac next to subshell parentheses, including nested groups.
|
|
35
|
+
|
|
36
|
+
- Keep awk quoted operator strings as data, including install path concatenation.
|
|
37
|
+
|
|
38
|
+
- Remove the backquote escape layer before parsing command substitutions.
|
|
39
|
+
|
|
40
|
+
- Preserve short circuiting across comments before compounds and parse simple
|
|
41
|
+
pipeline stages before a trailing compound command.
|
|
42
|
+
|
|
43
|
+
- Keep persistent read descriptors open and consume one line without read-ahead.
|
|
44
|
+
- Expand positional parameter lengths such as libtool's ${#1}.
|
|
45
|
+
|
|
46
|
+
- Support explicit-class chmod rwxX modes such as a-w and u+rw.
|
|
47
|
+
|
|
48
|
+
- Recognize comments after else and loop-closing done as compound syntax.
|
|
49
|
+
|
|
50
|
+
- Apply enclosing descriptor redirects to compound-producer pipeline output.
|
|
51
|
+
|
|
52
|
+
- Add bytewise cmp, legacy egrep/fgrep names, and tr squeeze/delete combinations.
|
|
53
|
+
- Adapt mv/rm -- for Bun Shell while protecting option-looking filenames.
|
|
54
|
+
|
|
55
|
+
- Preserve multiline parameter expansion operands inside compound bodies.
|
|
56
|
+
- Accept combined print flags such as Autoconf's -rn.
|
|
57
|
+
- Preserve compound commands and function declarations after recipe continuations.
|
|
58
|
+
|
|
59
|
+
- Match quoted literals and bracket patterns in parameter prefix/suffix removal.
|
|
60
|
+
- Capture subshell state at execution time and scope its internal transport to
|
|
61
|
+
that command, preserving changes from earlier commands in the same list.
|
|
62
|
+
- Treat interior ^ and $ as literals in basic regular expressions, including
|
|
63
|
+
GNU make build.sh object-extension substitutions.
|
|
64
|
+
|
|
65
|
+
- Add a pure JavaScript awk fallback interpreter with fields, arrays, rules,
|
|
66
|
+
functions, loops, string/regex operations and file I/O. Input command pipes
|
|
67
|
+
and system() remain unsupported; full POSIX/GNU compatibility is not claimed.
|
|
68
|
+
- Preserve multiline quoted operands after compound pipeline connectors, quoted
|
|
69
|
+
backslash-newlines, heredoc AND/OR continuations, and case terminators after groups.
|
|
70
|
+
- Preserve ASCII control characters used as Autoconf awk separators during expansion.
|
|
71
|
+
- Keep nested redirected compound operands when reconstructing pipelines.
|
|
72
|
+
- Support sed r FILE, including end-of-cycle output and silently missing files.
|
|
73
|
+
|
|
74
|
+
- Add offline system diff/sed reference fixtures so isolated tests can compare
|
|
75
|
+
output and exit status without depending on host executables in the guest.
|
|
76
|
+
|
|
77
|
+
- Add file diff using the jsmdcui Myers line alignment, with separate insertion,
|
|
78
|
+
deletion and replacement hunks, binary notices and missing-final-newline markers.
|
|
79
|
+
- Expand parameters and substitutions inside arithmetic, including Autoconf `$(( $* ))`.
|
|
80
|
+
|
|
81
|
+
- In `set -o posix` mode, send only exported variables and command-prefix
|
|
82
|
+
assignments to external programs, while preserving complete internal state
|
|
83
|
+
for pipeline/subshell Bun children. Default mode still passes all variables.
|
|
84
|
+
- Match newlines with case wildcards, including Autoconf POSIX-mode detection.
|
|
85
|
+
- Keep heredoc contents out of subshell rewriting, support pipelines feeding
|
|
86
|
+
compound cases, accept operand-free rm -f, grep -e/-c, and sed -f.
|
|
87
|
+
|
|
88
|
+
- Track command source lines, preserve quotes and argument boundaries in selected
|
|
89
|
+
parameter operands, and parse nested compound conditions and subshell cases.
|
|
90
|
+
- Add expr and extend fallback sed with addresses, branches and hold-space edits.
|
|
91
|
+
- Make `set -o posix` an observable option: only this mode removes fallback ls
|
|
92
|
+
icons and implicit directory suffixes. Normal ls and lsfancy retain icons.
|
|
93
|
+
- Support ls inode/dereference options and sorting multiple file operands.
|
|
94
|
+
- Transport large internal subprocess state through a private temporary file;
|
|
95
|
+
retain the full function AST and clean up after foreground execution.
|
|
96
|
+
|
|
97
|
+
- Accept inline and next-line function braces, brace groups with redirects and
|
|
98
|
+
pipelines, multiline pipelines, and nested case clauses with here-documents.
|
|
99
|
+
- Implement return and counted break/continue with function/source/loop boundaries.
|
|
100
|
+
- Add persistent numeric fd bindings for exec, ordered duplication, scoped
|
|
101
|
+
restoration, and descriptor inheritance for external and subshell commands.
|
|
102
|
+
- Add conditional errexit, nounset/noglob, xtrace, option queries, EXIT handlers
|
|
103
|
+
and deferred signal traps. See PORTING.md for the remaining POSIX boundaries.
|
|
104
|
+
- Preserve the minimal background-command contract: original Bun.Subprocess
|
|
105
|
+
objects, append-only stable Bun.sha.procs indices, immediate return and unref;
|
|
106
|
+
no implicit waiting, killing or widening of accepted background syntax.
|
|
107
|
+
|
|
5
108
|
## [0.3.11] - 2026-10-12
|
|
6
109
|
|
|
7
110
|
### Fixed
|
|
@@ -38,8 +38,28 @@ pseudo-terminal tests.
|
|
|
38
38
|
Background pipelines, builtins, functions, and all redirections are rejected
|
|
39
39
|
before files are opened. General asynchronous command lists, job control,
|
|
40
40
|
and coprocesses are not implemented.
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
Compatibility invariant: keep the original `Bun.Subprocess` objects in an
|
|
42
|
+
append-only `Bun.sha.procs` array with stable indices, immediate return and
|
|
43
|
+
`unref()`. POSIX foreground work must not add implicit waiting, killing,
|
|
44
|
+
removal of completed entries, or a job-wrapper replacement.
|
|
45
|
+
- Brace command groups run in the current shell, including scoped redirects
|
|
46
|
+
and group pipelines. `select`, arithmetic commands, and `[[ ... ]]` remain
|
|
47
|
+
unimplemented. Function opening braces may be on the same or next line;
|
|
48
|
+
inline bodies and nested case clauses are supported.
|
|
49
|
+
- `return` stops at the function/source boundary; `break N` and `continue N`
|
|
50
|
+
unwind enclosing loops. Functions and sourced files establish their own
|
|
51
|
+
loop boundary, following mksh STOP_BRKCONT.
|
|
52
|
+
- `set -e` uses a dynamically inherited error-ignore context for conditions,
|
|
53
|
+
non-final AND/OR commands and negation, following mksh XERROK. `set -u`,
|
|
54
|
+
`set -f`, `set -x`, option queries and corresponding CLI flags are supported.
|
|
55
|
+
`-v` currently prints initial CLI input only; it is not an incremental reader.
|
|
56
|
+
`set -o posix` is listed and stored as an option. It makes fallback `ls`
|
|
57
|
+
omit icons and automatic directory suffixes; `lsfancy` remains decorative.
|
|
58
|
+
External environments in this mode contain only inherited/exported names
|
|
59
|
+
and command-prefix assignments. Full variables and export attributes travel
|
|
60
|
+
with internal pipeline/subshell state, separately from the native environment.
|
|
61
|
+
Default mode continues passing all shell variables to external programs.
|
|
62
|
+
It does not imply full POSIX conformance.
|
|
43
63
|
- Functions and subshells cover practical cases but do not yet reproduce every
|
|
44
64
|
mksh scoping, local-variable, trap, and diagnostic edge case.
|
|
45
65
|
- Pipelines isolate builtin/function state through subprocess copies. Changes
|
|
@@ -75,9 +95,17 @@ pseudo-terminal tests.
|
|
|
75
95
|
pathname expansion, or tilde expansion, and a trailing newline is appended.
|
|
76
96
|
It follows the same dash/`/bin/sh` comparison harness as everything else in
|
|
77
97
|
this codebase, except `<<<` itself, since dash does not implement it.
|
|
78
|
-
-
|
|
79
|
-
|
|
80
|
-
|
|
98
|
+
- Numeric file descriptors support file open, append, read/write (`<>`),
|
|
99
|
+
duplication and shell-level closure, with left-to-right redirect ordering.
|
|
100
|
+
`exec` without a command persists bindings. Compound/function redirections
|
|
101
|
+
restore only the descriptors they changed; native open handles retained by
|
|
102
|
+
another binding stay alive. External/pipeline children inherit extra fds
|
|
103
|
+
through Bun.spawn stdio. No native compiler or host shell is required.
|
|
104
|
+
- Descriptor variables and heredocs targeting non-stdin fds are not implemented.
|
|
105
|
+
Closing a descriptor denies subsequent shell duplication/use, but Bun.spawn
|
|
106
|
+
maps a closed child stdio slot to `ignore` (/dev/null), not native EBADF.
|
|
107
|
+
Aliases of captured stdout/stderr passed as extra fds to an arbitrary external
|
|
108
|
+
program do not yet reproduce every pipe/capture ordering case.
|
|
81
109
|
- External processes use `Bun.spawn`; regular and fallback builtins may execute
|
|
82
110
|
in-process or in a self-spawned bunmsh pipeline child depending on streaming
|
|
83
111
|
and state-isolation requirements.
|
|
@@ -96,13 +124,16 @@ pseudo-terminal tests.
|
|
|
96
124
|
- Ctrl-D on an empty readline input sends EOF and exits the interactive shell.
|
|
97
125
|
This is deliberately distinct from Ctrl-C, following the same high-level
|
|
98
126
|
editor/main-loop separation used by mksh.
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
or
|
|
105
|
-
|
|
127
|
+
- `trap` supports listing, reset (`-`), shell-local ignore (empty action),
|
|
128
|
+
EXIT/0 and catchable signal names/numbers. Signal callbacks enqueue handlers;
|
|
129
|
+
shell source runs at command boundaries, following mksh's pending-trap model.
|
|
130
|
+
Handlers preserve `$?`; EXIT runs once and can explicitly override status.
|
|
131
|
+
Shell finalization releases its fd resources and listeners, never background
|
|
132
|
+
subprocesses or Bun.sha.procs entries.
|
|
133
|
+
- Complete native signal semantics are not claimed: ignored handlers do not
|
|
134
|
+
establish inherited SIG_IGN in external children, handlers waiting at an idle
|
|
135
|
+
interactive prompt run at the next command boundary, and there is no ERR trap,
|
|
136
|
+
process-group forwarding, `wait` integration or general builtin cancellation.
|
|
106
137
|
- Status 130 is defined for an interrupted `serve`, and its SIGTERM path uses
|
|
107
138
|
143. Signal-derived statuses are not yet normalised consistently for every
|
|
108
139
|
external command, builtin, pipeline stage, and command substitution.
|
|
@@ -182,11 +213,11 @@ pseudo-terminal tests.
|
|
|
182
213
|
|
|
183
214
|
## Remaining major work
|
|
184
215
|
|
|
185
|
-
1.
|
|
216
|
+
1. General background jobs, process groups, complete signal/trap inheritance,
|
|
186
217
|
general builtin cancellation, and `jobs`/`fg`/`bg`/`wait`.
|
|
187
|
-
2.
|
|
218
|
+
2. Full shell-option edge cases, `pipefail`, incremental verbose input and POSIX
|
|
188
219
|
mode, plus startup/login/restricted-shell files and modes.
|
|
189
|
-
3.
|
|
220
|
+
3. `[[ ... ]]`, arithmetic commands,
|
|
190
221
|
extended globs, process substitution, and fuller mksh expansion semantics.
|
|
191
222
|
4. Arrays, associative arrays, namerefs, `typeset`/scope semantics, and more
|
|
192
223
|
complete special builtins.
|
|
@@ -194,3 +225,90 @@ pseudo-terminal tests.
|
|
|
194
225
|
`fc`, and automatic history policy.
|
|
195
226
|
6. Broader POSIX conformance testing, mksh `check.t` coverage, exact diagnostics,
|
|
196
227
|
and exit-status compatibility for edge cases.
|
|
228
|
+
|
|
229
|
+
## Bootstrap compatibility verification (2026-10-13)
|
|
230
|
+
|
|
231
|
+
Implementation reference: sibling `mksh/syn.c` (`function_body`/brace grammar),
|
|
232
|
+
`exec.c` (TBRACE, XERROK, E_LOOP), `funcs.c` (c_exitreturn, c_brkcont, c_trap),
|
|
233
|
+
and `histrap.c` (runtrap/cleartraps). The JavaScript execution and descriptor
|
|
234
|
+
model is adapted to Bun; no C code or native signal/job-control layer is copied.
|
|
235
|
+
|
|
236
|
+
`test/posix-bootstrap.test.js` covers finite control-flow, descriptor, trap,
|
|
237
|
+
option and background-registry cases without requiring a reference shell.
|
|
238
|
+
Tests were run with musl Bun 1.4.2 in `bunproot -r rfs1`. The guest's `/bin/sh`
|
|
239
|
+
is itself bunmsh, so reference.test.js comparisons there would not constitute
|
|
240
|
+
an independent POSIX oracle.
|
|
241
|
+
|
|
242
|
+
The next configure compatibility batch adds physical source-line tracking for
|
|
243
|
+
ordinary commands and nested function/case bodies, quoted parameter operands
|
|
244
|
+
(including `${1+"$@"}`), compound conditions containing nested groups/if, and
|
|
245
|
+
multiline subshells containing case clauses. LINENO handling is not yet complete
|
|
246
|
+
for every condition, eval, subshell, or user-assignment edge case.
|
|
247
|
+
|
|
248
|
+
The sed fallback now has addresses/ranges, labels/branches, pattern/hold-space
|
|
249
|
+
operations, and text commands; expr provides arithmetic/comparison/BRE matching.
|
|
250
|
+
File diff uses the jsmdcui Myers alignment and normal-format change hunks;
|
|
251
|
+
directory comparison and unified/context output are not implemented.
|
|
252
|
+
Subprocess state still includes the complete function AST. Large internal state
|
|
253
|
+
uses a private temporary file cleaned by the spawning foreground process. This
|
|
254
|
+
avoids the observed bunproot environment-string limit without changing the
|
|
255
|
+
Bun.sha.procs registry or background process lifecycle.
|
|
256
|
+
|
|
257
|
+
GNU make 4.4.1 configure validation is ongoing; no complete run is claimed.
|
|
258
|
+
Its LINENO/re-exec blockers and large unexported test-source environment values
|
|
259
|
+
have dedicated regressions. Autoconf's multiline case wildcard now detects the
|
|
260
|
+
listed posix option and enables it. Further utility/parser blockers may remain.
|
|
261
|
+
|
|
262
|
+
Independent utility references can be recorded outside the bootstrap guest with
|
|
263
|
+
`node test/utility-reference-cases.mjs OUTPUT.json`, using `/usr/bin/diff` and
|
|
264
|
+
`/usr/bin/sed`. Make only that JSON data accessible inside the guest, then run
|
|
265
|
+
`BUNMSH_UTILITY_REFERENCE=/guest/OUTPUT.json bun test test/utility-reference.test.js`.
|
|
266
|
+
The test compares status, stdout and stderr from explicit bunmsh builtins; it
|
|
267
|
+
does not invoke or mount host reference executables. Without the environment
|
|
268
|
+
variable, the reference fixture suite is skipped explicitly.
|
|
269
|
+
|
|
270
|
+
The current 13 file-diff and 15 sed cases passed under musl Bun/bunproot against
|
|
271
|
+
GNU diffutils 3.10 and GNU sed 4.9. They cover middle edits, repeated lines,
|
|
272
|
+
newline boundaries, UTF-8, sed script files, addresses, branches, hold space and file reads.
|
|
273
|
+
These are selected compatibility cases, not a claim of complete GNU behavior.
|
|
274
|
+
|
|
275
|
+
The awk fallback is a JavaScript parser/interpreter in src/awk.js, with no
|
|
276
|
+
native awk or FFI dependency. It supports BEGIN/END, pattern/action records,
|
|
277
|
+
fields, associative arrays, functions/control flow, regex/string operations,
|
|
278
|
+
getline and file redirection. Output command pipes run through bunmsh, with
|
|
279
|
+
input buffered until close or program end; streaming and interactive pipe
|
|
280
|
+
communication are not supported. Input command pipes and system() fail
|
|
281
|
+
explicitly. JavaScript regex, string and numeric behavior imposes remaining
|
|
282
|
+
locale/formatting limits; this is not full POSIX or GNU awk compatibility.
|
|
283
|
+
The optional test/awk-reference.test.js suite compares a separately supplied
|
|
284
|
+
BUNMSH_AWK_REFERENCE executable; it is never used by the builtin itself.
|
|
285
|
+
|
|
286
|
+
### Additional Autoconf regressions
|
|
287
|
+
|
|
288
|
+
Compound normalization removes only lexer-recognized line continuations; it
|
|
289
|
+
preserves backslash-newlines inside single quotes and heredoc bodies. Case `;;`
|
|
290
|
+
terminators remain adjacent after brace groups. AND/OR operators continue across
|
|
291
|
+
heredoc bodies, and pipelines retain redirected compound operands. Expansion
|
|
292
|
+
markers use reserved Unicode noncharacters instead of ASCII control bytes, so
|
|
293
|
+
Autoconf's BEL separator reaches awk intact. Sed `r FILE` appends raw file data
|
|
294
|
+
at the end of the cycle (including after `d`); missing files contribute nothing.
|
|
295
|
+
|
|
296
|
+
GNU make build.sh additionally exercises bracket/quoted parameter trimming and
|
|
297
|
+
subshell snapshots taken at execution time. Internal state transport is scoped
|
|
298
|
+
to its command even outside POSIX mode; default user variable export behavior
|
|
299
|
+
and the background process registry are unchanged. Basic regex anchors are
|
|
300
|
+
context-sensitive so literal make variable references can be substituted.
|
|
301
|
+
|
|
302
|
+
Binutils bootstrap coverage additionally includes multiline `${...}` operands
|
|
303
|
+
inside compound bodies, legacy egrep/fgrep fallback names, bytewise cmp (normal
|
|
304
|
+
and quiet modes), tr squeezing with optional translation/deletion, and an
|
|
305
|
+
adapter for Bun Shell mv's missing `--` support. The adapter protects filenames
|
|
306
|
+
beginning with `-` by prefixing `./` after removing the option delimiter. The
|
|
307
|
+
cmp and tr subset has offline GNU command reference fixtures;
|
|
308
|
+
unsupported extensions remain errors, not successful no-ops.
|
|
309
|
+
|
|
310
|
+
The uniq fallback preserves byte comparisons and adjacent groups, supports
|
|
311
|
+
-c/-d/-u, -- and input/output operands. Other GNU extensions are explicit
|
|
312
|
+
errors. Twelve GNU reference fixtures cover ordering, flags, blank lines,
|
|
313
|
+
missing final newlines and NUL bytes. rm -f discards empty nonexistent path
|
|
314
|
+
operands before Bun Shell can incorrectly treat them as the current directory.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## awk
|
|
2
|
+
|
|
3
|
+
Scan records and evaluate AWK programs using a JavaScript interpreter.
|
|
4
|
+
|
|
5
|
+
### Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
awk [-F SEPARATOR] [-v NAME=VALUE] [-f SCRIPT_FILE] [PROGRAM] [FILE ...]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Options and forms
|
|
12
|
+
|
|
13
|
+
- `-F`: Set the field separator; `-v`: assign a variable before BEGIN.
|
|
14
|
+
- `-f`: Read program text from a file; `-e`: append program text.
|
|
15
|
+
- BEGIN/END, pattern/action rules, fields, variables, associative arrays,
|
|
16
|
+
functions, conditionals, loops, next/nextfile, exit and delete.
|
|
17
|
+
- print/printf, arithmetic, comparisons, regular expressions, concatenation,
|
|
18
|
+
split, substr, index, length, match, sub/gsub and common numeric functions.
|
|
19
|
+
- getline from input or files; file output with `>` and `>>`; close.
|
|
20
|
+
- Parenthesized print/printf lists and continued arguments after commas.
|
|
21
|
+
- Output pipes run through bunmsh, buffering input until close or program end.
|
|
22
|
+
They do not provide streaming or interactive communication. close returns
|
|
23
|
+
the command status; closing and reopening starts a fresh command.
|
|
24
|
+
- This is a subset, not full POSIX/GNU compatibility. Input command pipes and
|
|
25
|
+
system() are unsupported and report errors. Text processing uses JavaScript strings
|
|
26
|
+
and regular expressions; locale and floating-point edge cases may differ.
|
|
27
|
+
|
|
28
|
+
### Example
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
printf 'apple 2\npear 3\n' | awk '{total += $2} END {print total}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Output:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
5
|
|
38
|
+
```
|