echo
that prints a string to stdout, and there is a true
that does nothing but just ends with zero code.yes
hidden. If you run it without arguments, you will get an infinite stream of characters "y", each from a new line: y y y y (... )
yes | sh boring_installation.sh
yes
command comes to the rescue! She will carry out this task carefully, so you can stay in touch with the Pootie Tang . 10 PRINT "y" 20 GOTO 10
while True: print("y")
python yes.py | pv -r > /dev/null [4.17MiB/s]
yes | pv -r > /dev/null [34.2MiB/s]
use std::env; fn main() { let expletive = env::args().nth(1).unwrap_or("y".into()); loop { println!("{}", expletive); } }
yes
.unwrap_or
to get expletive from parameters. If no parameters are set, the default is "y".&str
) to owned()
on a heap ( String
) using into()
. cargo run --release | pv -r > /dev/null Compiling yes v0.1.0 Finished release [optimized] target(s) in 1.0 secs Running `target/release/yes` [2.35MiB/s]
main(argc, argv) char **argv; { for (;;) printf("%s\n", argc>1? argv[1]: "y"); }
# brew install coreutils gyes | pv -r > /dev/null [854MiB/s]
/* Repeatedly output the buffer until there is a write error; then fail. */ while (full_write (STDOUT_FILENO, buf, bufused) == bufused) continue;
BUFSIZ
, which is selected for each system in order to maximally optimize I / O operations (see here ). On my system, it was installed as 1024 bytes. In reality, the best performance was at 8192 bytes. use std::io::{self, Write}; const BUFSIZE: usize = 8192; fn main() { let expletive = env::args().nth(1).unwrap_or("y".into()); let mut writer = BufWriter::with_capacity(BUFSIZE, io::stdout()); loop { writeln!(writer, "{}", expletive).unwrap(); } }
use std::env; use std::io::{self, Write}; use std::process; use std::borrow::Cow; use std::ffi::OsString; pub const BUFFER_CAPACITY: usize = 64 * 1024; pub fn to_bytes(os_str: OsString) -> Vec<u8> { use std::os::unix::ffi::OsStringExt; os_str.into_vec() } fn fill_up_buffer<'a>(buffer: &'a mut [u8], output: &'a [u8]) -> &'a [u8] { if output.len() > buffer.len() / 2 { return output; } let mut buffer_size = output.len(); buffer[..buffer_size].clone_from_slice(output); while buffer_size < buffer.len() / 2 { let (left, right) = buffer.split_at_mut(buffer_size); right[..buffer_size].clone_from_slice(left); buffer_size *= 2; } &buffer[..buffer_size] } fn write(output: &[u8]) { let stdout = io::stdout(); let mut locked = stdout.lock(); let mut buffer = [0u8; BUFFER_CAPACITY]; let filled = fill_up_buffer(&mut buffer, output); while locked.write_all(filled).is_ok() {} } fn main() { write(&env::args_os().nth(1).map(to_bytes).map_or( Cow::Borrowed( &b"y\n"[..], ), |mut arg| { arg.push(b'\n'); Cow::Owned(arg) }, )); process::exit(1); }
std::ffi::OsString
and std::borrow::Cow
to avoid unnecessary memory locations.mut
.yes
program was actually not so simple. It uses output buffering and memory alignment to improve performance.Source: https://habr.com/ru/post/342002/
All Articles