Program Composition: Slides of new section

This is likely sufficient to get me through my entire talk time, but I have
a number of other interesting things I want to get to.  Let's see what the
timing looks like in a couple of commits.
master
Mike Gerwitz 2019-03-14 22:57:37 -04:00
parent 5abc22bae0
commit b40e289f35
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
1 changed files with 592 additions and 83 deletions

View File

@ -21,14 +21,19 @@
- GUIs /are/ sometimes the most efficient means of melding mind and machine.
- De-emphasize doing everything on a terminal just because its "cool".
** Concepts [7/28]
** Concepts [8/27]
- [ ] =/sys= and such
- [ ] Automating multi-step workflows with GNU Make
- [ ] Concurrency
- [ ] Connecting graphical and command line (X11 integration) [0/3]
- [-] Connecting graphical and command line (X11 integration) [1/4]
- [ ] Clipboard (image)
- [ ] Clipboard (text)
- [X] Clipboard (text) ([[*Program Composition]])
- [ ] X11 commands
- [ ] Interesting example idea: =import=, =tesseract ss.png - | xsel -ib=
so that you can select an area of text on the screen and perform
OCR, then have the result on your clipboard
- I've never done this, but it goes to show how trivial it is to
create something that is seemingly novel.
- [ ] Discoverability
- Example: I used GIMP for editing some images for this talk because I
thought it'd be faster to discover how to that way vs. ImageMagick docs.
@ -44,17 +49,13 @@
- Symbiosis is not only with machine, but community
- [ ] Globbing
- [ ] GnuPG and smart cards
- [ ] Incremental development [0/3]
- [ ] Develop as you go, perhaps just referencing history early on
- [ ] Evolve by making portions of command dynamic (variables, subshells)
- [ ] Transfer commands from history into scripts and aliases for re-use
- [ ] Interactive prototyping
- [ ] Incremental, iterative, interactive development ([[*Program Composition]])
- [X] Looping ([[*Perspective Topics][Perspective Topics]])
- [ ] McIlroy and Knuth
- [X] Mouse has dependency on positioning of UI elements ([[*Browser Topics][Browser Topics]])
- Changes over time, subject to user/system preferences, etc
- [ ] Multiplexing with GNU Screen
- [ ] Output redirection
- [X] Output redirection ([[*A New Perspective]])
- [ ] Phone as an example of a device that best works with touch and GUIs
and sacrifices practical freedom.
- Requires specialized knowledge and is inconvenient to work with.
@ -77,91 +78,106 @@
- [ ] Version control
** Programs [0/4]
- [-] Coreutils / Common [3/12]
- [-] Coreutils / Common [7/14]
- [X] =cut=
- [ ] =column=
- [ ] =diff=
- [X] =echo= ([[*Browser Topics][Browser Topics]]).
- [X] =echo=
- [ ] =find=
- [ ] =gpg=
- [X] =grep= ([[*Browser Topics][Browser Topics]])
- [X] =grep=
- [ ] =make= / Makefiles
- [ ] =sort=
- [ ] =man=
- [X] =sort=
- [ ] =ssh=
- [ ] =uniq=
- [ ] =wc=
- [X] =wget= / =curl= ([[*Browser Topics][Browser Topics]])
- [ ] Miscellaneous [0/8]
- [X] =uniq=
- [X] =wc=
- [X] =wget= / =curl=
- [-] Miscellaneous [4/8]
- [ ] =awk=
- [ ] =cowsay=
- [ ] =dict=
- [ ] =espeak=
- [X] =espeak=
- [ ] =git=
- [ ] =mpv= (e.g. my =pronounce=)
- [ ] =torify=
- [ ] =sed=
- [ ] X11 / Graphical [0/5]
- [X] =mail=
- [X] =torify=
- [X] =sed=
- [-] X11 / Graphical [1/5]
- [ ] =convert=
- [ ] =i3= / =xmonad= / etc
- [ ] =import=
- [ ] =setxkbmap=
- [ ] =xclip= / =xsel=
- [X] =xclip= / =xsel=
- [ ] Editors / Multiplexing [0/4]
- [ ] =emacs=
- [ ] =nano=
- [ ] =vim=
- [ ] =screen=
* DEVOID Slides [0/5]
* DEVOID Slides [0/6]
:PROPERTIES:
:ID: slides
:END:
** Summary :noexport:
#+BEGIN: columnview :hlines 2 :maxlevel 3 :indent t :id slides
| ITEM | DURATION | TODO | ENVIRONMENT |
|---------------------------------------------------+----------+--------+-------------|
| Slides | 0:23:54 | DEVOID | |
|---------------------------------------------------+----------+--------+-------------|
| \_ Summary | | | |
|---------------------------------------------------+----------+--------+-------------|
| \_ Introduction | | RAW | note |
|---------------------------------------------------+----------+--------+-------------|
| \_ Choreographed Workflows | | DEVOID | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ Practical Freedom | | DEVOID | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ Practical Example: Web Browser | 0:09:32 | DRAFT | |
| \_ Browser Topics | | | |
| \_ Example: Web Browser | 0:00:40 | DRAFT | frame |
| \_ Finding Text (Mouse-Driven GUI Interaction) | 0:01:39 | DRAFT | frame |
| \_ GUIs Change Over Time | 0:00:45 | DRAFT | frame |
| \_ Ctrl+F---Just Works | 0:00:25 | DRAFT | frame |
| \_ Muscle Memory | 0:00:40 | DRAFT | fullframe |
| \_ A Research Task | 0:00:25 | DRAFT | fullframe |
| \_ Executing the Research Task | 0:03:00 | DRAFT | frame |
| \_ GUIs of a Feather | 0:00:40 | DRAFT | fullframe |
| \_ Macro-Like Keyboard Instructions | 0:01:19 | DRAFT | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ A New Perspective | 0:14:22 | DRAFT | |
| \_ Perspective Topics | | | |
| \_ Secrets? | 0:01:19 | DRAFT | fullframe |
| \_ Lifting the Curtain | 0:01:00 | DRAFT | frame |
| \_ Web Page Source Code | 0:00:35 | DRAFT | block |
| \_ Text | 0:00:35 | DRAFT | fullframe |
| \_ Text is a Universal Interface | 0:01:19 | DRAFT | fullframe |
| \_ The Shell Command Prompt | 0:00:45 | DRAFT | frame |
| \_ Eliminating the Web Browser | 0:01:00 | DRAFT | frame |
| \_ Browser vs. =wget= Comparison | 0:00:40 | DRAFT | frame |
| \_ Finding Text on the Command Line | 0:01:00 | DRAFT | frame |
| \_ A More Gentle Reply | 0:01:00 | DRAFT | frame |
| \_ Writing to Files (Redirection) | 0:00:55 | DRAFT | frame |
| \_ Starting Our List | 0:01:10 | DRAFT | fullframe |
| \_ Command Refactoring | 0:02:00 | DRAFT | fullframe |
| \_ Again: Text is a Universal Interface | 0:00:20 | DRAFT | againframe |
| \_ Pipelines | 0:00:15 | DRAFT | fullframe |
| \_ Summary of the Unix Philosophy | 0:00:30 | DRAFT | fullframe |
|---------------------------------------------------+----------+--------+-------------|
| \_ Thank You | 00:00:01 | | fullframe |
| ITEM | DURATION | TODO | ENVIRONMENT |
|-------------------------------------------------------+----------+---------+-------------|
| Slides | 0:23:54 | DEVOID | |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Summary | | | |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Introduction | | RAW | note |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Choreographed Workflows | | DEVOID | fullframe |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Practical Freedom | | DEVOID | fullframe |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Practical Example: Web Browser | 0:09:32 | DRAFT | |
| \_ Browser Topics | | | |
| \_ Example: Web Browser | 0:00:40 | DRAFT | frame |
| \_ Finding Text (Mouse-Driven GUI Interaction) | 0:01:39 | DRAFT | frame |
| \_ GUIs Change Over Time | 0:00:45 | DRAFT | frame |
| \_ Ctrl+F---Just Works | 0:00:25 | DRAFT | frame |
| \_ Muscle Memory | 0:00:40 | DRAFT | fullframe |
| \_ A Research Task | 0:00:25 | DRAFT | fullframe |
| \_ Executing the Research Task | 0:03:00 | DRAFT | frame |
| \_ GUIs of a Feather | 0:00:40 | DRAFT | fullframe |
| \_ Macro-Like Keyboard Instructions | 0:01:19 | DRAFT | fullframe |
|-------------------------------------------------------+----------+---------+-------------|
| \_ A New Perspective | 0:14:22 | DRAFT | |
| \_ Perspective Topics | | | |
| \_ Secrets? | 0:01:19 | DRAFT | fullframe |
| \_ Lifting the Curtain | 0:01:00 | DRAFT | frame |
| \_ Web Page Source Code | 0:00:35 | DRAFT | block |
| \_ Text | 0:00:35 | DRAFT | fullframe |
| \_ Text is a Universal Interface | 0:01:19 | DRAFT | fullframe |
| \_ The Shell Command Prompt | 0:00:45 | DRAFT | frame |
| \_ Eliminating the Web Browser | 0:01:00 | DRAFT | frame |
| \_ Browser vs. =wget= Comparison | 0:00:40 | DRAFT | frame |
| \_ Finding Text on the Command Line | 0:01:00 | DRAFT | frame |
| \_ A More Gentle Reply | 0:01:00 | DRAFT | frame |
| \_ Writing to Files (Redirection) | 0:00:55 | DRAFT | frame |
| \_ Starting Our List | 0:01:10 | DRAFT | fullframe |
| \_ Command Refactoring | 0:02:00 | DRAFT | fullframe |
| \_ Again: Text is a Universal Interface | 0:00:20 | DRAFT | againframe |
| \_ Pipelines | 0:00:15 | DRAFT | fullframe |
| \_ Summary of the Unix Philosophy | 0:00:30 | DRAFT | fullframe |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Program Composition | | LACKING | |
| \_ Composition Topics | | | |
| \_ Clarifying Pipelines | | RAW | fullframe |
| \_ Tor | | LACKING | fullframe |
| \_ LP Sessions | | LACKING | fullframe |
| \_ Interactive, Incremental, Iterative Development | | LACKING | fullframe |
| \_ Discovering URLs | | LACKING | fullframe |
| \_ Go Grab a Coffee | | LACKING | fullframe |
| \_ Async Processes | | | fullframe |
| \_ Executable Shell Script and Concurrency | | LACKING | fullframe |
| \_ Again: A Research Task | | LACKING | againframe |
| \_ A Quick-n-Dirty Solution | | LACKING | frame |
|-------------------------------------------------------+----------+---------+-------------|
| \_ Thank You | 00:00:01 | | fullframe |
#+END:
** RAW Introduction :B_note:
@ -818,21 +834,6 @@ And that's why I've dragged you through this drawn-out example---to
- [X] Eliminate the temporary file entirely using a pipe
- [X] Alias =fetch-url= for =wget -qO-=.
- [X] Introduce the Unix philosophy
- [ ] Now script discovering what pages contain a certain word [0/4]
- [ ] Mention previous example of being emailed a list of URLs. Rather
than pasting them into a file, let's discover them using the same
tool: =grep=. Save email to a file.
- [ ] =grep -o 'https\?://[^ ]\+'=, show how it gets a list of URLs.
- Mention how powerful regexes are, e.g. "find all the phone numbers on
a page".
- g/re/p
- [ ] Introduce =while= and =read=, showing how we can iteratively run
commands, maybe =... | while read url; do echo "URL: $url"; done=.
- [ ] Introduce =-q= flag for grep, and use it to conditionally output
only the URLs at which the word can be found.
- Not enough talk time to walk away and get a coffee, but let's see if
we can maybe let it run for 10--30s while I blabber on. Depends on
the connection speed at MIT with all the participants.
*** DRAFT Secrets? :B_fullframe:
:PROPERTIES:
@ -1695,6 +1696,514 @@ We start to think of how to decompose problems into small operations that
We think of how to chain small, specialized programs together,
transforming text at each step to make it more suitable for the next.
** LACKING Program Composition [0/9]
*** Composition Topics [5/6] :noexport:
- [X] Clarify how pipelines work with existing =wget | grep=.
- [X] More involved pipeline with more than two programs.
- [ ] Emphasize iterative development and how the shell is a REPL. [0/3]
- Useful for programmers for prototyping and debugging, but also essential
to average users for discovery.
- [ ] Develop as you go, perhaps just referencing history early on
- [ ] Evolve by making portions of command dynamic (variables, subshells)
- [ ] Transfer commands from history into scripts and aliases for re-use
- [X] Now script discovering what pages contain a certain word [3/3]
- [X] Mention previous example of being emailed a list of URLs. Rather
than pasting them into a file, let's discover them using the same
tool: =grep=. Save email to a file.
- [X] =grep -o 'https\?://[^ ]\+'=, show how it gets a list of URLs.
- [X] Introduce =while= and =read=, showing how we can iteratively run
commands, maybe =... | while read url; do echo "URL: $url"; done=.
- Not enough talk time to walk away and get a coffee, but let's see if
we can maybe let it run for 10--30s while I blabber on. Depends on
the connection speed at MIT with all the participants.
- [X] Extract =url-grep= into script.
- [X] Demonstrate running jobs in parallel with =xargs=.
*** RAW Clarifying Pipelines :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| head -n3
<!DOCTYPE html>
<html lang="en">
<head>
#+END_SRC
#+BEAMER: \begin{uncoverenv}<2->
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| wc -l
1422
#+END_SRC
#+BEAMER: \end{uncoverenv}
#+BEAMER: \begin{uncoverenv}<3->
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep 'free software' \
| wc -l
38
#+END_SRC
#+BEAMER: \end{uncoverenv}
#+BEAMER: \begin{uncoverenv}<4->
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep 'free software' \
| tail -n1
Expat</a>. The JavaScript is free software with
#+END_SRC
#+BEAMER: \end{uncoverenv}
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:END:
Let's observe the profound consequences of these design decisions.
First,
let's make sure you understand what outputting to standard out is doing
with our existing =wget= command.
Remember that standard out is displayed to us on the terminal by default.
If we were to just run that =wget= command and nothing else,
we'd be spammed with output.
But I just want to prove to you that HTML is being output to standard out;
I don't want a ton of spam.
So we can pipe it to =head= to show only the first few lines.
But how many lines did we save ourselves?
We can pipe it to =wc= instead,
which stands for ``word count'',
and tell it to count the number of newlines with =-l=.
What about the number of lines that contain the string ``free software''?
Or how about the last such line?
*** LACKING Tor :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEGIN_SRC sh
$ alias fetch-url='torify wget -qO-'
#+END_SRC
*** LACKING LP Sessions :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| head -n14
<header class="keynote-speaker-header" id="garbee">
<hgroup>
<h2>Bdale Garbee</h2>
</hgroup>
</header>
<p><em>Closing keynote</em></p>
--
<header class="keynote-speaker-header" id="loubani">
<hgroup>
<h2>Tarek Loubani</h2>
</hgroup>
</header>
<p><em>Opening keynote (Day 1)</em></p>
--
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep '<em>'
<p><em>Closing keynote</em></p>
<p><em>Opening keynote (Day 1)</em></p>
<p><em>Opening keynote (Day 2)</em></p>
[...]
<p><em>The Tor Project: State of the Onion</em> and <em>Library Freedom Institute: A new hope</em></p>
<p><em>The Tor Project: State of the Onion</em></p>
[...]
<p><em>Large-scale collaboration with free software</em></p>
<p><em>Large-scale collaboration with free software</em></p>
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep -o '<em>[^<]\+</em>'
<em>Closing keynote</em>
<em>Opening keynote (Day 1)</em>
<em>Opening keynote (Day 2)</em>
[...]
<em>The Tor Project: State of the Onion</em>
<em>Library Freedom Institute: A new hope</em>
<em>The Tor Project: State of the Onion</em>
[...]
<em>Large-scale collaboration with free software</em>
<em>Large-scale collaboration with free software</em>
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep -o '<em>[^<]\+</em>' \
| sort \
| uniq -cd
2 <em>Hackerspace Rancho Electrónico</em>
4 <em>Large-scale collaboration with free software</em>
2 <em>Library Freedom Institute: A new hope</em>
2 <em>Right to Repair and the DMCA</em>
2 <em>Teaching privacy and security via free software</em>
2 <em>The joy of bug reporting</em>
5 <em>The Tor Project: State of the Onion</em>
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep -o '<em>[^<]\+</em>' \
| sort \
| uniq -cd \
| sort -nr \
| head -n5
5 <em>The Tor Project: State of the Onion</em>
4 <em>Large-scale collaboration with free software</em>
2 <em>The joy of bug reporting</em>
2 <em>Teaching privacy and security via free software</em>
2 <em>Right to Repair and the DMCA</em>
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep -o '<em>[^<]\+</em>' \
| sort \
| uniq -cd \
| sort -nr \
| head -n5 \
| sed 's#^ *\(.\+\) <em>\(.*\)</em>#\2 has \1 speakers#g'
The Tor Project: State of the Onion has 5 speakers
Large-scale collaboration with free software has 4 speakers
The joy of bug reporting has 2 speakers
Teaching privacy and security via free software has 2 speakers
Right to Repair and the DMCA has 2 speakers
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ fetch-url https://libreplanet.org/2019/speakers/ \
| grep -A5 speaker-header \
| grep -o '<em>[^<]\+</em>' \
| sort \
| uniq -cd \
| sort -nr \
| head -n5 \
| sed 's#^ *\(.\+\) <em>\(.*\)</em>#\2 has \1 speakers#g'
| espeak
#+END_SRC
#+BEAMER: \end{onlyenv}
*** LACKING Interactive, Incremental, Iterative Development :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEAMER: \fullslidetext
Incremental Development
#+BEAMER: \fullsubtext
Interactive REPL, Iterative Decomposition
*** LACKING Discovering URLs :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg
https://en.wikipedia.org/wiki/Free_software
https://en.wikipedia.org/wiki/Open_source
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
| while read URL; do
echo "URL is $URL"
done
URL is https://en.wikipedia.org/wiki/Free_software
URL is https://en.wikipedia.org/wiki/Open_source
URL is https://en.wikipedia.org/wiki/Microsoft
URL is https://opensource.org/about
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" >> results.txt
done
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" | tee -a results.txt
done
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" | tee -a results.txt
done \
| xclip -i -selection clipboard
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ grep -o 'https\?://[^ ]\+' email-of-links.msg \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" | tee -a results.txt
done \
| tee >( xclip -i -selection clipboard )
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ xclip -o -selection clipboard \
| grep -o 'https\?://[^ ]\+' \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" | tee -a results.txt
done \
| tee >( xclip -i -selection clipboard )
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ xclip -o -selection clipboard \
| grep -o 'https\?://[^ ]\+' \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| echo "$URL" | tee -a results.txt
done
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
$ xclip -i -selection clipboard < results.txt
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
$ xclip -o -selection clipboard \
| grep -o 'https\?://[^ ]\+' \
| while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| tee -a results.txt <<< "$URL"
done
https://en.wikipedia.org/wiki/Microsoft
https://opensource.org/about
$ xclip -i -selection clipboard < results.txt
#+END_SRC
#+BEAMER: \end{onlyenv}
*** LACKING Go Grab a Coffee :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEAMER: \fullslidetext
Go Grab a Coffee
**** Notes :B_noteNH:
:PROPERTIES:
:BEAMER_env: noteNH
:END:
...
But grabbing a coffee means that this system is a bottleneck.
Ideally,
we wouldn't have to wait long.
Can we do better?
*** Async Processes :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
#+BEGIN_SRC sh
$ sleep 1 && echo done & echo start
start
done
#+END_SRC
#+BEAMER: \begin{uncoverenv}<2>\subskip
/(Don't do this for large numbers of URLs!)/
#+BEGIN_SRC sh
$ while read URL; do
fetch-url "$URL" | grep -q 'free software' \
|| tee -a results.txt <<< "$URL" &
done
#+END_SRC
#+BEAMER: \end{uncoverenv}
*** LACKING Executable Shell Script and Concurrency :B_fullframe:
:PROPERTIES:
:BEAMER_env: fullframe
:END:
**** =url-grep= :B_block:
:PROPERTIES:
:BEAMER_env: block
:END:
#+BEGIN_SRC sh
#!/bin/bash
#+END_SRC
#+BEAMER: \begin{onlyenv}<+>
#+BEGIN_SRC sh
search="$1"
url="$2"
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<+->
#+BEGIN_SRC sh
search="${1?Missing search string}"
url="${2?Missing URL}"
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEGIN_SRC sh
wget -qO- "$url" \
| grep -q "$search" || echo "$url"
#+END_SRC
**** Execute :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
#+BEGIN_SRC sh
$ chmod +x url-grep
#+END_SRC
#+BEAMER: \begin{onlyenv}<1-2>
#+BEGIN_SRC sh
$ while read URL; do
./url-grep 'free software' "$URL" >> results.txt
done
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<3>
#+BEGIN_SRC sh
$ xargs -n1 ./url-grep 'free software' > results.txt
#+END_SRC
#+BEAMER: \end{onlyenv}
#+BEAMER: \begin{onlyenv}<4>
#+BEGIN_SRC sh
$ xargs -n1 -P5 ./url-grep 'free software' > results.txt
# ^ 5 concurrent processes
#+END_SRC
#+BEAMER: \end{onlyenv}
*** LACKING Again: A Research Task :B_againframe:
:PROPERTIES:
:BEAMER_env: againframe
:BEAMER_ref: *A Research Task
:BEAMER_act:
:END:
*** LACKING A Quick-n-Dirty Solution :B_frame:
:PROPERTIES:
:BEAMER_env: frame
:END:
#+BEGIN_SRC sh
echo 'wget -qO- "$2" | grep -q "$1" || echo "$2"' > url-grep
$ grep -o 'https\?://[^ ]\+' mail \
| xargs -n1 -P10 bash url-grep 'free software' \
| mail -s 'URLs not mentioning free software' mtg@gnu.org
#+END_SRC
** Thank You :B_fullframe:
:PROPERTIES: