Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The Unbearable Lightness: Extending the Bash shell

93 views

Published on

My talk at the Linux Day 2016 in Rome.

Published in: Software
  • Be the first to comment

  • Be the first to like this

The Unbearable Lightness: Extending the Bash shell

  1. 1. #LinuxDay2016 http://lugroma3.org/
  2. 2. The Unbearable Lightness Extending the Bash shell
  3. 3. I have a natural revulsion to any operating system that shows so little planning as to have named all of its commands after digestive noises (awk, grep, fsck, nroff). Source: The UNIX HATERS Handbook
  4. 4. Shellshocks
  5. 5. CVE-2014-6271 env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
  6. 6. CVE-2014-7169 env X='() { (a)=>' bash -c "echo date"; cat echo
  7. 7. Weaknesses
  8. 8. http://mywiki.wooledge.org/BashWeaknesses
  9. 9. Speed It's too big and too slow. Source: man bash
  10. 10. Everything is text egrep '^To:|^Cc:' /var/spool/mail/$USER | cut -c5- | awk '{ for (i = 1; i <= NF; i++) print $i }' | sed 's/,//g' | grep -v $USER | sort | uniq
  11. 11. Floating point $ echo $((3/2)) 1
  12. 12. Multidimensional arrays $ array=('d1=(v1 v2 v3)' 'd2=(v1 v2 v3)') $ for elt in "${array[@]}";do eval $elt;done $ echo "d1 ${#d1[@]} ${d1[@]}" $ echo "d2 ${#d2[@]} ${d2[@]}"
  13. 13. Sorting $ array=(2 1 0) $ IFS=$'n' sorted=($(sort <<<"${array[*]}")) $ unset IFS $ echo ${sorted[*]} 0 1 2
  14. 14. Variable typing $ declare -i x $ x=foo $ echo $x 0
  15. 15. Variable scope Local vs Global vs Environment
  16. 16. Return values Bash functions don't return anything (except numbers in the range 0-255); they only produce output streams
  17. 17. Passing by reference function swap() { eval "$1=${!2} $2=${!1}" } $ x=a y=b $ swap x y b a
  18. 18. Function scope $ shopt -s extdebug $ function foo() { echo $qux ; echo ${BASH_ARGV[0]} ; } $ function bar() { local qux=thud ; foo ; } $bar baz thud baz
  19. 19. Function collapsing chatter() { if [[ $verbose ]]; then chatter() { echo "$@" } chatter "$@" else chatter() { : } fi }
  20. 20. No closures No first-order functions, no lambdas, ...
  21. 21. Try/catch trap
  22. 22. Exception handling set -e
  23. 23. Process management select? poll? events?
  24. 24. Parsing sed -ne "s|^($s):|1|" -e "s|^($s)($w)$s:$s["'](.*)["']$s$|1$fs2$fs3|p" -e "s|^($s)($w)$s:$s(.*)$s$|1$fs2$fs3|p"
  25. 25. Binary data dd if=/dev/brain of=/dev/null
  26. 26. Paradigms OO? Functional? Flow-driven? Reflective?
  27. 27. Security Did you say dropping permissions?
  28. 28. Large programs source foobar.sh
  29. 29. Debugging set -x
  30. 30. Subshell Dilemma $ c=0; ls * | while read i; do ((c++)); done; echo $c 0
  31. 31. Bashisms eval x=$$x
  32. 32. Portability It is easier to port a shell than a shell script. Source: Larry Wall
  33. 33. Why does it matter?
  34. 34. DRY Don't write scripts, write libraries
  35. 35. DevOps Python/Ruby/Scala/... are not ubiquitous
  36. 36. Legacy code
  37. 37. Attempts
  38. 38. bang.sh the "b" namespace
  39. 39. bashinator function createDirectory() { local directory=${1} if [[ -z "${directory}" ]]; then __msg err "argument 1 (directory) missing" return 2 fi __msg debug "directory: ${directory}" if ! mkdir -p "${directory}" >> "$_{L}" 2>&1; then __msg err "failed to create directory '${directory}'" return 2 fi return 0 }
  40. 40. bash automated testing system @test "addition using bc" { result="$(echo 2+2 | bc)" [ "$result" -eq 4 ] } @test "addition using dc" { result="$(echo 2 2+p | dc)" [ "$result" -eq 4 ] }
  41. 41. bash infinity import util/namedParameters util/class class:Human() { public string name public integer height public array eaten Human.__getter__() { echo "I'm a human called $(this name), $(this height) cm tall." } ... }
  42. 42. bash manager hello: p1=World! $ ./bash_manager.sh -h /tmp/helloHome Hello World!
  43. 43. bash toolbox alias fail='printf "${BASH_SOURCE##*/}: ${FU ... alias debug='printf "${BASH_SOURCE##*/}: ${FU ... alias caller='nm=$(builtin caller 0); nm=${nm% ...
  44. 44. bashworks Inversion of control: the overall program's flow of control is not dictated by the caller, but by the framework. Polite functions: Generic reuseable functions usually take a module name string argument.
  45. 45. blp minimalist approach
  46. 46. log4sh # set alternative 'nc' command log4sh_setAlternative nc /bin/nc # add and configure a SyslogAppender that logs to a remote host logger_addAppender mySyslog appender_setType mySyslog SyslogAppender appender_syslog_setFacility mySyslog local4 appender_syslog_setHost mySyslog somehost appender_activateOptions mySyslog # say Hello to the world logger_info 'Hello, world'
  47. 47. mbfl mbfl_argv_all_files || exit_because_wrong_command_line_arguments for item in "${ARGV[@]}" do test "${script_option_AUTO}" = yes && { size=$(mbfl_file_get_size "${item}") ...
  48. 48. oobash ## class Dialog Dialog=( # Explicit definition is needed to make inheritance possible. function __new__ = Dialog::__new__ function __delete__ = Dialog::__delete__ )
  49. 49. ticktick . ticktick.sh function printEmployees() { for employee in ``people.Engineering.items()``; do printf " - %sn" ${!employee} done }
  50. 50. Bashlets
  51. 51. Modular source bashlet datatype/version bash$$ version sort 1.44 1.4 1.4.4 1.4.4a 1.4-1234
  52. 52. Git integration
  53. 53. General-purpose IPC, math, network, OS-abstraction, parsers, UX, ...
  54. 54. Extensible Plugins for web protocols, databases, RCS, ...
  55. 55. Smart autoloading Via introspection
  56. 56. Work in progress
  57. 57. Colophon vim, Hovercraft!, CentOS Linux 7.2
  58. 58. exit 0 Roberto Reale https://bashlets.sh https://github.com/bashlets

×