+ All Categories
Home > Engineering > Coming Out Of Your Shell - A Comparison of *Nix Shells

Coming Out Of Your Shell - A Comparison of *Nix Shells

Date post: 16-Apr-2017
Category:
Upload: kel-cecil
View: 319 times
Download: 2 times
Share this document with a friend
39
Coming Out of Your Shell Kel Cecil @praisechaos
Transcript
Page 1: Coming Out Of Your Shell - A Comparison of *Nix Shells

Coming Out of Your Shell

Kel Cecil@praisechaos

Page 2: Coming Out Of Your Shell - A Comparison of *Nix Shells

bashCreated by Brian Fox in1989Stallman was not pleasedwith

for an open shellanother developer's

progress

Page 3: Coming Out Of Your Shell - A Comparison of *Nix Shells

zshCreated by Paul Falstad in1990 while a student atPrinceton.Named after for Yaleprofessor Zhong Shaowhose login id was "zsh"

Page 4: Coming Out Of Your Shell - A Comparison of *Nix Shells

Shared history (like FTP and TCP support)

Extended file globbingTheme-able prompts

Sweet loadable modules

zsh configured with oh-my-zsh and demonstrating extended globbing

(Some) zsh Features

Page 5: Coming Out Of Your Shell - A Comparison of *Nix Shells

fishOrignally written by AxelLiljencrantz and released in2005"friendly interactive shell"Considered an "exotic"shell

Does not derive syntaxfrom Bourne or c shells

fish's design is opinionated

Page 6: Coming Out Of Your Shell - A Comparison of *Nix Shells

(Some) fish Features

Selectable, searchable tab-completion menu with helpfuldescriptions

Web configuration tool (fish_config)

Aesthetic feedback on completions and moreShell completions by parsing man pages

Event handlers

Page 7: Coming Out Of Your Shell - A Comparison of *Nix Shells

Digging a Little Deeper

Page 8: Coming Out Of Your Shell - A Comparison of *Nix Shells

GlobbingReferencing Files with Ease

Page 9: Coming Out Of Your Shell - A Comparison of *Nix Shells

What is Globbing?The ability to get a list of filenamesmatching some descriptive string

Proficiency with globbing can save a lot oftime.

Page 10: Coming Out Of Your Shell - A Comparison of *Nix Shells

Recursive WildcardsWorks out of the box in zsh, fish

Page 11: Coming Out Of Your Shell - A Comparison of *Nix Shells

Recursive Wildcardsbash 4.x

Page 12: Coming Out Of Your Shell - A Comparison of *Nix Shells

Opt-in Features for bash

There are several opt-in features for bash.Opt-in is intended to preserve default behaviorwhere desired.A list of opt-in features is available on the

.Be sure to check it out if you're a bash person.

shoptbuiltin info page

Page 13: Coming Out Of Your Shell - A Comparison of *Nix Shells

zsh's Glob QualifiersWhat if I'd like to find an .iso in my Downloads folder?

Filter down to images that are larger than 1 GBModified less than 1 Month Ago

*.iso(.Lg+1mM-1)

Page 14: Coming Out Of Your Shell - A Comparison of *Nix Shells

zsh's estringsestrings allow you to use a comparison as a conditionfor expansion

