Cli
CSV tools
Here are some CSV utilities that may come in handy since most teams deal with this format.
- daff - part of my default toolset ;)
- csvq - part of my default toolset ;)
- tsv-utils - interesting read
- xsv - yeah, the ripgrep guy
- gron - now part of my default toolset (yeah, json but faster than jq with “flatten” filter; line grep is powerful)
- coopy - patch/diff for CSV and spreadsheet data
- rq - in trial
Pure BASH interactive CLI/TUI menu (single-/multi-select/checkboxes)
This post presents a first version of a pure bash script for creating interactive command-line menus with single-select, multi-select, and checkbox functionality.
First version. To be refactored.
Inspired by
- https://serverfault.com/questions/144939/multi-select-menu-in-bash-script
- partly based on https://www.bughunter2k.de/blog/cursor-controlled-selectmenu-in-bash by Ingo Hollmann
Notes
- This is a hacky first implementation for my shell tools/dotfiles (ZSH).
- The intention is to use it for CLI wizards (my aim is NOT a full-blown curses TUI window interface).
- I converted TPUT to ANSI-sequences to spare command executions (e.g.
tput ed | xxd --plain).
Permission to copy and modify is granted under the Creative Commons Attribution 4.0 license.
PHP: just in case posix_isatty() is missing
This article provides a couple of PHP code snippets from StackOverflow that can be used to determine if a PHP script is running in an interactive terminal (TTY). These are useful workarounds for environments where the posix_isatty() function is not available.
Short function
function is_a_tty()
{
static $result;
if (is_null($result)) {
$fp = fopen('php://stdin', 'r');
$stat = fstat($fp);
$mode = $stat['mode'] & 0170000; // S_IFMT
$result = $mode == 0020000; // S_IFCHR
fclose($fp);
}
return $result;
}
Info Class from StackOverflow by leigh
<?php
class IOMode
{
public $stdin;
public $stdout;
public $stderr;
private function getMode(&$dev, $fp)
{
$stat = fstat($fp);
$mode = $stat['mode'] & 0170000; // S_IFMT
$dev = new StdClass;
$dev->isFifo = $mode == 0010000; // S_IFIFO
$dev->isChr = $mode == 0020000; // S_IFCHR
$dev->isDir = $mode == 0040000; // S_IFDIR
$dev->isBlk = $mode == 0060000; // S_IFBLK
$dev->isReg = $mode == 0100000; // S_IFREG
$dev->isLnk = $mode == 0120000; // S_IFLNK
$dev->isSock = $mode == 0140000; // S_IFSOCK
}
public function __construct()
{
$this->getMode($this->stdin, fopen('php://stdin', 'r'));
$this->getMode($this->stdout, fopen('php://stdout', 'w'));
$this->getMode($this->stderr, fopen('php://stderr', 'w'));
}
}
$io = new IOMode;
Input
$ php io.php
// Character device as input
// $io->stdin->isChr == true
$ echo | php io.php
// Input piped from another command
// $io->stdin->isFifo == true
$ php io.php < infile
// Input from a regular file (name taken verbatim from C headers)
// $io->stdin->isReg == true
$ mkdir test
$ php io.php < test
// Directory used as input
// $io->stdin->isDir == true
Output:
$ php io.php
// $io->stdout->isChr == true
$ php io.php | cat
// $io->stdout->isFifo == true
$ php io.php > outfile
// $io->stdout->isReg == true
Error:
$ php io.php
// $io->stderr->isChr == true
$ php io.php 2>&1 | cat
// stderr redirected to stdout AND piped to another command
// $io->stderr->isFifo == true
$ php io.php 2>error
// $io->stderr->isReg == true
I hope this PHP stuff finally dies.
bash: shell table output to json
This post presents a Python script that converts tabular command-line output into a more versatile JSON format. This allows for easier data manipulation using tools like jq, as an alternative to complex text-processing pipelines in bash.
You know that sometimes it would be really great to format a shell output to a more versatile format like JSON or YAML that you can process with jq instead of writing long pipes with text-processing.
AWS S3 Sync is Not Reliable and Slow!
This article explores reliability issues with AWS CLI’s S3 sync functionality and provides alternative solutions for better file synchronization.
While migrating from s3cmd to AWS S3 CLI, I noticed that files don’t sync properly when using AWS CLI.
I tested with different versions and they all revealed the same behavior:
python2.7-awscli1.9.7python2.7-awscli1.15.47python3.6-awscli1.15.47
Test Setup
- Setup AWS CLI utility and configure your credentials
- Create a testing S3 bucket
- Setup some random files
# Create 10 random files of 10MB each
for i in {1..10}; do dd if=/dev/urandom of=multi/part-$i.out bs=1MB count=10; done;
# Then copy the first 5 files over
mkdir multi-changed
cp -r multi/part-{1,2,3,4,5}.out multi-changed
# And replace the content in 5 files
for i in {6..10}; do dd if=/dev/urandom of=multi-changed/part-$i.out bs=1MB count=10; done;
Testing S3 Sync with AWS CLI
Cleanup
$ aws s3 rm s3://testbucket/multi --recursive
Initial Sync
$ aws s3 sync multi s3://testbucket/multi
upload: multi/part-1.out to s3://testbucket/multi/part-1.out
upload: multi/part-3.out to s3://testbucket/multi/part-3.out
upload: multi/part-2.out to s3://testbucket/multi/part-2.out
upload: multi/part-4.out to s3://testbucket/multi/part-4.out
upload: multi/part-10.out to s3://testbucket/multi/part-10.out
upload: multi/part-5.out to s3://testbucket/multi/part-5.out
upload: multi/part-6.out to s3://testbucket/multi/part-6.out
upload: multi/part-8.out to s3://testbucket/multi/part-8.out
upload: multi/part-7.out to s3://testbucket/multi/part-7.out
upload: multi/part-9.out to s3://testbucket/multi/part-9.out
Update Files
Only 5 files should now be uploaded. Timestamps for all 10 files should be changed.
Away with grep! Use ripgrep!
Ripgrep is a tool that recursively searches your current directory for a regex pattern. This article provides a brief overview of ripgrep and why it is a good alternative to grep.
I used ack for some time for grepping source code, yet I moved on to ripgrep since it offers quite a bit more than grep and source-code-greps like The Silver Searcher. Plus it can mostly replace grep and is about 6 times faster (it’s written in Rust). I am still astonished when I get results instantly.