https://github.com/acikgozb/gtee
Go implementation of `tee`, a GNU Coreutils tool. Work in progress.
https://github.com/acikgozb/gtee
cli gnu-coreutils go tee
Last synced: 8 months ago
JSON representation
Go implementation of `tee`, a GNU Coreutils tool. Work in progress.
- Host: GitHub
- URL: https://github.com/acikgozb/gtee
- Owner: acikgozb
- License: gpl-3.0
- Created: 2024-12-25T20:05:22.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-01-01T20:35:27.000Z (over 1 year ago)
- Last Synced: 2025-01-01T21:33:22.650Z (over 1 year ago)
- Topics: cli, gnu-coreutils, go, tee
- Language: Go
- Homepage:
- Size: 32.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `gtee`
A Go implementation of `tee`, a GNU Coreutils tool. The original implementation in C can be checked on [here](https://github.com/coreutils/coreutils/blob/master/src/tee.c).
## Table of Contents
- [Installation](#a-idinstallation-installation)
- [`go install`](#go-install)
- [Prebuilt Binaries](#prebuilt-binaries)
- [Usage](#a-idusage-usage)
- [The Implementation](#a-idthe-implementation-the-implementation)
- [Tests](#a-idtests-tests)
- [Benchmarks](#a-idbenchmarks-benchmarks)
- [TODO](#a-idtodo-todo)
`gtee` is available on Linux and MacOS.
As a Go project, `gtee` can be installed via `go install`, like below:
```bash
go install github.com/acikgozb/gtee
```
If you wish to not install Go on your machine just to install `gtee`, you can download a prebuilt binary from the release page.
The binaries are available for the platforms below:
- _x86_64_ (amd64) Linux
- _arm64_ Darwin (macOS)
You can download the version you wish to use and then extract the binary from the archive to wherever you want.
Once downloaded and put into a directory, you can verify the installation by simply running:
```bash
gtee -h
```
If you see the usage, then you are all set!
Don't forget to make sure the binary is under `$PATH` to be able to use it without manually entering the location of the binary itself.
To verify whether `gtee` is under path, you can run:
```bash
which gtee
```
If `which` returns a path, that means you can successfully use `gtee` without specifying the full path of the binary.
`gtee` is designed to be used as a drop in replacement of `tee` with the exception of:
- Merging shorthand options like `-ai`,
- Environment variables that alter the language of diagnostic messages.
Here are the supported usages:
```bash
# Write to both stdout and a file named "example.txt".
$ echo "write me!" | gtee example.txt
# Use input redirection and write "input.txt" to both stdout and a file named "example.txt".
$ gtee example.txt < input.txt
# Write "input.txt" only to a file named "example.txt", not stdout.
$ gtee example.txt > /dev/null < input.txt
# Append only to a file named "example.txt".
$ echo "append me!" | gtee -a example.txt > /dev/null
$ echo "append me!" | gtee --a example.txt > /dev/null
$ echo "append me!" | gtee -append example.txt > /dev/null
$ echo "append me!" | gtee --append example.txt > /dev/null
# Ignore SIGINT during a long execution.
$ echo "write me, a super long input!" | gtee -i example.txt > /dev/null
$ echo "write me, a super long input!" | gtee --i example.txt > /dev/null
$ echo "write me, a super long input!" | gtee -ignore example.txt > /dev/null
$ echo "write me, a super long input!" | gtee --ignore example.txt > /dev/null
# Attempting to send a SIGINT signal results in a diagnostic message on stdout, not err.
$ echo "write me, a super long input!" | gtee -i example.txt > /dev/null
^Cgtee: The SIGINT signal is ignored.
# Append to a file named "example.txt" and ignore the SIGINT signal.
$ echo "append me, a super long input!" | gtee -a -i example.txt > /dev/null
$ echo "append me, a super long input!" | gtee --a --i example.txt > /dev/null
$ echo "append me, a super long input!" | gtee -append -ignore example.txt > /dev/null
$ echo "append me, a super long input!" | gtee --append --ignore example.txt > /dev/null
```
Running `gtee` with `-h` or with a non-supported flag will result in showing the usage of the program, which is inspired from the man page of `tee`:
```bash
# Show usage:
$ gtee -h # --h, -help, --help
NAME
gtee - Duplicate standard input.
SYNOPSIS
gtee [-a] [-i] [file ...]
OPTIONS
-i, --i, -ignore, --ignore Ignore the SIGINT signal.
-a, --a, -append, --append Append the output to the files rather than overwriting them.
EXAMPLES
Send the echoed message to both stdout and a file called greetings.txt:
$ echo "Hello" | gtee greetings.txt
Hello
```
The implemenation is done based on the POSIX specification of `tee`.
You can see the specification on [here](https://pubs.opengroup.org/onlinepubs/9799919799/).
Search for `tee` from index and you will see the document.
Each test is written to satisfy a different part of the specification.
To see which requirement is tested in a given test, search the content of the `expected` variable on the specification.
Currently, there is only one simple benchmark which compares both `tee` and `gtee` on a 100MB file created by `dd`.
Check out `BenchmarkTee` and `BenchmarkGtee` for more information.
Here is a sample comparison to showcase a result.
Keep in mind that the times you get on your own host may not match with these:
```bash
$ go test -bench=. -benchtime 100x -benchmem
pkg: github.com/acikgozb/gtee
BenchmarkTee-10 100 55095693 ns/op 5940 B/op 22 allocs/op
BenchmarkGtee-10 100 49339303 ns/op 5988 B/op 22 allocs/op
PASS
ok github.com/acikgozb/gtee 12.470s
```
- `man gtee`.