~/code/*(/e:'[[ -e ${REPLY}/.git ]]':)

Page 15: Coming Out Of Your Shell - A Comparison of *Nix Shells

zsh's glob qualifier abuse

Glob qualifiers can be nasty if abused.

~/code/*(-FUGmM+3e:'[[ -e ${REPLY}/.git ]]':^mM+12)

Page 16: Coming Out Of Your Shell - A Comparison of *Nix Shells
Page 17: Coming Out Of Your Shell - A Comparison of *Nix Shells

zsh's glob qualifier abuse

~/code/*(-FUGe:'[[ -e ${REPLY}/.git ]]':^mM+12)

Non-empty directories (F) in the code directory in myhome directory that are not symlinks (-)Directories are owned by the current user (U) AND thecurrent user's primary group (G).Include the directory if it includes a .git directory(estring).Do not include ( ^ ) directories modified more than 12 months ago.

Page 18: Coming Out Of Your Shell - A Comparison of *Nix Shells

There's plenty more...Be sure to check out zsh's Expansion manual page

Page 19: Coming Out Of Your Shell - A Comparison of *Nix Shells

ScriptingMaking the shell work for you

Page 20: Coming Out Of Your Shell - A Comparison of *Nix Shells

A simple example scriptTakes a list of files and two wordsLoops through each of the files

Ensure the file is a regular fileReplace the first word with the second wordOutput a status line

Example:./chtext.sh bruceBanner incredibleHulk ./data/*.txt

Page 21: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/bin/bash# chtext - change text within multiple files

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo echo >&2 "chtext: change ${FILE}: ${OLD} to ${NEW}" if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" else echo >&2 "chtext: could not change file: ${FILE}" fi fidone

bash

Page 22: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/bin/bash# chtext - change text within multiple files

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo echo >&2 "chtext: change ${FILE}: ${OLD} to ${NEW}" if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" else echo >&2 "chtext: could not change file: ${FILE}" fi fidone

bash

Check if we've suppliedfewer than threeparameters.Exit with an error codeof 1 if so.

Page 23: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/bin/bash# chtext - change text within multiple files

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo echo >&2 "chtext: change ${FILE}: ${OLD} to ${NEW}" if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" else echo >&2 "chtext: could not change file: ${FILE}" fi fidone

bashSet our word to bereplaced as OLD andthe replacement wordas NEWShift the scriptarguments two places.

Move all arraycontents left twoplaces.This removes thefirst two array items.

Page 24: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/bin/bash# chtext - change text within multiple files

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo echo >&2 "chtext: change ${FILE}: ${OLD} to ${NEW}" if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" else echo >&2 "chtext: could not change file: ${FILE}" fi fidone

bash

Loop through theremaining scriptarguments.Set each argument tothe FILE variable.This isn't exactlyintuitive...

Page 25: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/bin/bash# chtext - change text within multiple files

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo echo >&2 "chtext: change ${FILE}: ${OLD} to ${NEW}" if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" else echo >&2 "chtext: could not change file: ${FILE}" fi fidone

bashCheck if the file is aregular file. Perform a sed toreplace the OLD wordwith the new word andwrite to a temp file.

$$ represents theprocess ID for thescript.

If the sed returns a zerostatus code, thenreplace the file.

Page 26: Coming Out Of Your Shell - A Comparison of *Nix Shells

fish is a little different...bash strives to be POSIX compliantzsh strives to be compatible with bashfish does it's own thing

fish is not POSIX compliant and considers that tobe a feature.The scripting language is intended to be moresimple.

Page 27: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

set VALUES (count $argv)

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fish

Page 28: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fishCheck to see if ourarguments are lessthan 3.Script arguments arestored in $argvWe use the mathbuiltin for ourcomparisonRedirect the mathoutput to /dev/null toavoid printing ouranswer on stdout

Page 29: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fishfish uses "set" forvariable assignment.

Page 30: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fishList ranges can bespecified using ".."The last item in thelist can be identifiedby using "-1"

Page 31: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fishNotice that variablesdo not have curlybraces "{}"

Curly braces areoptional in bash.fish requires younot use them.fish will be niceabout it.

Page 32: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fishfish defers toprograms whenpossible instead ofreimplementingfeatures.This call to testchecks to see if a fileis a regular file.

Page 33: Coming Out Of Your Shell - A Comparison of *Nix Shells

#!/usr/bin/env fish# chtext - change text within multiple files

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] echo >&2 "chtext: change $FILE: $OLD to $NEW" if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" else echo >&2 "chtext: could not change file: $FILE" end endend

fish%self substitutes theprocess ID in fish.

Using $$ as youwould in bashresults in a helpfulerror message.

Page 34: Coming Out Of Your Shell - A Comparison of *Nix Shells

if math (count $argv) "<3" > /dev/null echo >&2 "usage: chtext old new [file ...]" exit 1end

set OLD $argv[1]set NEW $argv[2]

for FILE in $argv[3..-1] if test -f $FILE if sed "s|$OLD|$NEW|g" < "$FILE" > /tmp/ct%self mv /tmp/ct%self "$FILE" end endend

if [ $# -lt 3 ]; then echo >&2 "usage: chtext old new [file ...]" exit 1fi

OLD="$1"NEW="$2"shift 2

for FILEdo if [ -r "${FILE}" ] then if sed "s|${OLD}|${NEW}|g" < "${FILE}" > /tmp/ct$$ then mv /tmp/ct$$ "${FILE}" fi fidone

Which do you prefer?

Bash?

or fish?

Page 35: Coming Out Of Your Shell - A Comparison of *Nix Shells

Frameworks

Page 36: Coming Out Of Your Shell - A Comparison of *Nix Shells

Why use shell frameworks?Carefully manicured shell scripts can be a lot of work.Community maintained scripts can be higher quality.

Page 38: Coming Out Of Your Shell - A Comparison of *Nix Shells

What are my takeaways?

bash is capable of more than it's givencredit for.zsh is great for people who like to tweakand invest the time into unlocking it's fullpotential.fish is fantastic for useful features right outof the box.All three shells have frameworks to try.We've hardly scratched the surface...

Page 39: Coming Out Of Your Shell - A Comparison of *Nix Shells

Thanks for Listening!

Twitter: @praisechaos

Web: http://kelcecil.com

Here's a Game Boy Advance running Unix 5!


Recommended