TIP: How to Use Standard In (stdin) in Shell Scripts

shellscript

#1

Question.
Will the input always be after the first command?
So in this case right after cat?


“Copy, sort by length and paste” Macro
#2

No. It's the cat command that reads from stdin, which in this case is the input from the system clipboard.


#3

So to understand.
The input from KM becomes stdin for the shell script. And with no file cat uses this instead.

In cases with shell scripts then I am a bit unsure where stdin "ends up" in the shell script.

This post from @peternlewis also sends input from KM.


But this is another shell script, so what happens with stdin in this case?


#4

This is more a basic shell question. Basically, shell tools typically have one input stream (stdin - standard in), two output streams (stdout - standard out and stderr - standard error). Shell tools also get their arguments (listed after the command), and the environment variables.

Typical shell tool behaviour is to read and process either the stdin or the files listed on the command line, and then to output to stdout. Some tools accept only stdin, some tools accept only the command line files, some tools accept either, reading the files listed on the command line, or if there are none, reading from stdin instead.

So, for example:

  • grep x — read from stdin and output lines containing an x to stdout
  • grep x file.txt — read from file.txt and output lines containing an x to stdout

Now, further, you can then pipe the stdout of one tool to the stdin of the next tool.

  • grep x | tr /x/y/ — read from stdin, output only the lines containing x to stdout, then tr reads that stdout as its stdin, changes the the x to y, and then outputs that result to stdout.

cat is a very simple tool, it reads from stdin or the files listed, and outputs them to its stdout without any processing.

So in your original script, you have

  • cat /tmp/clipboard.txt | … — read from file clipboard.txt, and send it to its stdout, which will past it on to the next command as its stdin.

In @CJK’s script,

  • cat | awk … — reads from stdin (which Keyboard Maestro provides with the contents of the System Clipboard), and passes it unmodified to awk …. The cat | is unnecessary in this case - awk will read from the stdin whether it comes from cat or from Keyboard Maestro.

In the Execute Shell Script, the stdout is sent back to Keyboard Maestro to do with as you specify (eg save to a variable or set the system clipboard).


#5

Thanks. This is a good explainer for me.