John's hacks

From ProgClub
Jump to: navigation, search

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.

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" );

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;

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;

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